/* =========================================================================
   APP.CSS — CSS PROPIO DEL SITIO PÚBLICO
   =========================================================================
   Orden de carga:  bootstrap.min.css -> tokens.css -> bridge.css -> app.css

   Destilado de main.css, header.css, footer.css, home.css, product.css,
   category.css, responsive.css y de los bloques <style> incrustados en las
   vistas (3055 líneas + ~600 líneas sueltas en PHP).

   TRES REGLAS QUE GOBIERNAN ESTE ARCHIVO

   1. Ni un solo valor literal de color, sombra, radio o tamaño de fuente.
      Todo sale de var(--tk-*). Lo único que se escribe literal es
      `transparent` y `currentColor`. Verificación:
          grep -nE '#[0-9a-fA-F]{3,8}\b|rgba?\(' app.css   ->   vacío

   2. Un hover cambia SOLO la luminosidad. Nunca el matiz, nunca el rol
      semántico. Y si cambia el fondo, cambia el texto de forma coherente.
      (El tema viejo tenía un botón que al pasar el mouse quedaba blanco
      sobre blanco, y otro rojo que se volvía verde.)

   3. Los cortes responsivos salen exclusivamente de la escala de Bootstrap 5
      —576 / 768 / 992 / 1200 / 1400—; este archivo usa los cuatro primeros y
      no necesita el de 1400. El tema viejo tenía once cortes distintos
      —480, 500, 576, 700, 767, 768, 943, 959, 991, 992, 1199— que se pisaban
      entre sí.

   Lo que NO está acá, a propósito: grilla, flex, espaciado, alineación,
   display y tipografía utilitaria. Todo eso lo trae Bootstrap 5. Tampoco
   están los componentes que ninguna vista renderiza (testimonios, galerías,
   blog, preloader, sidebar de widgets, slider bxSlider, carrusel de Owl).
   ========================================================================= */


/* =========================================================================
   1. BASE Y TIPOGRAFÍA
   ========================================================================= */

/* El pie queda abajo aunque la página tenga poco contenido. Reemplaza los
   min-height:80vh que cada vista de cuenta declaraba por su cuenta. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font-family: var(--tk-font-body);
  font-size: var(--tk-fs-base);
  line-height: var(--tk-lh-base);
  color: var(--tk-text);
  background-color: var(--tk-surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

main { flex: 1 0 auto; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--tk-font-heading);
  color: var(--tk-text-strong);
  font-weight: var(--tk-weight-semi);
  line-height: var(--tk-lh-tight);
  letter-spacing: var(--tk-tracking-heading);
  margin: 0 0 var(--tk-sp-3);
}

h1 { font-size: var(--tk-fs-2xl); }
h2 { font-size: var(--tk-fs-xl);  }
h3 { font-size: var(--tk-fs-lg);  }
h4 { font-size: var(--tk-fs-md);  }
h5 { font-size: var(--tk-fs-base); }
h6 { font-size: var(--tk-fs-sm); }

/* El título de página crece recién en pantalla ancha: a 30px en un teléfono
   de 360px un nombre de producto largo ocupa cuatro renglones. */
@media (min-width: 768px) {
  h1 { font-size: var(--tk-fs-3xl); }
  h2 { font-size: var(--tk-fs-2xl); }
}

p { margin: 0 0 var(--tk-sp-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--tk-primary-ink); text-decoration: none; transition: color var(--tk-dur-fast) var(--tk-ease-out); }
a:hover { color: var(--tk-primary-hover); }

/* Subrayar al pasar el mouse solo en texto corrido. En navegación, tarjetas
   y botones el subrayado agrega ruido y desalinea la grilla. */
:where(.content, .faq-answer, .auth-footer, .tab-content-inner, .address-details) a:hover { text-decoration: underline; }

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

hr { border: 0; border-top: var(--tk-border-width) solid var(--tk-border); margin: var(--tk-sp-6) 0; opacity: 1; }

small, .small { font-size: var(--tk-fs-sm); }

del { color: var(--tk-price-old); font-weight: var(--tk-weight-normal); }

/* El precio es el dato más importante de la página. Token fijo, nunca marca. */
.price, .product-price { color: var(--tk-price); font-weight: var(--tk-weight-bold); }


/* =========================================================================
   2. UTILIDADES PROPIAS
   =========================================================================
   Solo lo que Bootstrap 5 NO trae. Las utilidades de espaciado del tema viejo
   (pt_70, pb_70, pb_30, mb_30, pl_0, pr_0) no se reproducen: equivalen a las
   familias pt, pb, mb y px de Bootstrap, y cada una de las viejas venía con
   !important. Hay que reemplazarlas en el markup.
   ========================================================================= */

/* Bootstrap 5 renombró .sr-only a .visually-hidden. El markup todavía usa el
   nombre viejo en cuatro lugares; sin este alias, texto para lectores de
   pantalla aparece a la vista. */
.sr-only {
  position: absolute !important; /* imprescindible: replica .visually-hidden de Bootstrap, que también lo usa */
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Bootstrap 5 no define .hidden ni .btn-block (son .d-none y .w-100). */
.hidden { display: none; }

.btn-block { display: block; width: 100%; }

/* Fondo de sección alterna. Se conserva porque marca el ritmo de la portada. */
.bg-gray { background-color: var(--tk-surface-sunken); }

/* ---------- Botón sólido propio ----------
   Cinco botones del sitio —comprar ahora, finalizar compra, agregar dirección
   y los dos de ingreso— vienen en el markup SIN la clase .btn, así que
   Bootstrap no les da forma. El par fondo/texto y su hover se declaran UNA sola
   vez acá; cada uno pone después solo su geometría. Si esto se repitiera cinco
   veces, el próximo cambio de marca dejaría alguno atrás: así fue como el tema
   viejo terminó con un botón rojo que al pasar el mouse se volvía verde. */
.btn-buy-now, .btn-checkout, .btn-add-address,
.auth-card .btn-primary, .auth-card-mini .btn-primary {
  background-color: var(--tk-primary);
  color: var(--tk-on-primary);
  border: var(--tk-border-width) solid var(--tk-primary);
  border-radius: var(--tk-radius-md);
  font-family: inherit;
  font-weight: var(--tk-weight-semi);
  cursor: pointer;
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out),
              border-color var(--tk-dur-fast) var(--tk-ease-out);
}
/* Solo luminosidad: mismo matiz, mismo rol, mismo texto encima. */
.btn-buy-now:hover, .btn-checkout:hover, .btn-add-address:hover,
.auth-card .btn-primary:hover, .auth-card-mini .btn-primary:hover {
  background-color: var(--tk-primary-hover); border-color: var(--tk-primary-hover); color: var(--tk-on-primary);
}
.btn-buy-now:active, .btn-checkout:active, .btn-add-address:active,
.auth-card .btn-primary:active, .auth-card-mini .btn-primary:active {
  background-color: var(--tk-primary-active); border-color: var(--tk-primary-active);
}

/* ---------- Tarjeta elevada ----------
   Las cuatro pantallas de cuenta repetían la misma caja con cuatro juegos de
   valores apenas distintos. Acá el fondo, el borde y la elevación se definen
   una vez; cada pantalla ajusta solo su ancho y su relleno. */
.auth-card, .profile-card, .orders-card, .address-card {
  width: 100%;
  background-color: var(--tk-surface-raised);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-lg);
  box-shadow: var(--tk-shadow-sm);
}


/* =========================================================================
   3. LAYOUT DE PÁGINA Y CONTENEDORES
   ========================================================================= */

/* El contenedor se topea en el ancho del token, no en los 1320px de
   Bootstrap: con una grilla de cuatro productos, 1320 deja tarjetas
   desproporcionadamente anchas. */
@media (min-width: 1200px) {
  .container { max-width: var(--tk-container-max); }
}

/* Envoltorio de toda página interior. Antes el espaciado lo ponía la clase
   pt_70/pb_70 en el markup; ahora es responsabilidad del bloque. */
.page { width: 100%; padding-block: var(--tk-sp-8); }

@media (min-width: 768px) {
  .page { padding-block: var(--tk-sp-12); }
}

/* Bandas de la portada. El espaciado lo daban las clases pt_70/pb_70 del
   markup; al no reproducirlas, lo asume el bloque. Si el markup pasa a py-5,
   la utilidad de Bootstrap gana y esto no estorba. */
.product, .service { padding-block: var(--tk-sp-12); }

/* Servicios de la portada: tres columnas centradas con su ícono arriba. */
.service .item { text-align: center; }
.service .photo { margin-bottom: var(--tk-sp-4); }

/* Carrusel principal de la portada.
   OJO: se estila .carousel-item, el nombre de Bootstrap 5. El markup todavía
   emite .item, heredado de Bootstrap 3, y con ese nombre NINGUNA regla oculta
   las diapositivas inactivas: se apilan todas una debajo de otra. Ese renombre
   es obligatorio, no cosmético. */
.bs-slider .carousel-item {
  min-height: 320px;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.bs-slider-overlay {
  position: absolute;
  inset: 0;
  background-color: color-mix(in oklab, var(--tk-surface-inverse) 52%, transparent);
}
.bs-slider .slide-text { position: relative; z-index: 1; padding-block: var(--tk-sp-12); }
.bs-slider .slide-text h1,
.bs-slider .slide-text p { color: var(--tk-text-inverse); }
.bs-slider .slide-text p { font-size: var(--tk-fs-md); }

@media (min-width: 768px) {
  .bs-slider .carousel-item { min-height: 440px; }
}

/* Bloque de título de sección centrado (portada y categoría). */
.headline { text-align: center; margin-bottom: var(--tk-sp-8); }
.headline h2 { font-size: var(--tk-fs-xl); margin-bottom: var(--tk-sp-2); }
.headline h3 { font-size: var(--tk-fs-md); font-weight: var(--tk-weight-normal); color: var(--tk-text-muted); margin: 0; }

/* Banner de las páginas estáticas (Nosotros, FAQ, Contacto). Sustituye a
   .page-banner, que pedía una foto de fondo con un velo encima. */
.hero {
  background-color: var(--tk-surface-sunken);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-lg);
  padding: var(--tk-sp-6);
  margin-bottom: var(--tk-sp-6);
}
.hero h1 { margin: 0; }

.content { font-size: var(--tk-fs-base); }
.content h2, .content h3 { margin-top: var(--tk-sp-8); }

/* Migas. El markup es <nav class="breadcrumb"><ul><li>, no la lista plana que
   espera el componente de Bootstrap, así que hay que estilar el ul interno. */
.breadcrumb { background: transparent; padding: 0; margin-bottom: var(--tk-sp-6); font-size: var(--tk-fs-sm); }
.breadcrumb ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--tk-sp-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.breadcrumb li { color: var(--tk-text-muted); }
.breadcrumb li:last-child { color: var(--tk-text); }

/* Acordeón de preguntas frecuentes. */
.faq-item { border-bottom: var(--tk-border-width) solid var(--tk-border); }
.faq-question {
  width: 100%;
  text-align: left;
  font-weight: var(--tk-weight-semi);
  color: var(--tk-text-strong);
  padding: var(--tk-sp-3) 0;
  text-decoration: none;
}
.faq-question:hover { color: var(--tk-primary-ink); }
.faq-answer { padding-bottom: var(--tk-sp-4); color: var(--tk-text); }

/* Botón de volver arriba. */
/* `--tk-barra-inferior` lo declara la pagina que tenga barra fija. Sin eso, el
   boton de volver arriba quedaba ENTERRADO debajo de la barra de la ficha de
   producto: no se veia por mas que uno bajara, y el toque en esa zona caia sobre
   "Agregar al carrito". En el resto de las paginas si aparecia, lo que hacia el
   sintoma dificil de ver. */
.scrollup {
  position: fixed; right: var(--tk-sp-5);
  bottom: calc(var(--tk-sp-5) + var(--tk-barra-inferior, 0px));
  z-index: 1030; display: none;
}
.scrollup.is-visible { display: block; }   /* el gancho que activa el script al desplazar */
.scrollup i {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--tk-radius-pill);
  background-color: var(--tk-primary);
  color: var(--tk-on-primary);
  font-size: var(--tk-fs-lg);
  box-shadow: var(--tk-shadow-md);
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
/* Solo luminosidad: mismo matiz, mismo rol, texto coherente. */
.scrollup:hover i { background-color: var(--tk-primary-hover); color: var(--tk-on-primary); }


/* =========================================================================
   4. ENCABEZADO
   =========================================================================
   Estructura: .header-container > .top (contacto) + .header (logo, acciones,
   buscador) + .nav (menú de categorías).
   ========================================================================= */

.header-container {
  position: sticky;
  top: 0;
  z-index: 1030;
  background-color: var(--tk-surface);
  border-bottom: var(--tk-border-width) solid var(--tk-border);
}
.header-container.is-sticky { box-shadow: var(--tk-shadow-sm); }

/* ---------- Barra de contacto ---------- */
.top {
  background-color: var(--tk-surface-inverse);
  color: var(--tk-text-inverse);
  font-size: var(--tk-fs-2xs);
  padding-block: var(--tk-sp-1);
}
.top .left ul,
.top .right ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--tk-sp-4);
  list-style: none;
  margin: 0;
  padding: 0;
}
.top .right ul { justify-content: flex-end; gap: var(--tk-sp-2); }
.top li { white-space: nowrap; }
.top a,
.top i { color: var(--tk-text-inverse); }
.top .right a {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--tk-radius-pill);
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
/* Se ilumina el fondo, el ícono sigue siendo del mismo color. */
.top .right a:hover {
  background-color: color-mix(in oklab, var(--tk-text-inverse) 18%, transparent);
  color: var(--tk-text-inverse);
}

/* ---------- Fila principal: logo, acciones, buscador ---------- */
.header { background-color: var(--tk-header-bg, var(--tk-surface)); color: var(--tk-header-text, var(--tk-text)); }

.header .inner { display: flex; flex-wrap: wrap; align-items: center; row-gap: var(--tk-sp-2); padding-block: var(--tk-sp-2); }

.header .logo img { max-height: 40px; width: auto; }

/* Acciones de usuario y mini carrito. */
.header .right ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--tk-sp-4);
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--tk-fs-sm);
}
/* `:not(.btn)` NO es decorativo. Este selector tiene mas especificidad que la
   regla `.btn` de Bootstrap, asi que pintaba de gris el texto de los botones que
   viven en el encabezado: los dos del mini carrito quedaban con letra gris sobre
   el color de marca, ilegibles, mientras el mismo boton en cualquier otra parte
   del sitio salia bien. */
.header .right a:not(.btn) { color: var(--tk-header-text, var(--tk-text)); white-space: nowrap; }
.header .right a:not(.btn):hover { color: var(--tk-primary-ink); }

.cart-badge {
  display: inline-block;
  min-width: 18px;
  padding: 0 var(--tk-sp-1);
  border-radius: var(--tk-radius-pill);
  background-color: var(--tk-primary);
  color: var(--tk-on-primary);
  font-size: var(--tk-fs-3xs);
  line-height: 18px;
  text-align: center;
  vertical-align: top;
}

/* ---------- Buscador ---------- */
.search-area form { display: flex; gap: var(--tk-sp-2); width: 100%; margin: 0; }
.search-area .form-group { flex: 1 1 auto; min-width: 0; margin: 0; }
.search-area .form-control { width: 100%; }

/* ---------- Menús desplegables del encabezado ---------- */
.mini-cart,
.user-dropdown-container { position: relative; }

.mini-cart-dropdown,
.user-dropdown-menu {
  position: absolute;
  right: 0;
  top: calc(100% + var(--tk-sp-2));
  z-index: 1040;
  background-color: var(--tk-surface-raised);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  box-shadow: var(--tk-shadow-lg);
}
.mini-cart-dropdown { width: 320px; }
/* `display:none` fijo hacía que el panel no se pudiera mostrar nunca: el script
   conmuta el atributo `hidden`, no el estilo. Con la regla anterior, aunque el
   script funcionara, el menú seguía invisible. */
.user-dropdown-menu { width: 220px; padding-block: var(--tk-sp-2); }
.user-dropdown-menu[hidden] { display: none; }

.mini-cart-header {
  padding: var(--tk-sp-3) var(--tk-sp-4);
  font-weight: var(--tk-weight-semi);
  color: var(--tk-text-strong);
  border-bottom: var(--tk-border-width) solid var(--tk-border);
}
.mini-cart-list { max-height: 280px; overflow-y: auto; margin: 0; padding: var(--tk-sp-2) var(--tk-sp-4); }
.mini-cart-item { display: flex; align-items: center; gap: var(--tk-sp-2); padding-block: var(--tk-sp-2); }
.mini-cart-item + .mini-cart-item { border-top: var(--tk-border-width) solid var(--tk-border); }
.mini-cart-thumb {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  object-fit: cover;
  background-color: var(--tk-image-pad);
  border-radius: var(--tk-radius-xs);
}
.mini-cart-info { flex: 1 1 auto; min-width: 0; }
.mini-cart-title {
  font-size: var(--tk-fs-xs);
  color: var(--tk-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mini-cart-meta { font-size: var(--tk-fs-2xs); color: var(--tk-text-muted); }
.mini-cart-subtotal { font-size: var(--tk-fs-xs); font-weight: var(--tk-weight-semi); color: var(--tk-price); }
.mini-cart-footer {
  padding: var(--tk-sp-3) var(--tk-sp-4);
  border-top: var(--tk-border-width) solid var(--tk-border);
  display: grid;
  gap: var(--tk-sp-2);
}
.mini-cart-total { font-size: var(--tk-fs-sm); }
.mini-cart-empty { padding: var(--tk-sp-4); color: var(--tk-text-muted); text-align: center; }

.user-dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--tk-sp-2);
  padding: var(--tk-sp-2) var(--tk-sp-4);
  color: var(--tk-text);
  font-size: var(--tk-fs-sm);
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.user-dropdown-item i { width: 20px; text-align: center; color: var(--tk-text-muted); }
/* El fondo se oscurece un paso; el texto pasa a tinta de marca. Coherente. */
.user-dropdown-item:hover,
.user-dropdown-item:hover i { background-color: var(--tk-surface-inset); color: var(--tk-primary-ink); }
/* La opción destructiva conserva su rol también al pasar el mouse. */
.user-dropdown-item.text-danger:hover,
.user-dropdown-item.text-danger:hover i { background-color: var(--tk-danger-subtle); color: var(--tk-danger); }
.user-dropdown-divider { height: var(--tk-border-width); background-color: var(--tk-border); margin-block: var(--tk-sp-2); }

/* ---------- Menú de categorías ---------- */
/* .nav es un componente de Bootstrap 5 (display:flex). Acá es solo la franja
   oscura que contiene al menú, así que se le devuelve el flujo de bloque.
.header .nav { display: block; background-color: color-mix(in oklab, var(--tk-surface-inverse) 88%, var(--tk-text-inverse)); }
   que contiene al menú, así que se le devuelve el flujo de bloque.
   El fondo lo elige el comerciante (claro, oscuro o color de marca) a través de
   las variables del encabezado; acá no se fija un color propio. Antes esta
   franja usaba --tk-surface-inverse fijo y el .menu-container que vive adentro
   la pisaba con --tk-header-bg blanco: resultado, una caja blanca flotando
   dentro de una franja oscura, con texto gris oscuro ilegible. */
.header .nav {
  display: block;
  background-color: var(--tk-header-bg, var(--tk-surface));
  border-top: var(--tk-border-width) solid var(--tk-header-border, var(--tk-border));
}

.menu-container { width: 100%; background-color: transparent; border-bottom: 0; }

.menu > ul { display: flex; flex-wrap: wrap; justify-content: center; list-style: none; margin: 0; padding: 0; }
.menu > ul > li > a {
  display: block;
  padding: var(--tk-sp-3) var(--tk-sp-4);
  color: var(--tk-header-text, var(--tk-text));
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
/* Hover: un velo del color del texto sobre el fondo elegido. Funciona igual con
   la barra clara, oscura o en color de marca, sin fijar un matiz. */
.menu > ul > li > a:hover,
.menu > ul > li > a:focus-visible {
  background-color: color-mix(in oklab, var(--tk-header-text, var(--tk-text)) 12%, transparent);
  color: var(--tk-header-text, var(--tk-text));
}
/* El activo marca el borde inferior con el color de marca, que es el acento
   del sitio y se lee sobre cualquiera de los tres estilos de barra. */
.menu > ul > li > a.active {
  color: var(--tk-header-text, var(--tk-text));
  box-shadow: inset 0 -3px 0 var(--tk-primary);
}


/* =========================================================================
   5. MENÚ MÓVIL
   =========================================================================
   El botón lo inyecta el script del menú antes de .menu > ul y alterna la
   clase .show-on-mobile sobre esa lista. Acá solo se declara la apariencia
   en los dos estados; nada depende de una librería.
   ========================================================================= */

.menu-mobile { display: none; }

@media (max-width: 991.98px) {
  .menu-mobile {
    display: flex;
    /* Es un boton, asi que hereda el fondo claro por omision del navegador y
       quedaba como una caja clara pegada sobre la barra oscura. */
    width: 100%;
    background: transparent;
    border: 0;
    cursor: pointer;
    align-items: center;
    justify-content: space-between;
    gap: var(--tk-sp-2);
    padding: var(--tk-sp-3) var(--tk-sp-4);
    /* Del color del ENCABEZADO, no del inverso fijo. Cuando la barra dejó de ser
       siempre oscura -el comerciante elige entre claro, oscuro y color de marca-
       este botón se quedó con la letra clara: sobre la barra blanca daba 1,00 de
       contraste, o sea invisible. Y es el único acceso al menú en teléfono. */
    color: var(--tk-header-text, var(--tk-text-inverse));
    font-size: var(--tk-fs-sm);
    font-weight: var(--tk-weight-semi);
    text-transform: uppercase;
    letter-spacing: var(--tk-tracking-heading);
  }
  .menu-mobile:hover { color: var(--tk-header-text, var(--tk-text)); }
  .menu-mobile:focus-visible { outline: 2px solid var(--tk-primary); outline-offset: 2px; }
  .menu-mobile::after {
    content: "\f0c9";               /* fa-bars */
    font-family: "FontAwesome";
    font-size: var(--tk-fs-lg);
  }

  /* Cerrada por omisión; el botón la abre agregando .show-on-mobile. */
  .menu > ul { display: none; }
  .menu > ul.show-on-mobile {
    display: flex;
    flex-direction: column;
    border-top: var(--tk-border-width) solid var(--tk-header-border, var(--tk-border));
    position: relative;
    z-index: 1000;
  }
  .menu > ul > li { width: 100%; }
  .menu > ul > li + li {
    border-top: var(--tk-border-width) solid var(--tk-header-border, var(--tk-border));
  }
  .menu > ul > li > a { padding: var(--tk-sp-3) var(--tk-sp-5); }
}


/* =========================================================================
   6. PIE
   ========================================================================= */

.home-newsletter {
  background-color: color-mix(in oklab, var(--tk-surface-inverse) 88%, var(--tk-text-inverse));
  padding-block: var(--tk-sp-12);
}

/* Tarjeta clara sobre la franja oscura. */
.home-newsletter .single {
  max-width: 650px;
  margin-inline: auto;
  padding: var(--tk-sp-6);
  background-color: var(--tk-surface-raised);
  border-radius: var(--tk-radius-lg);
  box-shadow: var(--tk-shadow-md);
  text-align: center;
}
.home-newsletter .single h2 { font-size: var(--tk-fs-lg); margin-bottom: var(--tk-sp-4); }
/* .btn-theme no existe en Bootstrap: sin esto el botón de suscripción queda
   transparente sobre la tarjeta blanca. Toma el rol primario, como corresponde
   a la única acción del bloque. */
.btn-theme {
  background-color: var(--tk-primary);
  color: var(--tk-on-primary);
  border-color: var(--tk-primary);
}
.btn-theme:hover { background-color: var(--tk-primary-hover); border-color: var(--tk-primary-hover); color: var(--tk-on-primary); }

.footer-bottom { background-color: var(--tk-surface-inverse); padding-block: var(--tk-sp-4); }
.footer-bottom .copyright {
  text-align: center;
  font-size: var(--tk-fs-xs);
  color: color-mix(in oklab, var(--tk-text-inverse) 72%, transparent);
}
.footer-bottom a { color: var(--tk-text-inverse); }


/* =========================================================================
   7. TARJETA DE PRODUCTO Y GRILLAS
   ========================================================================= */

.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: var(--tk-surface-raised);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  box-shadow: var(--tk-shadow-xs);
  transition: transform var(--tk-dur-base) var(--tk-ease-out),
              box-shadow var(--tk-dur-base) var(--tk-ease-out);
}
.product-card:hover { transform: translateY(-2px); box-shadow: var(--tk-shadow-md); }

.product-card .thumb { position: relative; display: block; overflow: hidden; background-color: var(--tk-image-pad); }

/* La proporción de la foto es un token: ropa quiere retrato, ferretería
   cuadrado. Antes era un padding-top:133% fijo dentro del CSS. */
.product-card .photo {
  width: 100%;
  aspect-ratio: var(--tk-product-aspect);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  transition: transform var(--tk-dur-slow) var(--tk-ease-out);
}
.product-card .thumb:hover .photo { transform: scale(1.03); }

/* Velo de la foto al pasar el mouse. */
.product-card .overlay {
  position: absolute;
  inset: 0;
  background-color: color-mix(in oklab, var(--tk-surface) 55%, transparent);
  opacity: 0;
  transition: opacity var(--tk-dur-base) var(--tk-ease-out);
  pointer-events: none;
}
.product-card:hover .overlay { opacity: 1; }

.product-card .text,
.product-card .card-body { display: flex; flex-direction: column; flex: 1 1 auto; padding: var(--tk-sp-3); }

.product-card .card-title {
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  line-height: var(--tk-lh-tight);
  margin-bottom: var(--tk-sp-2);
  /* Dos renglones a lo sumo: empareja la grilla sin fijar altura en píxeles. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.product-card .card-title a { color: var(--tk-text-strong); }
.product-card .card-title a:hover { color: var(--tk-primary-ink); }

.product-card .card-subtitle {
  font-size: var(--tk-fs-md);
  font-weight: var(--tk-weight-bold);
  color: var(--tk-price);
  margin-bottom: var(--tk-sp-2);
}
.product-card .card-subtitle del { font-size: var(--tk-fs-sm); margin-left: var(--tk-sp-2); }

.rating i { color: var(--tk-warning); font-size: var(--tk-fs-xs); }

/* Botón de agregar al carrito sobre la foto, en la grilla de categoría.
   Con puntero fino aparece al pasar el mouse; en pantalla táctil, donde no
   hay hover, queda siempre visible. */
.add-to-cart-inline { z-index: 2; }
@media (hover: hover) {
  .add-to-cart-inline { opacity: 0; transition: opacity var(--tk-dur-base) var(--tk-ease-out); }
  .product-card:hover .add-to-cart-inline,
  .add-to-cart-inline:focus-within { opacity: 1; }
}


/* =========================================================================
   8. CARRUSEL DE PRODUCTOS (DESPLAZAMIENTO CON ANCLAJE, SIN JAVASCRIPT)
   =========================================================================
   Reemplaza a Owl Carousel, bxSlider y bootstrap-touch-slider.

   Por qué importa: la librería anterior arrancaba con opacity:0 y solo la
   subía a 1 en su callback de inicialización. En teléfonos ese callback no
   llegaba a correr y la portada quedaba SIN NINGÚN PRODUCTO VISIBLE. Con
   desplazamiento nativo no hay estado de carga que se pueda trabar: si el
   CSS cargó, los productos están.
   ========================================================================= */

.product-carousel {
  display: flex;
  gap: var(--tk-sp-4);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline-start: var(--tk-sp-1);
  -webkit-overflow-scrolling: touch;

  /* Sitio para que la sombra y el -2px del hover no queden recortados:
     overflow-x:auto convierte también el eje vertical en desplazable. */
  padding-block: var(--tk-sp-2) var(--tk-sp-4);

  /* Barra oculta, desplazamiento táctil intacto. */
  scrollbar-width: none;      /* Firefox */
  -ms-overflow-style: none;   /* Edge heredado */
}
.product-carousel::-webkit-scrollbar { display: none; }  /* WebKit y Blink */

/* flex:0 0 auto con ancho fijo es lo que evita que una fila de un solo
   producto estire la tarjeta a todo el ancho. Queda a la izquierda, con su
   tamaño natural, porque flex-start es el valor por omisión. */
.product-carousel > .item { flex: 0 0 auto; width: 72%; max-width: 280px; margin: 0; scroll-snap-align: start; }

@media (min-width: 576px) { .product-carousel > .item { width: 46%; } }
@media (min-width: 768px) { .product-carousel > .item { width: 31%; } }
@media (min-width: 992px) { .product-carousel > .item { width: 23.5%; } }
@media (min-width: 1200px){ .product-carousel > .item { width: 19%; } }


/* =========================================================================
   9. FICHA DE PRODUCTO
   ========================================================================= */

/* ---------- Disposición general ---------- */
.product-info-top {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "title" "gallery" "options";
  gap: var(--tk-sp-6);
  align-items: start;
  margin-bottom: var(--tk-sp-8);
}

@media (min-width: 992px) {
  .product-info-top { grid-template-columns: minmax(0, 1.55fr) minmax(320px, 1fr); grid-template-areas: "gallery options"; }
}

.product-gallery { grid-area: gallery; }
.product-main-details { grid-area: options; }


.product-title { font-size: var(--tk-fs-xl); margin-bottom: var(--tk-sp-2); }

/* ---------- Galería ---------- */
/* ARREGLO DE DISPOSICIÓN: antes la imagen principal se dibujaba a su tamaño
   natural (~270px) dentro de una columna de ~600px y dejaba un hueco blanco
   de casi 300px de alto. Ahora .product-main-image es el elemento flexible
   de la fila y la imagen ocupa el 100% de él, con la proporción del token y
   object-fit:contain para no deformar la foto. El relleno lateral que pueda
   quedar lo pinta --tk-image-pad, que es claro en ambos temas. */
.product-gallery {
  display: flex;
  flex-wrap: wrap;          /* en teléfono: foto arriba, tira de miniaturas debajo */
  align-items: flex-start;
  gap: var(--tk-sp-4);
  min-width: 0;
}

.product-thumbnails {
  display: flex;
  gap: var(--tk-sp-2);
  order: 2;                 /* en teléfono las miniaturas van DEBAJO de la foto */
  width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.product-thumbnails::-webkit-scrollbar { display: none; }

.thumbnail-item {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  background-color: var(--tk-image-pad);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border: 2px solid transparent;
  border-radius: var(--tk-radius-sm);
  cursor: pointer;
  transition: border-color var(--tk-dur-fast) var(--tk-ease-out);
}
.thumbnail-item:hover { border-color: var(--tk-border-strong); }
.thumbnail-item.selected { border-color: var(--tk-primary); }

.product-main-image { position: relative; order: 1; flex: 1 1 auto; min-width: 0; width: 100%; }
.product-main-image img {
  width: 100%;
  aspect-ratio: var(--tk-product-aspect);
  object-fit: contain;
  background-color: var(--tk-image-pad);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
}

@media (min-width: 768px) {
  .product-gallery { flex-wrap: nowrap; }
  .product-thumbnails {
    order: 1;
    flex: 0 0 72px;
    flex-direction: column;
    width: 72px;
    max-height: 520px;
    overflow-x: visible;
    overflow-y: auto;
  }
  .thumbnail-item { flex: 0 0 72px; width: 72px; height: 72px; }
  .product-main-image { order: 2; }
}

/* ---------- Columna de compra ---------- */
.product-main-details { display: flex; flex-direction: column; gap: var(--tk-sp-3); min-width: 0; }

@media (min-width: 992px) {
  .product-main-details {
    position: sticky;
    top: calc(var(--tk-header-height) + var(--tk-sp-5));
    padding: var(--tk-sp-5);
    background-color: var(--tk-surface-raised);
    border: var(--tk-border-width) solid var(--tk-border);
    border-radius: var(--tk-radius-md);
    box-shadow: var(--tk-shadow-xs);
  }
}

.product-price { font-size: var(--tk-fs-2xl); line-height: var(--tk-lh-tight); margin-block: var(--tk-sp-1) var(--tk-sp-2); }
.product-price del { font-size: var(--tk-fs-base); margin-left: var(--tk-sp-2); }

.share-button {
  align-self: flex-start;
  background: none;
  border: 0;
  padding: 0;
  color: var(--tk-primary-ink);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  cursor: pointer;
}
.share-button:hover { color: var(--tk-primary-hover); }

/* ---------- Selectores de variante ---------- */
.size-buttons { display: flex; flex-wrap: wrap; gap: var(--tk-sp-2); margin-top: var(--tk-sp-2); }

.size-option-item {
  padding: var(--tk-sp-2) var(--tk-sp-4);
  min-width: 44px;
  background-color: var(--tk-surface);
  color: var(--tk-text-strong);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-sm);
  font-size: var(--tk-fs-sm);
  cursor: pointer;
  transition: border-color var(--tk-dur-fast) var(--tk-ease-out),
              background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.size-option-item:hover {
  border-color: var(--tk-primary);
  background-color: var(--tk-primary-subtle);
  color: var(--tk-primary-ink);
}
.size-option-item.active { background-color: var(--tk-primary); border-color: var(--tk-primary); color: var(--tk-on-primary); }

.design-thumb {
  width: 60px;
  height: 60px;
  background-color: var(--tk-image-pad);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border: 2px solid var(--tk-border);
  border-radius: var(--tk-radius-sm);
  cursor: pointer;
  transition: border-color var(--tk-dur-fast) var(--tk-ease-out);
}
.design-thumb:hover { border-color: var(--tk-border-strong); }
.design-thumb.selected { border-color: var(--tk-primary); }

/* Fila de diseños desplazable en vez de envuelta: con doce variantes, el
   wrap empujaba el botón de compra fuera de la primera pantalla. */
.design-thumbs { display: flex; flex-wrap: nowrap; gap: var(--tk-sp-2); margin-top: var(--tk-sp-2); overflow-x: auto; scrollbar-width: none; }
.design-thumbs::-webkit-scrollbar { display: none; }
.design-thumb { flex: 0 0 auto; }

/* ---------- Cantidad ---------- */
.quantity-wrapper { max-width: 200px; }

.quantity-control { display: flex; align-items: center; gap: var(--tk-sp-2); margin-top: var(--tk-sp-2); }
.quantity-control input[type="number"] {
  width: 64px;
  padding: var(--tk-sp-2);
  text-align: center;
  font-size: var(--tk-fs-base);
  color: var(--tk-text-strong);
  background-color: var(--tk-surface);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-sm);
  appearance: textfield;
  -moz-appearance: textfield;
}
.quantity-control input::-webkit-outer-spin-button,
.quantity-control input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.btn-qty {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  background-color: var(--tk-surface-inset);
  color: var(--tk-text-strong);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-pill);
  font-size: var(--tk-fs-lg);
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
/* Un paso más oscuro, mismo texto. */
.btn-qty:hover { background-color: var(--tk-border); color: var(--tk-text-strong); }

.stock-info { display: block; margin-top: var(--tk-sp-1); font-size: var(--tk-fs-xs); color: var(--tk-stock-ok); }

/* ---------- Acciones de compra ---------- */
/* ARREGLO 1 — .btn-cart tenía un hover que lo dejaba con texto blanco sobre
   fondo casi blanco: ilegible. Ahora es el botón secundario y su hover solo
   baja un paso de luminosidad manteniendo el texto fuerte.
   ARREGLO 2 — .btn-buy-now era rojo y se volvía VERDE al pasar el mouse
   (copiado de otro tema). Ahora es la acción principal, en color de marca, y
   su hover es el mismo matiz más oscuro con el mismo texto encima. */
.product-action-buttons { display: flex; flex-wrap: wrap; gap: var(--tk-sp-3); margin-top: var(--tk-sp-4); }

.btn-cart, .btn-buy-now { flex: 1 1 160px; padding: var(--tk-sp-3) var(--tk-sp-5); font-size: var(--tk-fs-base); }

.btn-cart {
  background-color: var(--tk-surface-inset);
  color: var(--tk-text-strong);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-md);
  font-family: inherit;
  font-weight: var(--tk-weight-semi);
  cursor: pointer;
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.btn-cart:hover { background-color: var(--tk-border); color: var(--tk-text-strong); }

/* ---------- Secciones expandibles ---------- */
.product-tabs { margin-block: var(--tk-sp-8) var(--tk-sp-10); }

.tab-content-inner { padding-block: var(--tk-sp-4); }
.tab-content-inner + .tab-content-inner { border-top: var(--tk-border-width) solid var(--tk-border); }
.tab-content-inner h5 { margin-bottom: var(--tk-sp-3); font-size: var(--tk-fs-md); }

.collapsible-content {
  position: relative;
  max-height: 140px;
  overflow: hidden;
  transition: max-height var(--tk-dur-slow) var(--tk-ease-both);
}
/* Degradado que avisa que hay más texto. El punto de llegada es el fondo real
   de la página, no un blanco fijo, para que no se vea una banda en tema oscuro. */
.collapsible-content::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 56px;
  background: linear-gradient(to bottom, transparent, var(--tk-surface));
  pointer-events: none;
  transition: opacity var(--tk-dur-base) var(--tk-ease-out);
}
.collapsible-content.expanded { max-height: none; }
.collapsible-content.expanded::after { opacity: 0; }

.expand-toggle {
  margin-top: var(--tk-sp-2);
  padding: 0;
  background: none;
  border: 0;
  color: var(--tk-primary-ink);
  font-size: var(--tk-fs-sm);
  cursor: pointer;
  text-decoration: underline;
}
.expand-toggle:hover { color: var(--tk-primary-hover); }

.product-attributes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--tk-sp-2) var(--tk-sp-5);
}
.product-attributes .attribute { display: flex; align-items: baseline; gap: var(--tk-sp-2); font-size: var(--tk-fs-sm); }
.product-attributes i { color: var(--tk-success); }

.related-products { margin-top: var(--tk-sp-10); }
.related-products .card-img-top {
  background-color: var(--tk-image-pad);
  background-size: cover;
  background-position: center;
  aspect-ratio: var(--tk-product-aspect);
  border-radius: var(--tk-radius-md) var(--tk-radius-md) 0 0;
}

/* ---------- Barra fija de acciones en teléfono ---------- */
.mobile-share-bar { display: none; }

@media (max-width: 767.98px) {
  .mobile-share-bar {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 1040;
    display: flex;
    gap: var(--tk-sp-2);
    padding: var(--tk-sp-2) var(--tk-sp-3);
    padding-bottom: max(var(--tk-sp-2), env(safe-area-inset-bottom));
    background-color: var(--tk-surface-raised);
    border-top: var(--tk-border-width) solid var(--tk-border);
    box-shadow: var(--tk-shadow-lg);
  }
  .mobile-share-bar .btn { flex: 1 1 0; }
  /* .btn-outline a secas no existe en Bootstrap 5; acá es el par secundario
     del botón principal de la barra. */
  .mobile-share-bar .btn-outline {
    background-color: var(--tk-surface);
    color: var(--tk-primary-ink);
    border: var(--tk-border-width) solid var(--tk-primary);
  }
  .mobile-share-bar .btn-outline:hover { background-color: var(--tk-primary-subtle); color: var(--tk-primary-hover); }
  /* El aire para la barra fija lo reserva LA PAGINA QUE TIENE BARRA, no el
     cuerpo entero. Cuando estaba en `body`, todas las paginas del sitio -la
     portada, el carrito, las preguntas frecuentes- quedaban con una franja
     vacia de 64 pixeles debajo del copyright sin ninguna barra que la
     justificara. Y en la ficha, que si la tiene, el reservado se quedaba corto:
     la barra mide 69 y tapaba los ultimos 5 pixeles del pie. */
}


/* =========================================================================
   10. CATEGORÍA Y BÚSQUEDA
   ========================================================================= */

.filter-sidebar { position: sticky; top: calc(var(--tk-header-height) + var(--tk-sp-5)); }

.filter-card { background: transparent; border: 0; box-shadow: none; }
.filter-card .card-body { padding: var(--tk-sp-2) 0; }

.filter-section + .filter-section { border-top: var(--tk-border-width) solid var(--tk-border); }

.filter-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--tk-sp-3) 0;
  background: none;
  border: 0;
  color: var(--tk-text-strong);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-semi);
  cursor: pointer;
}
.filter-header:hover { color: var(--tk-primary-ink); }
.filter-header i { transition: transform var(--tk-dur-base) var(--tk-ease-out); }

.filter-content { padding-bottom: var(--tk-sp-3); }
.filter-section.collapsed .filter-content { display: none; }
.filter-section.collapsed .filter-header i { transform: rotate(180deg); }

/* Fichas de faceta. Es la única forma en el sitio de un control seleccionable
   redondeado, así que se define una sola vez acá. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--tk-sp-2);
  padding: var(--tk-sp-1) var(--tk-sp-3);
  background-color: var(--tk-surface);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-pill);
  font-size: var(--tk-fs-xs);
  cursor: pointer;
  transition: border-color var(--tk-dur-fast) var(--tk-ease-out),
              background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.pill:hover { border-color: var(--tk-border-strong); background-color: var(--tk-surface-inset); }
.pill input { margin: 0; }
.pill:has(input:checked) {
  border-color: var(--tk-primary);
  background-color: var(--tk-primary-subtle);
  color: var(--tk-primary-ink);
}
/* Respaldo para navegadores sin :has() — colorea solo el texto. */
.pill input:checked + span { color: var(--tk-primary-ink); font-weight: var(--tk-weight-medium); }

.facet-group { display: flex; flex-wrap: wrap; gap: var(--tk-sp-2); }

.price-inline { display: flex; align-items: center; gap: var(--tk-sp-2); margin-bottom: var(--tk-sp-2); }
.price-inline .form-control { max-width: 100px; }
.price-inline .dash { color: var(--tk-text-muted); }

.price-preset { font-size: var(--tk-fs-2xs); white-space: nowrap; }

.filter-content .actions { display: flex; align-items: center; gap: var(--tk-sp-2); margin-top: var(--tk-sp-3); }
.btn-apply { flex: 1 1 auto; }

.category-summary { flex: 1 1 auto; min-width: 0; }

.category-controls { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: var(--tk-sp-3); }
.category-controls .control { display: inline-flex; align-items: center; gap: var(--tk-sp-2); white-space: nowrap; margin: 0; }
.category-controls .form-label { margin: 0; font-size: var(--tk-fs-sm); color: var(--tk-text-muted); }
.category-controls select.form-control { min-width: 140px; }

@media (max-width: 767.98px) {
  .category-controls { justify-content: flex-start; }
  .category-controls .control { flex: 1 1 100%; }
  /* En pantalla chica los filtros no se pegan: ocupan todo el ancho y
     preceden a la grilla. */
  .filter-sidebar { position: static; }
}

/* "Limpiar": acción terciaria, la usan tanto los filtros como el carrito. */
.btn-clear { color: var(--tk-text-muted); font-size: var(--tk-fs-sm); background: none; border: 0; }
.btn-clear:hover { color: var(--tk-danger); }

.pagination { margin-top: var(--tk-sp-6); }


/* =========================================================================
   11. CARRITO Y CHECKOUT
   ========================================================================= */

.cart-page,
.checkout-page { padding-block: var(--tk-sp-10); }

.cart-title, .checkout-title { font-size: var(--tk-fs-2xl); margin-bottom: var(--tk-sp-8); }

/* Una columna en teléfono y tableta, dos con la barra lateral fija desde 992. */
.cart-grid, .checkout-grid { display: grid; grid-template-columns: 1fr; gap: var(--tk-sp-8); }

@media (min-width: 992px) {
  .cart-grid,
  .checkout-grid { grid-template-columns: minmax(0, 1fr) 360px; }
}

/* Estas vistas usan .card como caja con contenido directo, sin .card-body,
   así que el relleno va en la tarjeta. */
.cart-page .card,
.checkout-page .card {
  padding: var(--tk-sp-6);
  background-color: var(--tk-surface-raised);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  box-shadow: var(--tk-shadow-xs);
}
.checkout-page .card + .card { margin-top: var(--tk-sp-6); }

.checkout-page .card-title,
.summary-title {
  font-size: var(--tk-fs-md);
  padding-bottom: var(--tk-sp-3);
  margin-bottom: var(--tk-sp-5);
  border-bottom: var(--tk-border-width) solid var(--tk-border);
}

/* ---------- Tabla del carrito ---------- */
.cart-table { width: 100%; border-collapse: collapse; }
.cart-table th {
  padding: var(--tk-sp-3) var(--tk-sp-4);
  text-align: left;
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-semi);
  color: var(--tk-text-muted);
  border-bottom: var(--tk-border-width) solid var(--tk-border);
}
.cart-table td {
  padding: var(--tk-sp-5) var(--tk-sp-4);
  vertical-align: middle;
  border-bottom: var(--tk-border-width) solid var(--tk-border);
}
.cart-table tr:last-child td { border-bottom: 0; }

.product-info { display: flex; align-items: center; gap: var(--tk-sp-4); }
.product-thumb,
.cart-item-thumb {
  width: 72px;
  height: 72px;
  object-fit: cover;
  background-color: var(--tk-image-pad);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-sm);
}
.product-details h3 { font-size: var(--tk-fs-sm); margin-bottom: var(--tk-sp-1); }
.product-meta { font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }

.qty-control {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-sm);
  overflow: hidden;
}
/* Los botones de la tabla son rectangulares e integrados al campo: la versión
   redonda de la ficha de producto no encaja dentro de una celda. */
.qty-control .btn-qty {
  width: auto;
  height: auto;
  padding: var(--tk-sp-2) var(--tk-sp-3);
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--tk-text-muted);
  font-size: var(--tk-fs-base);
}
.qty-control .btn-qty:hover { background-color: var(--tk-surface-inset); color: var(--tk-primary-ink); }
.qty-input {
  width: 44px;
  padding: var(--tk-sp-2) 0;
  text-align: center;
  border: 0;
  background-color: var(--tk-surface);
  color: var(--tk-text-strong);
  font-weight: var(--tk-weight-medium);
  appearance: textfield;
  -moz-appearance: textfield;
}
.qty-input::-webkit-outer-spin-button,
.qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ---------- Resumen ---------- */
.summary-card { position: sticky; top: calc(var(--tk-header-height) + var(--tk-sp-5)); }

.summary-row {
  display: flex;
  justify-content: space-between;
  gap: var(--tk-sp-4);
  margin-bottom: var(--tk-sp-3);
  font-size: var(--tk-fs-sm);
  color: var(--tk-text-muted);
}
.summary-row.total {
  margin-top: var(--tk-sp-4);
  padding-top: var(--tk-sp-4);
  border-top: var(--tk-border-width) solid var(--tk-border);
  font-size: var(--tk-fs-lg);
  font-weight: var(--tk-weight-bold);
  color: var(--tk-price);
}

.coupon-form { display: flex; gap: var(--tk-sp-2); margin-bottom: var(--tk-sp-5); }
.coupon-form .form-control { flex: 1 1 auto; min-width: 0; }

/* ---------- Botones propios del carrito ---------- */
.btn-checkout { display: block; width: 100%; padding: var(--tk-sp-3) var(--tk-sp-4); font-size: var(--tk-fs-base); text-align: center; }

.btn-update {
  padding: 0;
  background: none;
  border: 0;
  color: var(--tk-primary-ink);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  text-decoration: underline;
  cursor: pointer;
}
.btn-update:hover { color: var(--tk-primary-hover); }

.btn-remove {
  padding: var(--tk-sp-2);
  background: none;
  border: 0;
  border-radius: var(--tk-radius-xs);
  color: var(--tk-danger);
  cursor: pointer;
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
/* Se enciende el fondo en el mismo rol de peligro; el ícono no cambia de rol. */
.btn-remove:hover { background-color: var(--tk-danger-subtle); color: var(--tk-danger); }

.empty-cart { text-align: center; padding-block: var(--tk-sp-16); }
.empty-cart-icon { font-size: var(--tk-fs-4xl); color: var(--tk-text-disabled); margin-bottom: var(--tk-sp-5); }

/* ---------- Opciones de envío y pago ---------- */
.radio-group { display: flex; flex-direction: column; gap: var(--tk-sp-3); }
.radio-option {
  display: flex;
  align-items: center;
  gap: var(--tk-sp-3);
  padding: var(--tk-sp-3);
  background-color: var(--tk-surface);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  cursor: pointer;
  transition: border-color var(--tk-dur-fast) var(--tk-ease-out),
              background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.radio-option:hover { background-color: var(--tk-surface-sunken); }
.radio-option.selected { border-color: var(--tk-primary); background-color: var(--tk-primary-subtle); }
.radio-input { accent-color: var(--tk-primary); margin: 0; }
.radio-label { flex: 1 1 auto; font-size: var(--tk-fs-sm); font-weight: var(--tk-weight-medium); }
.radio-price { font-weight: var(--tk-weight-semi); color: var(--tk-price); }

/* ---------- Vista previa del pedido ---------- */
.cart-item-preview { display: flex; align-items: center; gap: var(--tk-sp-3); padding-block: var(--tk-sp-3); }
.cart-item-preview + .cart-item-preview { border-top: var(--tk-border-width) solid var(--tk-border); }
.cart-item-info { flex: 1 1 auto; min-width: 0; }
.cart-item-title {
  font-size: var(--tk-fs-sm);
  color: var(--tk-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cart-item-meta { font-size: var(--tk-fs-2xs); color: var(--tk-text-muted); }
.cart-item-price { font-size: var(--tk-fs-sm); font-weight: var(--tk-weight-semi); color: var(--tk-price); }


/* =========================================================================
   12. AUTENTICACIÓN Y PERFIL
   ========================================================================= */

.auth-container,
.profile-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--tk-sp-10) var(--tk-sp-5);
}

/* Fondo, borde y elevación vienen de la primitiva de tarjeta (sección 2). */
.auth-card    { max-width: 460px; padding: var(--tk-sp-10); text-align: center; box-shadow: var(--tk-shadow-lg); }
.profile-card { max-width: 520px; padding: var(--tk-sp-10); text-align: center; box-shadow: var(--tk-shadow-lg); }

.auth-card-mini { text-align: center; }

.auth-header { margin-bottom: var(--tk-sp-8); }
.auth-title { font-size: var(--tk-fs-xl); margin-bottom: var(--tk-sp-2); }
.auth-subtitle { color: var(--tk-text-muted); font-size: var(--tk-fs-sm); margin-bottom: var(--tk-sp-5); }

.social-login { display: flex; flex-direction: column; gap: var(--tk-sp-3); margin-bottom: var(--tk-sp-5); }
.btn-social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--tk-sp-3);
  width: 100%;
  padding: var(--tk-sp-3);
  background-color: var(--tk-surface);
  color: var(--tk-text-strong);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-md);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  cursor: pointer;
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.btn-social:hover { background-color: var(--tk-surface-inset); color: var(--tk-text-strong); }
.btn-social.disabled {
  background-color: var(--tk-surface-sunken);
  color: var(--tk-text-disabled);
  border-color: var(--tk-border);
  cursor: not-allowed;
}

/* Separador con texto al medio. */
.divider {
  display: flex;
  align-items: center;
  gap: var(--tk-sp-3);
  margin-block: var(--tk-sp-6);
  color: var(--tk-text-muted);
  font-size: var(--tk-fs-2xs);
  text-transform: uppercase;
}
.divider::before,
.divider::after { content: ""; flex: 1 1 auto; border-top: var(--tk-border-width) solid var(--tk-border); }

/* El markup de autenticación usa .form-input, no .form-control: se le da el
   mismo aspecto que al control de Bootstrap para que no convivan dos campos
   distintos en la misma pantalla. */
.form-input {
  display: block;
  width: 100%;
  padding: var(--tk-sp-3);
  background-color: var(--tk-surface);
  color: var(--tk-text);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-sm);
  font-family: inherit;
  font-size: var(--tk-fs-sm);
}
.form-input::placeholder { color: var(--tk-text-muted); }
.form-input:focus {
  outline: none;
  border-color: var(--tk-focus-ring);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--tk-focus-ring) 25%, transparent);
}

/* Color y hover salen de la primitiva de botón sólido (sección 2). */
.auth-card .btn-primary,
.auth-card-mini .btn-primary { width: 100%; padding: var(--tk-sp-3); font-size: var(--tk-fs-sm); }

.auth-footer { margin-top: var(--tk-sp-6); font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }

/* Ventana de ingreso rápido. */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1055;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--tk-sp-4);
  background-color: var(--tk-scrim);
}
.modal-container {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: var(--tk-sp-8);
  background-color: var(--tk-surface-raised);
  border-radius: var(--tk-radius-lg);
  box-shadow: var(--tk-shadow-xl);
}
.modal-close {
  position: absolute;
  top: var(--tk-sp-2);
  right: var(--tk-sp-4);
  color: var(--tk-text-muted);
  font-size: var(--tk-fs-xl);
  line-height: 1;
  cursor: pointer;
}
.modal-close:hover { color: var(--tk-text-strong); }

/* .close es el cierre de Bootstrap 3; en 5 se llama .btn-close y se dibuja con
   una imagen de fondo. Mientras el markup use el nombre viejo, la cruz textual
   necesita forma propia. */
.close {
  float: right;
  background: none;
  border: 0;
  color: var(--tk-text-muted);
  font-size: var(--tk-fs-xl);
  line-height: 1;
  cursor: pointer;
}
.close:hover { color: var(--tk-text-strong); }

/* ---------- Perfil ---------- */
.profile-avatar {
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  margin: 0 auto var(--tk-sp-6);
  border-radius: var(--tk-radius-pill);
  background-color: var(--tk-primary-subtle);
  color: var(--tk-primary-ink);
  font-size: var(--tk-fs-3xl);
  font-weight: var(--tk-weight-semi);
}
.profile-name { font-size: var(--tk-fs-xl); margin-bottom: var(--tk-sp-2); }
.profile-email { color: var(--tk-text-muted); margin-bottom: var(--tk-sp-8); }

.profile-details {
  padding: var(--tk-sp-5);
  margin-bottom: var(--tk-sp-8);
  text-align: left;
  background-color: var(--tk-surface-sunken);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
}
.detail-item { margin-bottom: var(--tk-sp-3); font-size: var(--tk-fs-sm); }
.detail-label { display: block; margin-bottom: var(--tk-sp-1); font-weight: var(--tk-weight-semi); color: var(--tk-text-strong); }
.detail-value { color: var(--tk-text-muted); }

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--tk-sp-3);
  width: 100%;
  max-width: 900px;
  margin-bottom: var(--tk-sp-6);
}
.page-title { font-size: var(--tk-fs-xl); margin: 0; }

.btn-back { color: var(--tk-primary-ink); font-weight: var(--tk-weight-semi); font-size: var(--tk-fs-sm); }

.orders-card { max-width: 800px; padding: var(--tk-sp-10); text-align: center; }
.empty-state-icon { font-size: var(--tk-fs-4xl); color: var(--tk-text-disabled); margin-bottom: var(--tk-sp-4); }
.empty-state-text { color: var(--tk-text-muted); }

.addresses-grid { display: grid; grid-template-columns: 1fr; gap: var(--tk-sp-6); width: 100%; max-width: 900px; }
@media (min-width: 768px) {
  .addresses-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.address-card { position: relative; padding: var(--tk-sp-8); }
.address-card.is-default { border-color: var(--tk-primary); }

.default-badge {
  position: absolute;
  top: var(--tk-sp-4);
  right: var(--tk-sp-4);
  padding: var(--tk-sp-1) var(--tk-sp-2);
  background-color: var(--tk-primary);
  color: var(--tk-on-primary);
  border-radius: var(--tk-radius-xs);
  font-size: var(--tk-fs-2xs);
  font-weight: var(--tk-weight-semi);
}

.address-title {
  font-size: var(--tk-fs-md);
  padding-bottom: var(--tk-sp-3);
  margin-bottom: var(--tk-sp-5);
  border-bottom: var(--tk-border-width) solid var(--tk-border);
}
.address-details p { margin-bottom: var(--tk-sp-2); font-size: var(--tk-fs-sm); color: var(--tk-text-muted); }
.address-details strong { color: var(--tk-text-strong); }

.btn-add-address { padding: var(--tk-sp-2) var(--tk-sp-5); font-size: var(--tk-fs-sm); }

/* Cerrar sesión: rol destructivo suave. El hover solo intensifica el fondo. */
.btn-logout {
  display: block;
  width: 100%;
  padding: var(--tk-sp-3);
  background-color: var(--tk-danger-subtle);
  color: var(--tk-danger);
  border: var(--tk-border-width) solid var(--tk-danger-border);
  border-radius: var(--tk-radius-md);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-semi);
  text-align: center;
  cursor: pointer;
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.btn-logout:hover { background-color: var(--tk-danger-border); color: var(--tk-danger); }


/* =========================================================================
   13. ESTADOS: SIN STOCK, OFERTA, CARGANDO
   ========================================================================= */

/* Sin stock es ausencia, no error: gris apagado, nunca rojo de alarma. */
.out-of-stock { text-align: center; color: var(--tk-stock-out); font-size: var(--tk-fs-sm); font-weight: var(--tk-weight-medium); }
.out-of-stock .inner {
  display: inline-block;
  padding: var(--tk-sp-1) var(--tk-sp-3);
  background-color: var(--tk-surface-inset);
  border-radius: var(--tk-radius-pill);
}

/* Insignias sobre la foto de la ficha de producto. */
.badge-ostock,
.badge-free,
.badge-discount {
  display: inline-block;
  padding: var(--tk-sp-1) var(--tk-sp-2);
  border-radius: var(--tk-radius-pill);
  font-size: var(--tk-fs-2xs);
  font-weight: var(--tk-weight-semi);
  line-height: var(--tk-lh-tight);
}
.badge-ostock, .badge-free { position: absolute; top: var(--tk-sp-3); z-index: 1; }
.badge-ostock { left: var(--tk-sp-3); background-color: var(--tk-surface-inverse); color: var(--tk-text-inverse); }
.badge-free { right: var(--tk-sp-3); background-color: var(--tk-success); color: var(--tk-on-success); }
/* El descuento usa el acento de oferta, que es un token aparte del de marca:
   una oferta tiene que leerse igual aunque el comerciante cambie su color. */
.badge-discount { margin-left: var(--tk-sp-2); background-color: var(--tk-sale); color: var(--tk-on-sale); vertical-align: middle; }

/* El mensaje de error de un campo. Bootstrap lo oculta salvo junto a
   .is-invalid; en las vistas de cuenta viene suelto, así que se muestra. */
.auth-card .invalid-feedback,
.auth-card-mini .invalid-feedback,
.form-group .invalid-feedback {
  display: block;
  margin-top: var(--tk-sp-1);
  font-size: var(--tk-fs-2xs);
  color: var(--tk-danger);
  text-align: left;
}

/* Estado de carga genérico: atenúa e inhabilita sin ocultar. Reemplaza al
   opacity:0 de la librería de carrusel, que dejaba la portada en blanco
   cuando su callback de inicialización no llegaba a correr. */
.is-loading { opacity: .6; pointer-events: none; }


/* =========================================================================
   14. AJUSTES RESPONSIVOS
   =========================================================================
   Solo cortes de la escala de Bootstrap 5. Las formas .98 son las que usa el
   propio Bootstrap para el límite superior de un tramo, no cortes nuevos.
   ========================================================================= */

/* ---------- Teléfono: compactar el encabezado ----------
   Antes el encabezado consumía unos 420px de alto antes de cualquier
   contenido, porque las tres columnas de Bootstrap se apilaban en tres filas
   completas y el logo medía 80px.

   Acá se reordena a dos filas: [logo | acciones] y [buscador], con el logo a
   40px. El encabezado queda en unos 175px, incluida la barra de contacto y
   el botón del menú. */
@media (max-width: 991.98px) {
  .header .inner { flex-wrap: wrap; align-items: center; column-gap: var(--tk-sp-3); }
  /* Se anula el width:100% que Bootstrap le da a .col-md-* por debajo de md. */
  .header .inner .logo { order: 1; flex: 0 0 auto; width: auto; text-align: left; }
  .header .inner .right { order: 2; flex: 1 1 auto; width: auto; }
  .header .inner .search-area { order: 3; flex: 1 1 100%; width: 100%; }
  .header .right ul { gap: var(--tk-sp-3); font-size: var(--tk-fs-xs); }
  .header .logo img { max-height: 36px; }

  /* El desplegable no puede ser más ancho que la pantalla. */
  .mini-cart-dropdown { width: min(320px, calc(100vw - var(--tk-sp-8))); right: calc(var(--tk-sp-2) * -1); }
}

@media (min-width: 992px) {
  .header .inner { flex-wrap: nowrap; padding-block: var(--tk-sp-3); }
  .header .logo img { max-height: 56px; }
  .search-area form { max-width: 360px; margin-left: auto; }
}

/* ---------- Tablas del carrito en pantalla angosta ----------
   La tabla no se reconstruye en tarjetas (haría falta tocar el markup), pero
   se le permite desplazarse en lugar de romper el ancho de la página. */
@media (max-width: 767.98px) {
  .cart-table { display: block; overflow-x: auto; white-space: nowrap; }
  .cart-table td { padding: var(--tk-sp-3) var(--tk-sp-2); }
  .product-thumb, .cart-item-thumb { width: 56px; height: 56px; }

  .cart-title, .checkout-title { font-size: var(--tk-fs-xl); }
  .auth-card, .profile-card, .orders-card, .address-card { padding: var(--tk-sp-6); }
  .auth-container, .profile-container { padding-inline: var(--tk-sp-4); }

  .product-action-buttons { flex-direction: column; }
  .btn-cart, .btn-buy-now { flex: 1 1 auto; width: 100%; }
}

/* ---------- Pantalla ancha ---------- */
@media (min-width: 1200px) {
  .page { padding-block: var(--tk-sp-16); }
  .product-price { font-size: var(--tk-fs-3xl); }
}

/* ==========================================================================
   COMPONENTES (biblioteca nueva, fase 4)
   --------------------------------------------------------------------------
   Nomenclatura por bloque y elemento. Reemplaza progresivamente a las clases
   heredadas del tema comprado, que quedan hasta terminar de convertir vistas.
   ========================================================================== */

/* --- Tarjeta de producto -------------------------------------------------- */
.pcard {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--tk-surface-raised);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  overflow: hidden;
  transition: transform var(--tk-dur-base) var(--tk-ease-out),
              box-shadow var(--tk-dur-base) var(--tk-ease-out);
}

/* El hover solo se activa donde hay puntero de verdad. En tactil, un :hover
   pegajoso deja la tarjeta en estado elevado hasta que se toca otra cosa. */
@media (hover: hover) {
  .pcard:hover { transform: translateY(-2px); box-shadow: var(--tk-shadow-md); }
  .pcard:hover .pcard__media img { transform: scale(1.04); }
}

.pcard__link { display: flex; flex-direction: column; flex: 1 1 auto; text-decoration: none; color: inherit; }
.pcard__link:hover { text-decoration: none; color: inherit; }

/* Proporción configurable por rubro: retrato para ropa, cuadrado para ferretería.
   `contain` no recorta nunca, así que todas las tarjetas de una fila miden igual
   sin cortarle las piernas a un pijama ni deformar una herramienta. */
.pcard__media {
  aspect-ratio: var(--tk-product-aspect);
  background: var(--tk-image-pad);
  overflow: hidden;
}
.pcard__media img {
  width: 100%; height: 100%;
  object-fit: contain;
  transition: transform var(--tk-dur-slow) var(--tk-ease-out);
}

.pcard__body { padding: var(--tk-sp-3); display: flex; flex-direction: column; gap: var(--tk-sp-1); }

/* Altura mínima para que los precios de toda la fila queden a la misma altura
   aunque unos nombres ocupen una línea y otros dos. Sin esto la fila baila. */
.pcard__title {
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  color: var(--tk-text-strong);
  line-height: 1.35;
  margin: 0;
  min-height: calc(var(--tk-fs-sm) * 1.35 * 2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pcard__badges { position: absolute; top: var(--tk-sp-2); left: var(--tk-sp-2); right: var(--tk-sp-2);
                 display: flex; justify-content: space-between; gap: var(--tk-sp-1); pointer-events: none; }
.pcard__action { padding: 0 var(--tk-sp-3) var(--tk-sp-3); }
.pcard--out .pcard__media img { opacity: .55; filter: grayscale(.25); }
.pcard--out .price__current { color: var(--tk-text-muted); }

/* --- Precio --------------------------------------------------------------- */
.price { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--tk-sp-2); }
.price__current { font-weight: var(--tk-weight-bold); color: var(--tk-price); }
.price--sm .price__current { font-size: var(--tk-fs-sm); }
.price--md .price__current { font-size: var(--tk-fs-md); }
.price--lg .price__current { font-size: var(--tk-fs-2xl); }
.price__old { font-size: var(--tk-fs-xs); color: var(--tk-price-old); font-weight: var(--tk-weight-normal); }
.price__off {
  font-size: var(--tk-fs-3xs); font-weight: var(--tk-weight-semi);
  background: var(--tk-sale); color: var(--tk-on-sale);
  padding: 2px var(--tk-sp-2); border-radius: var(--tk-radius-xs);
}

/* --- Calificación --------------------------------------------------------- */
.rating { display: inline-flex; align-items: center; gap: 2px; font-size: var(--tk-fs-xs); }
.rating .fa { color: var(--tk-warning); }
.rating__count { margin-left: var(--tk-sp-1); color: var(--tk-text-muted); }

/* --- Insignias ------------------------------------------------------------ */
.badge-stock, .badge-off {
  font-size: var(--tk-fs-3xs); font-weight: var(--tk-weight-semi);
  padding: 3px var(--tk-sp-2); border-radius: var(--tk-radius-xs);
  pointer-events: auto; white-space: nowrap;
}
.badge-stock--out { background: var(--tk-surface-inset); color: var(--tk-text); }
.badge-stock--low { background: var(--tk-warning-subtle); color: var(--tk-warning); }
.badge-off        { background: var(--tk-sale); color: var(--tk-on-sale); margin-left: auto; }

/* --- Estado vacío --------------------------------------------------------- */
.empty-state { text-align: center; padding: var(--tk-sp-12) var(--tk-sp-4); }
.empty-state__title { font-size: var(--tk-fs-lg); font-weight: var(--tk-weight-semi);
                      color: var(--tk-text-strong); margin-bottom: var(--tk-sp-2); }
.empty-state__text  { color: var(--tk-text-muted); margin-bottom: var(--tk-sp-5); }
.empty-state__chips { display: flex; flex-wrap: wrap; gap: var(--tk-sp-2); justify-content: center;
                      margin-top: var(--tk-sp-5); }
.chip {
  display: inline-block; padding: var(--tk-sp-1) var(--tk-sp-3);
  background: var(--tk-surface-inset); color: var(--tk-text);
  border-radius: var(--tk-radius-pill); font-size: var(--tk-fs-xs); text-decoration: none;
}
.chip:hover { background: var(--tk-primary-subtle); color: var(--tk-primary-ink); text-decoration: none; }

/* --- Selector de variantes ------------------------------------------------
   Un solo tipo de ficha con tres rellenos: texto, muestra de color y miniatura.
   La ficha de producto usaba tres lenguajes visuales distintos para lo mismo:
   botones para talles, un desplegable pelado para colores y miniaturas para
   disenos. Tres formas de elegir en la misma pantalla. */
.vaxis { border: 0; padding: 0; margin: 0 0 var(--tk-sp-4); }
.vaxis__legend {
  display: flex; justify-content: space-between; align-items: baseline;
  flex-wrap: wrap; gap: var(--tk-sp-2);
  font-size: var(--tk-fs-sm); font-weight: var(--tk-weight-semi);
  color: var(--tk-text-strong); margin-bottom: var(--tk-sp-2); width: 100%;
}
.vaxis__selected { font-weight: var(--tk-weight-normal); color: var(--tk-primary-ink); }
.vaxis__options  { display: flex; flex-wrap: wrap; gap: var(--tk-sp-2); }

.vchip {
  --borde: var(--tk-border-strong);
  display: inline-flex; align-items: center; justify-content: center;
  /* 44 pixeles de lado: es el minimo que un dedo acierta sin apuntar. A 40 se
     falla lo suficiente como para que elegir un talle en telefono moleste. */
  min-width: 48px; min-height: 44px; padding: 0 var(--tk-sp-3);
  border: var(--tk-border-width) solid var(--borde);
  border-radius: var(--tk-radius-sm);
  background: var(--tk-surface);
  color: var(--tk-text-strong);
  font-size: var(--tk-fs-sm);
  cursor: pointer; position: relative;
  transition: border-color var(--tk-dur-fast) var(--tk-ease-out),
              background-color var(--tk-dur-fast) var(--tk-ease-out);
}
@media (hover: hover) { .vchip:hover { --borde: var(--tk-n-400); } }

/* Elegido: borde de 2px MAS un tilde. Nunca solo color: quien no distingue
   el matiz tiene que poder ver cual eligio. */
.vchip__input:checked + .vchip {
  --borde: var(--tk-primary);
  border-width: 2px;
  background: var(--tk-primary-subtle);
}
.vchip__input:checked + .vchip::after {
  content: "✓"; position: absolute; top: -6px; right: -6px;
  width: 16px; height: 16px; line-height: 16px; text-align: center;
  font-size: var(--tk-fs-3xs);
  background: var(--tk-primary); color: var(--tk-on-primary);
  border-radius: var(--tk-radius-pill);
}
.vchip__input:focus-visible + .vchip {
  outline: var(--tk-focus-width) solid var(--tk-focus-ring);
  outline-offset: 2px;
}

/* Sin stock: se MUESTRA, no se oculta, y sigue siendo elegible para poder
   explicar que falta. La diagonal es la senal no cromatica. */
.vchip--out { opacity: .45; --borde: var(--tk-border); border-style: dashed; }
.vchip--out::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top right, transparent calc(50% - 1px),
              currentColor calc(50% - 1px), currentColor calc(50% + 1px),
              transparent calc(50% + 1px));
  opacity: .5; pointer-events: none;
}

.vchip--swatch_color { min-width: 44px; width: 44px; height: 44px; padding: 4px; }
.vchip__swatch {
  width: 100%; height: 100%; border-radius: calc(var(--tk-radius-sm) - 2px);
  background: var(--muestra, var(--tk-surface-inset));
  /* Borde interior: sin el, una muestra blanca desaparece sobre fondo blanco. */
  box-shadow: inset 0 0 0 1px var(--tk-border-strong);
}
.vchip--swatch_image { min-width: 56px; width: 56px; height: 56px; padding: 3px; overflow: hidden; }
.vchip__img { width: 100%; height: 100%; object-fit: cover; border-radius: calc(var(--tk-radius-sm) - 2px); }

.vaxis__aviso { margin: var(--tk-sp-2) 0 0; font-size: var(--tk-fs-xs); color: var(--tk-warning); }
.vaxis__aviso:empty { display: none; }

/* --- Miga de navegacion --------------------------------------------------- */
.breadcrumb-nav { margin-bottom: var(--tk-sp-5); }
.breadcrumb-nav__list {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--tk-sp-2);
  list-style: none; margin: 0; padding: 0;
  font-size: var(--tk-fs-xs); color: var(--tk-text-muted);
}
/* El separador se dibuja con CSS y no se escribe en el markup: asi los lectores
   de pantalla no leen un simbolo suelto entre cada nivel. */
.breadcrumb-nav__item + .breadcrumb-nav__item::before {
  content: "/"; margin-right: var(--tk-sp-2); color: var(--tk-text-disabled);
}
.breadcrumb-nav__item a { color: var(--tk-text-muted); text-decoration: none; }
.breadcrumb-nav__item a:hover { color: var(--tk-primary-ink); text-decoration: underline; }
.breadcrumb-nav__item [aria-current] { color: var(--tk-text); }

/* --- Galeria de producto -------------------------------------------------- */
.gallery { display: flex; gap: var(--tk-sp-3); align-items: flex-start; }

.gallery__thumbs {
  display: flex; flex-direction: column; gap: var(--tk-sp-2);
  flex: 0 0 72px; max-height: 520px; overflow-y: auto;
  scrollbar-width: thin;
}
.gallery__thumb {
  width: 72px; height: 72px; padding: 2px;
  border: 2px solid transparent; border-radius: var(--tk-radius-sm);
  background: var(--tk-image-pad); cursor: pointer;
  transition: border-color var(--tk-dur-fast) var(--tk-ease-out);
}
.gallery__thumb img { width: 100%; height: 100%; object-fit: contain; border-radius: calc(var(--tk-radius-sm) - 2px); }
.gallery__thumb.is-selected { border-color: var(--tk-primary); }
@media (hover: hover) { .gallery__thumb:hover { border-color: var(--tk-border-strong); } }

/* La imagen principal OCUPA su columna. Antes media unos 270px dentro de una
   columna de 600 y dejaba un hueco blanco de casi 300px de alto debajo. */
.gallery__main {
  position: relative; flex: 1 1 auto; min-width: 0;
  background: var(--tk-image-pad); border-radius: var(--tk-radius-md); overflow: hidden;
}
.gallery__main img {
  width: 100%; height: auto;
  aspect-ratio: 4 / 5; object-fit: contain;
  display: block; cursor: zoom-in;
}
.gallery__zoom {
  position: absolute; right: var(--tk-sp-3); bottom: var(--tk-sp-3);
  width: 44px; height: 44px; border-radius: var(--tk-radius-pill);
  border: var(--tk-border-width) solid var(--tk-border);
  background: var(--tk-surface); color: var(--tk-text);
  font-size: var(--tk-fs-lg); line-height: 1;
  box-shadow: var(--tk-shadow-sm); cursor: pointer;
}

/* Ampliacion con el elemento de dialogo nativo: trae cierre con escape, foco
   atrapado y fondo oscurecido sin ninguna libreria. */
.gallery-dialog {
  border: 0; padding: 0; background: transparent;
  max-width: 96vw; max-height: 96vh;
}
.gallery-dialog::backdrop { background: var(--tk-scrim); }
.gallery-dialog img { max-width: 96vw; max-height: 92vh; object-fit: contain; display: block; }
.gallery-dialog__close {
  position: absolute; top: var(--tk-sp-2); right: var(--tk-sp-2);
  width: 40px; height: 40px; font-size: var(--tk-fs-xl); line-height: 1;
  border: 0; border-radius: var(--tk-radius-pill);
  background: var(--tk-surface); color: var(--tk-text-strong); cursor: pointer;
}

/* En telefono las miniaturas pasan abajo y en fila: una columna de 72px se come
   un quinto del ancho util. */
@media (max-width: 767.98px) {
  .gallery { flex-direction: column-reverse; }
  .gallery__thumbs { flex-direction: row; flex: 0 0 auto; max-height: none; width: 100%; overflow-x: auto; }
  .gallery__thumb { flex: 0 0 56px; width: 56px; height: 56px; }
}

/* --- Panel de filtros ------------------------------------------------------
   Reemplaza a los dos paneles que habia, uno para categoria y otro para
   busqueda, con markup distinto para exactamente lo mismo. */
.filtros__titulo { font-size: var(--tk-fs-md); font-weight: var(--tk-weight-semi);
                   color: var(--tk-text-strong); margin-bottom: var(--tk-sp-4); }
.filtros__grupo  { border: 0; padding: 0 0 var(--tk-sp-4); margin: 0 0 var(--tk-sp-4);
                   border-bottom: var(--tk-border-width) solid var(--tk-border); }
.filtros__grupo:last-of-type { border-bottom: 0; }
.filtros__grupo legend { font-size: var(--tk-fs-sm); font-weight: var(--tk-weight-semi);
                         color: var(--tk-text-strong); margin-bottom: var(--tk-sp-2); }
.filtros__chips  { display: flex; flex-wrap: wrap; gap: var(--tk-sp-2); }
.filtros__rango  { display: flex; gap: var(--tk-sp-2); margin-top: var(--tk-sp-3); }
.filtros__check  { display: flex; align-items: center; gap: var(--tk-sp-2);
                   font-size: var(--tk-fs-sm); padding: var(--tk-sp-1) 0; cursor: pointer; }
.filtros__acciones { display: grid; gap: var(--tk-sp-2); margin-top: var(--tk-sp-5); }

/* La ficha es a la vez etiqueta de casilla y enlace, segun el caso. */
.chip { position: relative; display: inline-flex; align-items: center; gap: var(--tk-sp-1);
        border: var(--tk-border-width) solid var(--tk-border-strong); }
.chip--activo { border-color: var(--tk-primary); border-width: 2px;
                background: var(--tk-primary-subtle); color: var(--tk-primary-ink); }
.chip__n { color: var(--tk-text-muted); font-size: var(--tk-fs-3xs); }
.chip__muestra { width: 14px; height: 14px; border-radius: var(--tk-radius-pill);
                 background: var(--muestra, var(--tk-surface-inset));
                 box-shadow: inset 0 0 0 1px var(--tk-border-strong); }
.chip--quitable .chip__x { font-size: var(--tk-fs-sm); line-height: 1; opacity: .65; }
.chip--quitable:hover .chip__x { opacity: 1; }

.filtros-activos { display: flex; flex-wrap: wrap; align-items: center; gap: var(--tk-sp-2);
                   margin-bottom: var(--tk-sp-4); }
.filtros-activos__limpiar { font-size: var(--tk-fs-xs); color: var(--tk-text-muted);
                            text-decoration: underline; }

/* En telefono los filtros van en un panel deslizante. Antes el panel lateral
   completo quedaba APILADO ARRIBA de la grilla, asi que habia que pasar por seis
   acordeones de filtros antes de ver un solo producto. */
@media (max-width: 991.98px) {
  .filtros-barra { position: sticky; top: var(--tk-header-height); z-index: 1020;
                   display: grid; grid-template-columns: 1fr 1fr; gap: var(--tk-sp-2);
                   background: var(--tk-surface); padding: var(--tk-sp-2) 0;
                   border-bottom: var(--tk-border-width) solid var(--tk-border); }
  .filtros-barra .btn { min-height: 44px; }
}
@media (min-width: 992px) { .filtros-barra { display: none; } }

/* --- Encabezado de paginas estaticas ---------------------------------------
   Estaba escrito a mano, identico, en las tres paginas. */
.page-hero {
  background: var(--tk-surface-sunken);
  border-radius: var(--tk-radius-lg);
  padding: var(--tk-sp-5);
  margin-bottom: var(--tk-sp-4);
}
.page-hero h1 { font-size: var(--tk-fs-xl); font-weight: var(--tk-weight-bold); margin: 0; }

/* Los selectores de orden y cantidad por pagina llevaban el borde escrito
   en el atributo de estilo, cinco veces. */
.category-toolbar select { border: var(--tk-border-width) solid var(--tk-border-strong); }

/* --- Barra inferior de la ficha en telefono --------------------------------
   La anterior daba la mitad del ancho a "Compartir", que es la accion MENOS
   frecuente, y no mostraba ni el precio ni la variante elegida, que es
   justamente la informacion que se pierde al bajar por la pagina. */
.barra-movil { display: none; }

@media (max-width: 767.98px) {
  .barra-movil {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 1040;
    display: flex; align-items: center; gap: var(--tk-sp-3);
    padding: var(--tk-sp-3) var(--tk-sp-4);
    padding-bottom: calc(var(--tk-sp-3) + env(safe-area-inset-bottom));
    background: var(--tk-surface);
    border-top: var(--tk-border-width) solid var(--tk-border);
    box-shadow: 0 -2px 10px rgb(16 24 40 / 12%);
  }
  .barra-movil__info     { display: flex; flex-direction: column; min-width: 0; }
  .barra-movil__precio   { font-size: var(--tk-fs-md); font-weight: var(--tk-weight-bold);
                           color: var(--tk-price); line-height: 1.2; }
  .barra-movil__variante { font-size: var(--tk-fs-2xs); color: var(--tk-text-muted);
                           white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .barra-movil__cta      { flex: 1 1 auto; min-height: 44px; }

  /* El contenido no debe quedar tapado por la barra. */
  /* El hueco lo reserva el cuerpo SOLO si la pagina tiene barra fija. Cuando
     estaba puesto siempre, la portada, el carrito y las preguntas frecuentes
     quedaban con una franja vacia de 64 pixeles debajo del copyright sin
     ninguna barra que la justificara. Y donde si la hay, el reservado se
     quedaba corto: la barra mide 69 y tapaba los ultimos pixeles del pie. */
  body:has(.barra-movil) {
    --tk-barra-inferior: calc(72px + env(safe-area-inset-bottom));
    padding-bottom: var(--tk-barra-inferior);
  }
}


/* =========================================================================
   14. CARRITO (fase 5)
   =========================================================================
   Reemplaza a la tabla de cuatro columnas de la vista anterior. Una tabla con
   producto, cantidad, total y quitar obliga, en 390 píxeles, a desplazar en
   horizontal o a romper la semántica; acá es una lista y cada línea se
   reacomoda sola.

   Los tres controles de cantidad son TRES FORMULARIOS HERMANOS. El recuadro que
   parece un control único lo dibuja `.qty`; los formularios de adentro no
   aportan ninguna caja. Así el aspecto no obliga a anidar formularios, que es
   lo que rompía el botón de vaciar.
   ========================================================================= */

/* El atributo `hidden` lo pisa cualquier `display` propio, así que cada bloque
   que se oculta por script lo declara. */
.cartline[hidden],
.cart-undo[hidden],
.summary-row[hidden],
.cart-summary__recalculando[hidden],
.mini-cart__panel[hidden],
.mini-cart__pie[hidden],
.mini-cart__vacio[hidden],
.mini-cart__contador[hidden] { display: none; }

/* ---------- Avisos ---------- */
.cart-avisos:empty { display: none; }
.cart-avisos .alert { margin-bottom: var(--tk-sp-3); }

/* ---------- Lista de líneas ---------- */
.cart-lines { display: flex; flex-direction: column; gap: var(--tk-sp-4); }

.cartline-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background-color: var(--tk-surface-raised);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  box-shadow: var(--tk-shadow-xs);
}

/* Teléfono: la miniatura y el nombre arriba, y debajo cantidad e importe, que
   son los dos datos que se tocan. */
.cartline {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  grid-template-areas:
    "media info   quitar"
    "cant  cant   total";
  align-items: center;
  gap: var(--tk-sp-3);
  padding: var(--tk-sp-4);
}
.cartline + .cartline { border-top: var(--tk-border-width) solid var(--tk-border); }

.cartline__media  { grid-area: media; display: block; }
.cartline__info   { grid-area: info; min-width: 0; }
.cartline__qty    { grid-area: cant; }
.cartline__total  { grid-area: total; margin: 0; text-align: right; }
.cartline__remove { grid-area: quitar; margin: 0; justify-self: end; }

@media (min-width: 768px) {
  .cartline {
    grid-template-columns: 88px minmax(0, 1fr) auto auto auto;
    grid-template-areas: "media info cant total quitar";
    gap: var(--tk-sp-4);
    padding: var(--tk-sp-5);
  }
  .cartline__total { min-width: 110px; }
}

.cartline__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  background-color: var(--tk-image-pad);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-sm);
}

.cartline__name {
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  line-height: 1.35;
  margin: 0 0 var(--tk-sp-1);
}
.cartline__name a { color: var(--tk-text-strong); text-decoration: none; }
.cartline__name a:hover { color: var(--tk-primary-ink); text-decoration: underline; }

/* La variante es una ficha y no texto suelto: con dos ejes —talle y color— el
   texto plano se lee como una sola frase y no se ve dónde termina uno. */
.cartline__ejes { display: flex; flex-wrap: wrap; gap: var(--tk-sp-1); margin: 0 0 var(--tk-sp-1); }
.chip--sm { font-size: var(--tk-fs-3xs); padding: 2px var(--tk-sp-2); }

.cartline__unit { margin: 0; font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }
.cartline__sku {
  margin-left: var(--tk-sp-2);
  font-family: var(--tk-font-mono);
  font-size: var(--tk-fs-3xs);
  /* `--tk-text-disabled` es el gris de lo que NO se puede usar, y daba 2,58:1.
     El código del artículo no está deshabilitado: es el dato con el que el
     comercio identifica qué preparar y con el que el cliente reclama si le llegó
     otra cosa. Va en el gris de texto secundario, que sí se lee. */
  color: var(--tk-text-muted);
}
.cartline__stock { margin: var(--tk-sp-2) 0 0; }

/* ---------- Control de cantidad ---------- */
.cartline__qty-label {
  display: block;
  font-size: var(--tk-fs-3xs);
  color: var(--tk-text-muted);
  margin-bottom: var(--tk-sp-1);
}
@media (min-width: 768px) {
  /* En escritorio la columna ya se entiende sola; la etiqueta queda para quien
     usa lector de pantalla, que la necesita para nombrar el grupo. */
  .cartline__qty-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

.qty {
  display: inline-flex;
  align-items: stretch;
  background-color: var(--tk-surface);
  border: var(--tk-border-width) solid var(--tk-border-strong);
  border-radius: var(--tk-radius-sm);
  overflow: hidden;
}
/* Los formularios son estructura, no caja: no aportan ni margen ni borde. */
.qty__form { display: flex; margin: 0; }

.qty__paso {
  width: 40px;
  min-height: 40px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--tk-text);
  font-size: var(--tk-fs-md);
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.qty__paso:hover:not(:disabled) { background-color: var(--tk-surface-inset); color: var(--tk-primary-ink); }
.qty__paso:disabled { color: var(--tk-text-disabled); cursor: default; }
.qty__paso:focus-visible { outline: var(--tk-focus-width) solid var(--tk-focus-ring); outline-offset: -2px; }

.qty__campo {
  width: 52px;
  min-height: 40px;
  padding: 0;
  text-align: center;
  background-color: var(--tk-surface);
  color: var(--tk-text-strong);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  border: 0;
  border-inline: var(--tk-border-width) solid var(--tk-border);
  appearance: textfield;
  -moz-appearance: textfield;
}
.qty__campo::-webkit-outer-spin-button,
.qty__campo::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qty__campo:focus-visible { outline: var(--tk-focus-width) solid var(--tk-focus-ring); outline-offset: -2px; }

.cartline__total { font-size: var(--tk-fs-md); font-weight: var(--tk-weight-semi); color: var(--tk-price); }

/* Mientras el servidor recalcula, el importe viejo sigue legible pero atenuado.
   No se inventa una cifra: el servidor puede recortar la cantidad al stock. */
.cartline.is-recalculando .cartline__total,
.cart-summary.is-recalculando .summary-row { opacity: .5; }
.cartline.is-recalculando .cartline__total { transition: opacity var(--tk-dur-fast) var(--tk-ease-out); }

/* ---------- Barra de acciones ---------- */
.cart-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--tk-sp-3);
  justify-content: space-between;
  align-items: center;
}
.cart-toolbar form { margin: 0; }
.cart-toolbar__seguir { font-size: var(--tk-fs-sm); color: var(--tk-primary-ink); text-decoration: none; }
.cart-toolbar__seguir:hover { color: var(--tk-primary-hover); text-decoration: underline; }

/* ---------- Resumen ---------- */
.cart-summary__unidades {
  margin: 0 0 var(--tk-sp-4);
  font-size: var(--tk-fs-xs);
  color: var(--tk-text-muted);
}
/* El signo menos va en el CSS y no en el texto: en el HTML sería un carácter
   suelto que el lector de pantalla lee fuera de contexto. */
.cart-summary__resta::before { content: "\2212\00a0"; }

.cart-summary__recalculando {
  margin: var(--tk-sp-3) 0 0;
  font-size: var(--tk-fs-xs);
  color: var(--tk-text-muted);
}

.cart-summary .btn-checkout { margin-top: var(--tk-sp-5); }

.cart-summary__seguir {
  display: block;
  margin-top: var(--tk-sp-4);
  text-align: center;
  font-size: var(--tk-fs-sm);
  color: var(--tk-text-muted);
  text-decoration: none;
}
.cart-summary__seguir:hover { color: var(--tk-primary-ink); text-decoration: underline; }

/* ---------- Deshacer ----------
   Reemplaza al confirm() del navegador, que no se puede traducir ni estilar y
   que además preguntaba antes de una acción que es trivial de revertir. */
.cart-undo {
  position: fixed;
  left: 50%;
  bottom: var(--tk-sp-5);
  transform: translateX(-50%);
  z-index: 1080;
  display: flex;
  align-items: center;
  gap: var(--tk-sp-4);
  width: max-content;
  max-width: calc(100vw - var(--tk-sp-8));
  padding: var(--tk-sp-3) var(--tk-sp-4);
  background-color: var(--tk-surface-inverse);
  color: var(--tk-text-inverse);
  border-radius: var(--tk-radius-md);
  box-shadow: var(--tk-shadow-lg);
}
.cart-undo__texto { margin: 0; font-size: var(--tk-fs-sm); }
.cart-undo__boton {
  flex: 0 0 auto;
  padding: var(--tk-sp-1) var(--tk-sp-3);
  background: none;
  border: var(--tk-border-width) solid currentColor;
  border-radius: var(--tk-radius-sm);
  color: inherit;
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-semi);
  cursor: pointer;
}
.cart-undo__boton:hover { background-color: var(--tk-surface-inset); color: var(--tk-text-strong); }

/* ---------- Mini carrito del encabezado ---------- */
.mini-cart { position: relative; }

.mini-cart__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--tk-sp-2);
  color: inherit;
  text-decoration: none;
}
.mini-cart__toggle:hover { color: var(--tk-primary-ink); text-decoration: none; }

.mini-cart__contador {
  min-width: 20px;
  padding: 0 var(--tk-sp-1);
  background-color: var(--tk-primary);
  color: var(--tk-on-primary);
  border-radius: var(--tk-radius-pill);
  font-size: var(--tk-fs-3xs);
  font-weight: var(--tk-weight-semi);
  text-align: center;
}
.mini-cart__importe { font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }

.mini-cart__panel {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 1000;
  width: 320px;
  max-width: calc(100vw - var(--tk-sp-8));
  padding: var(--tk-sp-3);
  background-color: var(--tk-surface-raised);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  box-shadow: var(--tk-shadow-lg);
}
.mini-cart__titulo {
  margin: 0 0 var(--tk-sp-2);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-semi);
  color: var(--tk-text-strong);
}

.mini-cart__lista { list-style: none; margin: 0; padding: 0; max-height: 260px; overflow-y: auto; }
.mini-cart__lista:empty { display: none; }

.mini-cart__item { display: flex; align-items: center; gap: var(--tk-sp-2); padding-block: var(--tk-sp-2); }
.mini-cart__item + .mini-cart__item { border-top: var(--tk-border-width) solid var(--tk-border); }

.mini-cart__foto {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  object-fit: contain;
  background-color: var(--tk-image-pad);
  border-radius: var(--tk-radius-xs);
}
.mini-cart__info { flex: 1 1 auto; min-width: 0; }
.mini-cart__nombre {
  display: block;
  font-size: var(--tk-fs-xs);
  color: var(--tk-text-strong);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mini-cart__nombre:hover { color: var(--tk-primary-ink); }
.mini-cart__meta { display: flex; gap: var(--tk-sp-2); font-size: var(--tk-fs-3xs); color: var(--tk-text-muted); }
.mini-cart__sub { font-size: var(--tk-fs-xs); font-weight: var(--tk-weight-semi); color: var(--tk-price); }

.mini-cart__vacio { margin: var(--tk-sp-3) 0; font-size: var(--tk-fs-sm); color: var(--tk-text-muted); }

.mini-cart__pie { margin-top: var(--tk-sp-3); padding-top: var(--tk-sp-3); border-top: var(--tk-border-width) solid var(--tk-border); }
.mini-cart__total {
  display: flex;
  justify-content: space-between;
  margin-bottom: var(--tk-sp-3);
  font-size: var(--tk-fs-sm);
  color: var(--tk-text-strong);
}
.mini-cart__acciones { display: flex; gap: var(--tk-sp-2); }
.mini-cart__acciones .btn { flex: 1 1 0; font-size: var(--tk-fs-xs); }

@media (prefers-reduced-motion: reduce) {
  .qty__paso,
  .cartline__total { transition: none; }
}


/* =========================================================================
   16. PIE DE CUATRO COLUMNAS, FRANJA LEGAL Y PLEGADO EN TELEFONO
   =========================================================================
   El tema comprado traía este pie diseñado en footer.css (.footer-main,
   .footer-col, .contact-item) y NINGUNA VISTA LO RENDERIZABA: 110 líneas de
   estilo cargándose en cada página para un HTML que no existía. Acá vuelve,
   sobre tokens y con el markup que efectivamente se dibuja.

   Lo que cambia respecto del original, y por qué:

   - Sin un solo color literal. El original clavaba #2a2a2a de fondo, #a3a3a3
     de texto y #0d1452 en el subrayado del título: tres colores que el panel
     de temas no podía tocar, en el bloque más visible de todas las páginas.

   - El texto del pie sale de --tk-text-inverse mezclado, no de un gris fijo.
     Así sigue contrastando cuando el comercio cambia el fondo del pie.

   - Las viñetas eran un carácter de Font Awesome inyectado con ::before. Se
     fueron con la fuente: eran 400 KB de tipografía para dibujar flechitas.

   - El plegado en teléfono es una casilla más su etiqueta, sin JavaScript.
     La primera columna (marca, descripción y redes) NO se pliega: es la que
     identifica al comercio y tiene que verse siempre.
   ========================================================================= */

.site-footer { flex-shrink: 0; }

.footer-main {
  background-color: color-mix(in oklab, var(--tk-surface-inverse) 92%, var(--tk-text-inverse));
  color: color-mix(in oklab, var(--tk-text-inverse) 72%, transparent);
  padding-block: var(--tk-sp-12) var(--tk-sp-8);
}

.footer-col { margin-bottom: var(--tk-sp-8); }

/* ---------- Título de columna ---------- */
.footer-col__titulo {
  position: relative;
  margin: 0 0 var(--tk-sp-5);
  padding-bottom: var(--tk-sp-3);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-semi);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tk-text-inverse);
  border-bottom: var(--tk-border-width) solid color-mix(in oklab, var(--tk-text-inverse) 22%, transparent);
}
/* El acento del subrayado es el color de marca, que es de lo poco que el
   comerciante configura y lo único que tiñe el pie. */
.footer-col__titulo::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 48px;
  height: 3px;
  background-color: var(--tk-primary);
}
.footer-col__titulo label { cursor: default; color: inherit; }

.footer-col__rotulo {
  margin: var(--tk-sp-5) 0 var(--tk-sp-3);
  font-size: var(--tk-fs-2xs);
  font-weight: var(--tk-weight-semi);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--tk-text-inverse) 60%, transparent);
}

/* ---------- Columna 1: marca ---------- */
.footer-marca { display: inline-block; margin-bottom: var(--tk-sp-4); }
.footer-marca img { max-width: 180px; height: auto; }

.footer-col__texto {
  max-width: 46ch;   /* una línea de más de ~75 caracteres se lee mal */
  margin: 0;
  font-size: var(--tk-fs-sm);
  line-height: var(--tk-lh-base);
}

.footer-redes { display: flex; flex-wrap: wrap; gap: var(--tk-sp-2); margin: 0; padding: 0; list-style: none; }
.footer-redes a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 40px: el mínimo táctil. Los iconos del pie viejo eran de 24 y en teléfono
     había que apuntar. */
  width: 40px;
  height: 40px;
  border-radius: var(--tk-radius-pill);
  background-color: color-mix(in oklab, var(--tk-text-inverse) 12%, transparent);
  color: var(--tk-text-inverse);
  font-size: var(--tk-fs-md);
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.footer-redes a:hover,
.footer-redes a:focus-visible { background-color: var(--tk-primary); color: var(--tk-on-primary); }

/* ---------- Listas de enlaces ---------- */
.footer-col__lista { margin: 0; padding: 0; list-style: none; }
.footer-col__lista li { margin-bottom: var(--tk-sp-2); font-size: var(--tk-fs-sm); }
.footer-col__lista a {
  color: color-mix(in oklab, var(--tk-text-inverse) 74%, transparent);
  transition: color var(--tk-dur-fast) var(--tk-ease-out);
}
.footer-col__lista a:hover,
.footer-col__lista a:focus-visible { color: var(--tk-text-inverse); text-decoration: underline; }

/* ---------- Columna 4: contacto ---------- */
.contact-item {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: var(--tk-sp-3);
  align-items: start;
  margin-bottom: var(--tk-sp-4);
}
.contact-item__icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: var(--tk-radius-pill);
  background-color: color-mix(in oklab, var(--tk-text-inverse) 14%, transparent);
  color: var(--tk-text-inverse);
  font-size: var(--tk-fs-2xs);
}
.contact-item__texto { line-height: var(--tk-lh-base); }
.contact-item__rotulo {
  display: block;
  font-size: var(--tk-fs-3xs);
  letter-spacing: .06em;
  text-transform: uppercase;
  /* Era 52% y daba 4,05:1 contra el fondo del pie, por debajo del mínimo de
     4,5. Son los rótulos que dicen qué es cada dato de contacto -Dirección,
     Teléfono, Correo-, así que no son decorativos: si no se leen, la persona ve
     un número sin saber de qué. Al 72% dan 6,4:1 y siguen viéndose como rótulo,
     que era lo que la opacidad buscaba. */
  color: color-mix(in oklab, var(--tk-text-inverse) 72%, transparent);
}

/* =========================================================================
   FRANJA LEGAL — Resolución 424/2020, Data Fiscal de ARCA y Defensa del
   Consumidor. No es decoración: son tres requisitos para vender acá.
   ========================================================================= */

.footer-legal {
  background-color: color-mix(in oklab, var(--tk-surface-inverse) 96%, var(--tk-text-inverse));
  border-top: var(--tk-border-width) solid color-mix(in oklab, var(--tk-text-inverse) 12%, transparent);
  padding-block: var(--tk-sp-5);
  color: color-mix(in oklab, var(--tk-text-inverse) 68%, transparent);
}
.footer-legal__fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--tk-sp-4) var(--tk-sp-6);
}

/* El botón de arrepentimiento tiene que LEERSE como botón: la resolución pide
   que esté visible, no escondido entre los enlaces del pie. */
.footer-legal__arrepentimiento {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--tk-sp-2) var(--tk-sp-5);
  border: var(--tk-border-width) solid color-mix(in oklab, var(--tk-text-inverse) 45%, transparent);
  border-radius: var(--tk-radius-sm);
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-semi);
  color: var(--tk-text-inverse);
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out),
              border-color var(--tk-dur-fast) var(--tk-ease-out);
}
.footer-legal__arrepentimiento:hover,
.footer-legal__arrepentimiento:focus-visible {
  background-color: var(--tk-text-inverse);
  border-color: var(--tk-text-inverse);
  color: var(--tk-surface-inverse);
  text-decoration: none;
}

.footer-legal__ayuda {
  flex: 1 1 20ch;
  margin: 0;
  font-size: var(--tk-fs-2xs);
  line-height: var(--tk-lh-base);
}

.footer-legal__defensa {
  color: color-mix(in oklab, var(--tk-text-inverse) 80%, transparent);
  font-size: var(--tk-fs-sm);
}
.footer-legal__defensa:hover,
.footer-legal__defensa:focus-visible { color: var(--tk-text-inverse); text-decoration: underline; }
.footer-legal__nota {
  display: block;
  font-size: var(--tk-fs-3xs);
  color: color-mix(in oklab, var(--tk-text-inverse) 55%, transparent);
}

/* La imagen de Data Fiscal es la oficial de ARCA y viene sobre fondo claro:
   sin este respaldo se recorta contra el pie oscuro. */
.footer-legal__fiscal {
  display: inline-block;
  margin-left: auto;
  padding: var(--tk-sp-1);
  background-color: var(--tk-text-inverse);
  border-radius: var(--tk-radius-xs);
  line-height: 0;
}
.footer-legal__fiscal img { width: 60px; height: auto; }

/* La banda de suscripción, cuando va dentro del pie, apoya sobre el mismo
   fondo que las columnas en vez de abrir un tercer tono. */
.site-footer .home-newsletter {
  background-color: color-mix(in oklab, var(--tk-surface-inverse) 84%, var(--tk-text-inverse));
  padding-block: var(--tk-sp-10);
}
.home-newsletter__texto {
  margin: 0 0 var(--tk-sp-4);
  font-size: var(--tk-fs-sm);
  color: var(--tk-text-muted);
}

/* =========================================================================
   PLEGADO EN TELEFONO
   =========================================================================
   Las columnas 2, 3 y 4 se pliegan; la 1 queda siempre visible.

   Es una casilla escondida más su etiqueta, NO un <details>: a un <details>
   no se lo puede forzar abierto desde CSS en pantalla grande, así que en
   escritorio habría quedado dependiendo de JavaScript para mostrar los
   enlaces del pie. Con la casilla, en pantalla grande la regla de ancho
   simplemente no aplica y todo se ve, cargue o no cargue un script.
   ========================================================================= */

.footer-col__mas { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

@media (max-width: 767.98px) {
  .footer-main { padding-block: var(--tk-sp-8) var(--tk-sp-4); }
  .footer-col  { margin-bottom: var(--tk-sp-2); }

  /* El título pasa a ser el disparador: alto táctil y la flecha que indica
     que hay algo plegado debajo. */
  .footer-col:not(.footer-col--marca) .footer-col__titulo {
    margin-bottom: 0;
    padding-block: var(--tk-sp-4);
  }
  .footer-col:not(.footer-col--marca) .footer-col__titulo label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--tk-sp-3);
    min-height: 44px;
    cursor: pointer;
  }
  .footer-col:not(.footer-col--marca) .footer-col__titulo label::after {
    content: "";
    width: 9px;
    height: 9px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform var(--tk-dur-fast) var(--tk-ease-out);
  }
  .footer-col__mas:checked ~ .footer-col__titulo label::after {
    transform: rotate(225deg) translate(-2px, -2px);
  }

  .footer-col__mas:not(:checked) ~ .footer-col__lista { display: none; }
  .footer-col__mas:checked        ~ .footer-col__lista { padding-block: var(--tk-sp-3) var(--tk-sp-5); }

  /* El foco del teclado cae en la casilla, que está escondida: el anillo se
     dibuja sobre el título, que es lo que se ve. */
  .footer-col__mas:focus-visible ~ .footer-col__titulo {
    outline: var(--tk-focus-width) solid var(--tk-focus-ring);
    outline-offset: 2px;
  }

  .footer-legal__fila { flex-direction: column; align-items: flex-start; }
  .footer-legal__fiscal { margin-left: 0; }
  .footer-legal__arrepentimiento { width: 100%; justify-content: center; }
}

/* --- Encabezado de listados ------------------------------------------------
   El titulo de la categoria estaba AL FINAL de la pagina, despues de la grilla y
   de la paginacion, y ademas era un subtitulo. Para un buscador la pagina no tenia
   titulo principal, y quien la escucha con un lector de pantalla oia el nombre de
   la categoria DESPUES de todos los productos. */
.page-encabezado { margin-bottom: var(--tk-sp-5); }
.page-encabezado__titulo {
  font-size: var(--tk-fs-2xl);
  font-weight: var(--tk-weight-bold);
  letter-spacing: var(--tk-tracking-heading);
  color: var(--tk-text-strong);
  margin: 0 0 var(--tk-sp-1);
}
.page-encabezado__titulo em { font-style: normal; color: var(--tk-primary-ink); }
.page-encabezado__conteo { font-size: var(--tk-fs-sm); color: var(--tk-text-muted); margin: 0; }

@media (max-width: 767.98px) {
  .page-encabezado__titulo { font-size: var(--tk-fs-xl); }
}

/* =========================================================================
   PIPELINE DE IMÁGENES
   Estilos del componente `app/views/components/img.php`.

   El componente ya emite `width` y `height` en cada etiqueta, que es lo que
   evita que el diseño salte: el navegador conoce la proporción antes de tener
   un byte de la foto y reserva el hueco. Lo que falta acá es la contracara en
   CSS, y es una sola regla no obvia.

   Si una hoja de estilos escribe `width: 100%` sin decir nada del alto, el
   navegador DESCARTA los atributos y vuelve a no saber cuánto mide la imagen:
   el hueco reservado se pierde y el salto vuelve. Por eso todo ancho fluido va
   acompañado de `height: auto`, que es lo que le dice "mantené la proporción
   que te declaré". No es decorativo, es la mitad del arreglo.
   ========================================================================= */

/* Las imágenes del pipeline son fluidas y conservan su proporción declarada. */
.tk-img,
.pcard__media img,
.gallery__main img,
.gallery__thumb img {
  max-width: 100%;
  height: auto;
}

/* Hueco para cuando el producto no tiene foto cargada.
   Ocupa exactamente lo mismo que ocuparía la imagen, así una grilla con
   productos sin foto no se desalinea. */
.tk-img--empty {
  display: block;
  width: 100%;
  aspect-ratio: var(--tk-product-aspect);
  background-color: var(--tk-image-pad);
  border-radius: var(--tk-radius-md);
}

/* Mientras la imagen diferida no llegó, el navegador dibuja el hueco vacío.
   Un fondo tenue evita el parpadeo de blanco a foto. Se apaga solo cuando la
   imagen pinta encima. */
.pcard__media,
.gallery__main {
  background-color: var(--tk-image-pad);
}

/* Aparición suave de las imágenes diferidas. Sin esto, al desplazarse rápido
   las fotos entran de golpe y la grilla parpadea.
   `content-visibility` no se usa a propósito: se lleva mal con `aspect-ratio`
   en algunos navegadores y reintroduce el salto que veníamos de arreglar. */
@media (prefers-reduced-motion: no-preference) {
  .pcard__media img[loading="lazy"] {
    animation: tk-img-in var(--tk-dur-base) var(--tk-ease-out) both;
  }
}

@keyframes tk-img-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* La guía de talles es una tira de 1200x6380 dentro de una ventana modal.
   Declarada la proporción, el modal no se redimensiona a los saltos mientras
   baja la imagen. */
.modal-body .tk-img,
.modal-body img {
  max-width: 100%;
  height: auto;
}

/* --- Confirmacion de compra ------------------------------------------------ */
.confirmacion__cabecera { text-align: center; margin-bottom: var(--tk-sp-8); }
.confirmacion__marca {
  width: 56px; height: 56px; margin: 0 auto var(--tk-sp-4);
  display: grid; place-items: center;
  font-size: var(--tk-fs-xl); border-radius: var(--tk-radius-pill);
  background: var(--tk-success-subtle); color: var(--tk-success);
}
.confirmacion__numero { font-size: var(--tk-fs-md); color: var(--tk-text); margin-bottom: var(--tk-sp-2); }
.confirmacion__aviso  { color: var(--tk-text-muted); font-size: var(--tk-fs-sm); }

.confirmacion__bloque, .confirmacion__instrucciones {
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  padding: var(--tk-sp-5); margin-bottom: var(--tk-sp-5);
}
/* Las instrucciones son el paso siguiente: se destacan sobre el resto. */
.confirmacion__instrucciones { background: var(--tk-primary-subtle); border-color: var(--tk-primary-border); }
.confirmacion__subtitulo { font-size: var(--tk-fs-md); font-weight: var(--tk-weight-semi);
                           color: var(--tk-text-strong); margin-bottom: var(--tk-sp-3); }
.confirmacion__texto { color: var(--tk-text); margin: 0; }

.confirmacion__lineas { list-style: none; margin: 0 0 var(--tk-sp-4); padding: 0; }
.confirmacion__linea  { display: flex; justify-content: space-between; gap: var(--tk-sp-3);
                        padding: var(--tk-sp-2) 0; }
.confirmacion__linea + .confirmacion__linea { border-top: var(--tk-border-width) solid var(--tk-border); }
.confirmacion__variante { display: block; font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }
.confirmacion__cantidad { color: var(--tk-text-muted); }
.confirmacion__importe  { font-weight: var(--tk-weight-semi); white-space: nowrap; }

.confirmacion__totales { margin: 0; border-top: var(--tk-border-width) solid var(--tk-border);
                         padding-top: var(--tk-sp-3); }
.confirmacion__totales > div { display: flex; justify-content: space-between; padding: var(--tk-sp-1) 0; }
.confirmacion__totales dt, .confirmacion__totales dd { margin: 0; }
.confirmacion__total { font-size: var(--tk-fs-md); font-weight: var(--tk-weight-bold);
                       color: var(--tk-price); border-top: var(--tk-border-width) solid var(--tk-border);
                       margin-top: var(--tk-sp-2); padding-top: var(--tk-sp-3) !important; }

.confirmacion__acciones { display: flex; flex-wrap: wrap; gap: var(--tk-sp-3); justify-content: center; }

/* --- Páginas de error ------------------------------------------------------ */
/* La 404 y la 500 tenían los estilos escritos en el atributo `style` de cada
   elemento, con tres colores fijos. Es la peor pantalla para eso: es la única
   que el visitante ve cuando todo lo demás falló. */
.page-error { padding-block: var(--tk-sp-16); text-align: center; }
.page-error__codigo {
  font-family: var(--tk-font-mono); font-size: var(--tk-fs-4xl);
  font-weight: var(--tk-weight-bold); color: var(--tk-text-muted);
  margin: 0 0 var(--tk-sp-2); line-height: 1;
}
.page-error__titulo {
  font-size: var(--tk-fs-xl); color: var(--tk-text-strong);
  margin: 0 auto var(--tk-sp-3); max-width: 40ch;
}
.page-error__texto { color: var(--tk-text-muted); margin: 0 auto var(--tk-sp-6); max-width: 48ch; }
.page-error__detalle {
  text-align: left; white-space: pre-wrap; word-break: break-word;
  background: var(--tk-surface-sunken); color: var(--tk-text);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  padding: var(--tk-sp-4); margin: 0 0 var(--tk-sp-6);
  font-family: var(--tk-font-mono); font-size: var(--tk-fs-xs);
  overflow-x: auto;
}
.page-error__acciones { display: flex; flex-wrap: wrap; gap: var(--tk-sp-3); justify-content: center; }

/* --- Ficha de producto ----------------------------------------------------- */
/* El hueco blanco que rompía esta pantalla venía de una columna de galería con
   altura fija y una imagen que no la llenaba. Acá las dos columnas las reparte
   la grilla y la galería mide lo que mide su contenido. */
.ficha__principal {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--tk-sp-8);
  align-items: start;
  margin-bottom: var(--tk-sp-12);
}
@media (max-width: 991px) {
  .ficha__principal { grid-template-columns: minmax(0, 1fr); gap: var(--tk-sp-6); }
}

.ficha__titulo {
  font-family: var(--tk-font-heading);
  font-size: var(--tk-fs-2xl);
  line-height: var(--tk-lh-tight);
  color: var(--tk-text-strong);
  margin: 0 0 var(--tk-sp-2);
}

/* El precio NUNCA lleva el color de marca: es el dato que más se lee de la
   pantalla y tiene que sobrevivir a cualquier tema que elija la tienda. */
.ficha__precio {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--tk-sp-3);
  margin: var(--tk-sp-4) 0;
}
.ficha__precio-actual {
  font-size: var(--tk-fs-2xl); font-weight: var(--tk-weight-bold);
  color: var(--tk-price); line-height: 1;
}
.ficha__precio-antes { color: var(--tk-price-old); font-size: var(--tk-fs-md); }
.ficha__rebaja {
  background: var(--tk-sale-subtle);
  /* El color de oferta a secas sobre el fondo tenue daba 3,27:1 en modo oscuro.
     El que se deriva CONTRA ESE FONDO siempre llega al mínimo. */
  color: var(--tk-on-sale-subtle, var(--tk-sale));
  font-size: var(--tk-fs-xs); font-weight: var(--tk-weight-semi);
  padding: var(--tk-sp-1) var(--tk-sp-2); border-radius: var(--tk-radius-sm);
}

.ficha__sku {
  font-size: var(--tk-fs-xs); color: var(--tk-text-muted);
  font-family: var(--tk-font-mono); margin: 0 0 var(--tk-sp-4);
}

.ficha__form { margin-top: var(--tk-sp-5); }

/* --- Cantidad -------------------------------------------------------------- */
.ficha__cantidad { margin: var(--tk-sp-5) 0; }
.ficha__cantidad-label {
  display: block; font-size: var(--tk-fs-sm); font-weight: var(--tk-weight-medium);
  color: var(--tk-text); margin-bottom: var(--tk-sp-2);
}

.stepper {
  display: inline-flex; align-items: stretch;
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md); overflow: hidden;
  background: var(--tk-surface);
}
/* 44 píxeles de lado: es el mínimo que un dedo acierta sin apuntar. Los botones
   anteriores medían 28 y en teléfono había que intentarlo dos veces. */
.stepper__btn {
  min-width: 44px; min-height: 44px;
  border: 0; background: transparent; cursor: pointer;
  font-size: var(--tk-fs-lg); line-height: 1; color: var(--tk-text);
}
.stepper__btn:hover:not(:disabled) { background: var(--tk-surface-sunken); }
.stepper__btn:disabled { color: var(--tk-text-disabled); cursor: not-allowed; }
.stepper__campo {
  width: 4ch; min-height: 44px; text-align: center;
  border: 0; border-inline: var(--tk-border-width) solid var(--tk-border);
  background: transparent; color: var(--tk-text);
  font-size: var(--tk-fs-base); font-weight: var(--tk-weight-medium);
  -moz-appearance: textfield;
}
.stepper__campo::-webkit-outer-spin-button,
.stepper__campo::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper__campo:disabled { color: var(--tk-text-disabled); }

/* El nivel de stock nunca se comunica sólo con color: cambia también el texto. */
.ficha__stock { margin: var(--tk-sp-2) 0 0; font-size: var(--tk-fs-sm); }
.ficha__stock[data-nivel="ok"]   { color: var(--tk-stock-ok); }
.ficha__stock[data-nivel="bajo"] { color: var(--tk-stock-low); font-weight: var(--tk-weight-semi); }
.ficha__stock[data-nivel="cero"] { color: var(--tk-stock-out); }

/* --- Acciones -------------------------------------------------------------- */
/* Agregar al carrito es la acción principal y va sólida; comprar ahora es la
   alternativa y va delineada. Antes era al revés sin querer: agregar salía gris
   y parecía deshabilitado mientras comprar se llevaba toda la atención. */
.ficha__acciones { display: flex; flex-wrap: wrap; gap: var(--tk-sp-3); margin-top: var(--tk-sp-5); }
.ficha__agregar, .ficha__comprar { flex: 1 1 12rem; min-height: 48px; }

.ficha__aviso { margin: var(--tk-sp-3) 0 0; font-size: var(--tk-fs-sm); color: var(--tk-text); min-height: 1.25em; }
.ficha__aviso:empty { margin: 0; min-height: 0; }

.ficha__compartir { margin-top: var(--tk-sp-4); display: flex; align-items: center; gap: var(--tk-sp-3); }
.ficha__compartir-aviso { font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }

/* --- Secciones desplegables ------------------------------------------------ */
.ficha__secciones {
  display: grid; gap: var(--tk-sp-5);
  margin-bottom: var(--tk-sp-12);
}
@media (min-width: 768px) { .ficha__secciones { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.desplegable {
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  padding: var(--tk-sp-5);
}
.desplegable__titulo {
  font-size: var(--tk-fs-md); font-weight: var(--tk-weight-semi);
  color: var(--tk-text-strong); margin: 0 0 var(--tk-sp-3);
}
/* El degradado del final avisa que hay más texto. El valor tiene que coincidir
   con el LIMITE del script, que es el que decide si el botón hace falta. */
.desplegable__contenido {
  max-height: 140px; overflow: hidden; position: relative;
  color: var(--tk-text); font-size: var(--tk-fs-sm); line-height: var(--tk-lh-base);
}
.desplegable__contenido::after {
  content: ""; position: absolute; inset-inline: 0; bottom: 0; height: 3rem;
  background: linear-gradient(to bottom, transparent, var(--tk-surface));
  pointer-events: none;
}
.desplegable__contenido.is-abierto { max-height: none; }
.desplegable__contenido.is-abierto::after { display: none; }
.desplegable__boton { padding: 0; margin-top: var(--tk-sp-2); }

.ficha__caracteristicas { margin: 0; padding-inline-start: var(--tk-sp-5); }
.ficha__caracteristicas li { margin-bottom: var(--tk-sp-1); }

.ficha__relacionados { margin-bottom: var(--tk-sp-12); }
.ficha__relacionados > h2 { font-size: var(--tk-fs-xl); margin-bottom: var(--tk-sp-5); }

/* --- Diálogo genérico ------------------------------------------------------ */
/* Nativo, sin librería: el cierre con escape, el foco atrapado y el fondo
   oscurecido vienen de fábrica. */
.dialogo {
  border: 0; padding: 0; max-width: min(92vw, 900px); max-height: 90vh;
  border-radius: var(--tk-radius-lg); background: var(--tk-surface);
  box-shadow: var(--tk-shadow-xl); overflow: auto;
}
.dialogo::backdrop { background: var(--tk-scrim); }
.dialogo__img { display: block; width: 100%; height: auto; }
.dialogo__cerrar {
  position: sticky; top: var(--tk-sp-2); inset-inline-start: 100%;
  transform: translateX(calc(-1 * var(--tk-sp-2)));
  min-width: 44px; min-height: 44px;
  border: 0; border-radius: var(--tk-radius-pill); cursor: pointer;
  background: var(--tk-surface-raised); color: var(--tk-text);
  font-size: var(--tk-fs-lg); line-height: 1;
}

/* --- Barra inferior de teléfono -------------------------------------------- */
/* Sólo en teléfono, y con el hueco reservado abajo para que no tape el final de
   la página. Antes se superponía a los productos relacionados. */
@media (min-width: 992px) { .barra-movil { display: none; } }
/* El relleno de la ficha lo fija `--tk-barra-inferior`, mas abajo. */
.ficha__resultado { margin: var(--tk-sp-3) 0 0; font-size: var(--tk-fs-sm); }
.ficha__resultado:empty { margin: 0; }
.ficha__resultado[data-estado="ok"]    { color: var(--tk-success); }
.ficha__resultado[data-estado="error"] { color: var(--tk-danger); }
.ficha__ir-al-carrito { font-weight: var(--tk-weight-semi); text-decoration: underline; }

/* --- Objetivos táctiles ---------------------------------------------------- */
/* En teléfono todo lo que se toca mide al menos 44 píxeles de alto. Es el mínimo
   que un dedo acierta sin apuntar; por debajo se falla lo suficiente como para
   que la persona toque dos veces o toque otra cosa. En escritorio se apunta con
   el puntero y los botones pueden ser más compactos, así que la regla es sólo
   para pantallas chicas. */
@media (max-width: 991px) {
  .btn,
  .stepper__btn,
  .vaxis__guide,
  .desplegable__boton { min-height: 44px; }

  /* Los botones de sólo texto no necesitan crecer en alto: alcanza con
     agrandarles el área tocable alrededor de las letras. */
  .btn-link { padding-block: var(--tk-sp-3); }
}
.confirmacion__aviso--guardar {
  background: var(--tk-warning-subtle); border: var(--tk-border-width) solid var(--tk-warning-border);
  color: var(--tk-text); border-radius: var(--tk-radius-md);
  padding: var(--tk-sp-3) var(--tk-sp-4); display: inline-block;
}

/* --- Catálogo: panel de filtros y barra de controles ----------------------- */
.catalogo { display: grid; gap: var(--tk-sp-6); align-items: start; }
@media (min-width: 992px) { .catalogo { grid-template-columns: 260px minmax(0, 1fr); } }

/* En teléfono el panel se pliega. Antes ocupaba la primera pantalla y cuarto:
   la primera foto de producto aparecía a 1028 píxeles de arriba. */
.catalogo__filtros { border: var(--tk-border-width) solid var(--tk-border);
                     border-radius: var(--tk-radius-md); background: var(--tk-surface); }
.catalogo__filtros-abrir {
  display: flex; align-items: center; gap: var(--tk-sp-2);
  padding: var(--tk-sp-3) var(--tk-sp-4); cursor: pointer;
  font-weight: var(--tk-weight-semi); color: var(--tk-text-strong);
  min-height: 44px; list-style: none;
}
.catalogo__filtros-abrir::-webkit-details-marker { display: none; }
.catalogo__filtros-abrir::after {
  content: "▾"; margin-inline-start: auto; transition: transform var(--tk-dur-fast) var(--tk-ease-out);
}
.catalogo__filtros[open] .catalogo__filtros-abrir::after { transform: rotate(180deg); }
.catalogo__filtros-n {
  background: var(--tk-primary); color: var(--tk-on-primary);
  border-radius: var(--tk-radius-pill); font-size: var(--tk-fs-2xs);
  min-width: 20px; height: 20px; display: inline-grid; place-items: center; padding: 0 6px;
}
@media (min-width: 992px) {
  /* En escritorio hay lugar de sobra: el panel va abierto y sin el resorte. */
  .catalogo__filtros { border: 0; background: transparent; }
  .catalogo__filtros-abrir { display: none; }
  .catalogo__filtros > .filtros { display: block !important; }
}

.catalogo__barra {
  display: flex; flex-wrap: wrap; gap: var(--tk-sp-3);
  align-items: center; justify-content: space-between;
  margin-bottom: var(--tk-sp-5);
}
.catalogo__controles { display: flex; flex-wrap: wrap; gap: var(--tk-sp-4); margin-inline-start: auto; }
.catalogo__control { display: flex; align-items: center; gap: var(--tk-sp-2); }
.catalogo__control .form-label { margin: 0; white-space: nowrap; font-size: var(--tk-fs-sm);
                                 color: var(--tk-text-muted); }
.catalogo__control .form-select { width: auto; min-width: 10rem; }
@media (max-width: 575px) {
  .catalogo__controles { width: 100%; }
  .catalogo__control { flex: 1 1 100%; }
  .catalogo__control .form-select { flex: 1; min-width: 0; }
}

/* --- Avisos generales ------------------------------------------------------ */
.avisos { margin-top: var(--tk-sp-5); }
.avisos .alert { margin-bottom: var(--tk-sp-3); }
.avisos .alert:last-child { margin-bottom: 0; }

/* --- Prosa (páginas de contenido) ------------------------------------------ */
/* El contenido lo escribe quien administra la tienda desde el panel, así que
   acá no hay clases: se estilan las etiquetas que produce un editor de texto. */
.prosa { max-width: 70ch; color: var(--tk-text); line-height: var(--tk-lh-base); }
.prosa h2 {
  font-size: var(--tk-fs-lg); color: var(--tk-text-strong);
  margin: var(--tk-sp-8) 0 var(--tk-sp-3);
}
.prosa h2:first-child { margin-top: 0; }
.prosa h3 { font-size: var(--tk-fs-md); color: var(--tk-text-strong); margin: var(--tk-sp-6) 0 var(--tk-sp-2); }
.prosa p, .prosa ul, .prosa ol { margin: 0 0 var(--tk-sp-4); }
.prosa ul, .prosa ol { padding-inline-start: var(--tk-sp-6); }
.prosa li { margin-bottom: var(--tk-sp-2); }
.prosa a { text-decoration: underline; }
.prosa strong { color: var(--tk-text-strong); font-weight: var(--tk-weight-semi); }
.prosa table { width: 100%; border-collapse: collapse; margin-bottom: var(--tk-sp-4); }
.prosa th, .prosa td {
  text-align: left; padding: var(--tk-sp-2) var(--tk-sp-3);
  border-bottom: var(--tk-border-width) solid var(--tk-border);
}

/* --- Logo del pie ---------------------------------------------------------- */
/* El logo es negro sobre el fondo oscuro del pie: las caritas de colores se
   distinguen y el nombre de la tienda no. Una chapa clara detrás lo devuelve a
   su fondo de origen sin tocar el archivo ni inventarle colores. El día que la
   tienda suba una versión clara, se saca esta regla y listo. */
.footer-marca__img {
  background: var(--tk-n-0);
  border-radius: var(--tk-radius-sm);
  padding: var(--tk-sp-2);
  max-width: 180px;
  height: auto;
}

/* --- Barra fija inferior: el hueco lo reserva quien la tiene --------------- */
/* El hueco de la barra fija lo reserva el cuerpo, mas arriba, con `:has()`: asi
   la variable llega tambien al boton de volver arriba, que es hermano del pie y
   no desciende de la pagina. */

/* --- Encabezado en teléfono: lo que se toca, se puede tocar ---------------- */
/* Los enlaces del encabezado son los que más se usan de todo el sitio y eran los
   más chicos: "Ingresar" medía 57x15 y el carrito 78x20, con tipografía de 13px.
   Un dedo no acierta eso sin apuntar. El área tocable crece con relleno, así que
   la barra no se estira ni cambia de aspecto en escritorio. */
@media (max-width: 991px) {
  .header .right a,
  .header .right button,
  .mini-cart__toggle,
  .top a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-block: var(--tk-sp-2);
  }

  /* Los íconos de redes de la barra de contacto medían 26x26. */
  .top .social a,
  .footer-redes a {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
  }
}

@media (max-width: 991px) {
  /* Las fichas: las de filtro, las de los estados vacíos y las de filtro activo.
     Medían 30 píxeles de alto, y son el control con el que se navega el catálogo
     entero desde el teléfono. */
  .chip { min-height: 44px; }

  /* Enlaces de sólo ícono del encabezado: alto ya estaba, faltaba el ancho. */
  .header .right a { min-width: 44px; justify-content: center; }

  /* La miga de navegación y los enlaces de la franja legal. */
  .breadcrumb-nav__item a,
  .footer-legal a { display: inline-flex; align-items: center; min-height: 44px; }
}
.seccion__subtitulo { color: var(--tk-text-muted); margin: 0 0 var(--tk-sp-4); }

/* --- Enlace de salto al contenido ----------------------------------------- */
/* Fuera de la pantalla hasta que recibe el foco. No se esconde con `display:none`
   ni con `visibility:hidden`: eso lo sacaría también del orden de tabulación y el
   enlace no serviría para nada. */
.saltar-al-contenido {
  position: absolute;
  left: var(--tk-sp-3);
  top: var(--tk-sp-3);
  z-index: 2000;
  transform: translateY(-200%);
  padding: var(--tk-sp-3) var(--tk-sp-5);
  background: var(--tk-primary);
  color: var(--tk-on-primary);
  border-radius: var(--tk-radius-md);
  box-shadow: var(--tk-shadow-lg);
  text-decoration: none;
  font-weight: var(--tk-weight-semi);
  transition: transform var(--tk-dur-fast) var(--tk-ease-out);
}
.saltar-al-contenido:focus { transform: translateY(0); }

/* --- Errores de validación en el ingreso ---------------------------------- */
/* Estaban escritos en el atributo `style` de cada uno, con el rojo `#c0392b`
   clavado: no era el rojo de error del sistema, así que en una tienda con otra
   paleta quedaban fuera de tono. */
.campo-error {
  margin: var(--tk-sp-1) 0 0;
  color: var(--tk-danger);
  font-size: var(--tk-fs-xs);
}
.campo-error[hidden] { display: none; }

/* El azul de Facebook es SU color de marca, no del tema: cambiarlo haría que el
   botón deje de reconocerse. Por eso es el único color de este archivo que no
   sale de una variable, y está acá para que se vea que es a propósito. */
.marca-facebook { color: #1877f2; font-size: 18px; }

/* =========================================================================
   CHECKOUT, lo que le faltaba
   =========================================================================
   La vista se reescribió entera y la hoja de estilos no la acompañó: veintitrés
   de sus clases no existían en ningún lado. Eso se veía. El resumen "Tu pedido"
   salía como una lista con viñeta, con la miniatura pegada al nombre y
   "Talle: 10 Años 1 × $29.000 $29.000" amontonado en un renglón. El campo del
   cupón y su botón se apilaban en vez de ir uno al lado del otro. Los errores de
   cada campo salían en texto negro común, sin nada que los marcara como error.
   Y el botón "Recalcular envío" quedaba pegado a los radios, como si fuera una
   cuarta forma de entrega. */

.checkout-grid {
  display: grid;
  gap: var(--tk-sp-6);
  align-items: start;
}
@media (min-width: 992px) {
  .checkout-grid { grid-template-columns: minmax(0, 1fr) 360px; }
}

.checkout-main { min-width: 0; }
.checkout-aside { min-width: 0; }

.checkout-card { margin-bottom: var(--tk-sp-5); }
.checkout-aviso { margin: 0 0 var(--tk-sp-2); }
.checkout-aviso:last-child { margin-bottom: 0; }

/* --- Resumen del pedido ---------------------------------------------------- */
.checkout-lineas { list-style: none; margin: 0 0 var(--tk-sp-4); padding: 0; }

.checkout-linea {
  display: flex; align-items: center; gap: var(--tk-sp-3);
  padding-block: var(--tk-sp-3);
}
.checkout-linea + .checkout-linea { border-top: var(--tk-border-width) solid var(--tk-border); }

.checkout-linea__foto {
  flex: 0 0 48px; width: 48px; height: 48px;
  object-fit: contain; background-color: var(--tk-image-pad);
  border-radius: var(--tk-radius-xs);
}
.checkout-linea__cuerpo { flex: 1 1 auto; min-width: 0; }
.checkout-linea__nombre {
  display: block; font-size: var(--tk-fs-sm); color: var(--tk-text-strong);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.checkout-linea__variante,
.checkout-linea__cantidad {
  display: block; font-size: var(--tk-fs-xs); color: var(--tk-text-muted);
}
.checkout-linea__total {
  font-size: var(--tk-fs-sm); font-weight: var(--tk-weight-semi);
  color: var(--tk-text-strong); white-space: nowrap;
}

/* --- Cupón ----------------------------------------------------------------- */
.checkout-cupon {
  padding-block: var(--tk-sp-4);
  border-top: var(--tk-border-width) solid var(--tk-border);
  border-bottom: var(--tk-border-width) solid var(--tk-border);
  margin-bottom: var(--tk-sp-4);
}
/* El campo y el botón van en la misma línea: es un solo gesto. */
.checkout-cupon__fila { display: flex; gap: var(--tk-sp-2); }
.checkout-cupon__fila .form-control { flex: 1 1 auto; min-width: 0; }
.checkout-cupon__quitar {
  margin-top: var(--tk-sp-2); padding: 0;
  background: none; border: 0; cursor: pointer;
  color: var(--tk-text-muted); font-size: var(--tk-fs-xs);
  text-decoration: underline;
}
.checkout-cupon__mensaje { margin: var(--tk-sp-2) 0 0; font-size: var(--tk-fs-xs); color: var(--tk-success); }
.checkout-cupon__mensaje.is-error { color: var(--tk-danger); }
.checkout-cupon__mensaje:empty { margin: 0; }
.checkout-cupon__form { display: none; }   /* sólo existe para agrupar los controles */

/* --- Entrega --------------------------------------------------------------- */
.radio-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.radio-hint { font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }
.radio-option--off { opacity: .55; cursor: not-allowed; }

/* Separado de los radios: pegado parecía una cuarta forma de entrega. */
.btn-recalcular { margin-top: var(--tk-sp-4); }

.checkout-direccion { margin-top: var(--tk-sp-5); }
.checkout-direccion[hidden] { display: none; }

/* --- Errores por campo ----------------------------------------------------- */
/* Salían en texto negro común: nada los distinguía del texto de ayuda. */
.field-error {
  display: block; margin-top: var(--tk-sp-1);
  color: var(--tk-danger); font-size: var(--tk-fs-xs);
}
.form-control.is-invalid,
.form-select.is-invalid { border-color: var(--tk-danger); }
.form-check.is-invalid .form-check-label { color: var(--tk-danger); }

/* --- Resumen lateral ------------------------------------------------------- */
.summary-resta { color: var(--tk-success); }
.summary-recalculando { margin: var(--tk-sp-2) 0 0; font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }
.summary-nota { margin: var(--tk-sp-3) 0 0; font-size: var(--tk-fs-xs); color: var(--tk-text-muted); text-align: center; }
.summary-volver { display: block; margin-top: var(--tk-sp-3); text-align: center; font-size: var(--tk-fs-sm); }
.btn-confirmar { width: 100%; min-height: 48px; margin-top: var(--tk-sp-4); }
.btn-confirmar[data-trabajando] { opacity: .7; cursor: progress; }

/* La leyenda de la forma de entrega salía mucho más grande que las demás
   etiquetas, como si fuera un título de sección. */
.checkout-page legend.form-label {
  font-size: var(--tk-fs-sm);
  font-weight: var(--tk-weight-medium);
  color: var(--tk-text);
  margin-bottom: var(--tk-sp-2);
}
/* Las ayudas de campo se pegaban a la etiqueta de abajo. */
.checkout-page .form-hint { display: block; margin-top: var(--tk-sp-1); margin-bottom: var(--tk-sp-3); }

@media (max-width: 991px) {
  /* En teléfono el resumen deja de ser pegajoso: ocuparía media pantalla. */
  .summary-card { position: static; }
}

/* =========================================================================
   PORTADA: el carrusel, sin librería
   ========================================================================= */

/* =========================================================
   HERO / SLIDER
   ========================================================= */

.hero {
  position: relative;
  width: 100%;
  margin-bottom: var(--tk-sp-10);
}

.hero__pista {
  display: flex;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}

.hero__pista::-webkit-scrollbar { display: none; }

/* Cada slide */
.hero__lamina {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  scroll-snap-align: start;
  
  /* Proporción por defecto (móviles / pantallas pequeñas) */
  aspect-ratio: 2 / 1;
  overflow: hidden;
  background: #eee;
}

/* Ajuste para pantallas de computadora (escritorio) */
@media (min-width: 1024px) {
  .hero__lamina {
    /* Proporción más panorámica y fina para PC */
    aspect-ratio: 3.5 / 1;
    
    /* Límite máximo de altura para monitores muy anchos */
    max-height: 380px; 
  }
}

/* =========================================================
   IMAGEN
   ========================================================= */

/* =========================================================
   IMAGEN
   ========================================================= */

.hero__lamina picture {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.hero__foto {
  display: block;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  
  /* Cambiado de 'cover' a 'contain' para mostrar la imagen completa */
  object-fit: contain;
  object-position: center center;
  z-index: 1;
}

/* =========================================================
   TEXTO SOBRE LA IMAGEN
   ========================================================= */

.hero__texto {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--tk-sp-3);
  width: 100%;
  max-width: none;
  margin: 0;
  padding: var(--tk-sp-8) var(--tk-sp-6);
  box-sizing: border-box;
  background: linear-gradient(
    to right,
    rgba(0, 0, 0, 0.65),
    rgba(0, 0, 0, 0.15),
    rgba(0, 0, 0, 0)
  );
  color: #fff;
}

/* =========================================================
   ALINEACIÓN DEL TEXTO
   ========================================================= */

.hero__texto--left { align-items: flex-start; text-align: left; }
.hero__texto--center { align-items: center; text-align: center; }
.hero__texto--right { align-items: flex-end; text-align: right; }

/* =========================================================
   TEXTOS
   ========================================================= */

.hero__titular { margin: 0; }
.hero__bajada { margin: 0; }

/* =========================================================
   BOTÓN
   ========================================================= */

.hero__cta {
  position: relative;
  z-index: 3;
  pointer-events: auto;
}

/* =========================================================
   MOBILE
   ========================================================= */

@media (max-width: 767px) {
  .hero__lamina { aspect-ratio: 2 / 1; }
  .hero__texto { padding: var(--tk-sp-4); gap: var(--tk-sp-2); }
}

.hero__puntos {
  position: absolute; left: 0; right: 0; bottom: var(--tk-sp-4);
  display: flex; justify-content: center; gap: var(--tk-sp-2);
  margin: 0; padding: 0; list-style: none;
}
.hero__punto { display: grid; place-items: center; width: 44px; height: 44px; }
.hero__punto::before {
  content: ""; width: 10px; height: 10px;
  border-radius: var(--tk-radius-pill);
  background: rgb(255 255 255 / .55);
  box-shadow: 0 0 0 1px rgb(0 0 0 / .25);
  transition: background-color var(--tk-dur-fast) var(--tk-ease-out);
}
.hero__punto:hover::before,
.hero__punto:focus-visible::before { background: #FFFFFF; }

@media (prefers-reduced-motion: reduce) {
  .hero__pista { scroll-behavior: auto; }
}

/* --- Cuenta del cliente ---------------------------------------------------- */
.cuenta { display: grid; gap: var(--tk-sp-6); max-width: 680px; }

.cuenta__ficha {
  display: grid; justify-items: center; gap: var(--tk-sp-2);
  padding: var(--tk-sp-6);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
}
.cuenta__inicial {
  width: 64px; height: 64px; margin: 0;
  display: grid; place-items: center;
  border-radius: var(--tk-radius-pill);
  background: var(--tk-primary-subtle); color: var(--tk-primary-ink);
  font-size: var(--tk-fs-xl); font-weight: var(--tk-weight-bold);
}
.cuenta__nombre { margin: 0; font-size: var(--tk-fs-md); font-weight: var(--tk-weight-semi); color: var(--tk-text-strong); }
.cuenta__correo { margin: 0; font-size: var(--tk-fs-sm); color: var(--tk-text-muted); }

.cuenta__accesos { display: grid; gap: var(--tk-sp-3); }
@media (min-width: 576px) { .cuenta__accesos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.cuenta__acceso {
  display: grid; gap: var(--tk-sp-1);
  padding: var(--tk-sp-4);
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  text-decoration: none; min-height: 44px;
}
.cuenta__acceso:hover { border-color: var(--tk-primary); background: var(--tk-primary-subtle); }
.cuenta__acceso-titulo { font-weight: var(--tk-weight-semi); color: var(--tk-text-strong); }
.cuenta__acceso-texto { font-size: var(--tk-fs-sm); color: var(--tk-text-muted); }
.cuenta__salir { margin: 0; }

/* --- Lista de pedidos ------------------------------------------------------ */
.pedidos { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--tk-sp-4); max-width: 680px; }
.pedido {
  border: var(--tk-border-width) solid var(--tk-border);
  border-radius: var(--tk-radius-md);
  padding: var(--tk-sp-4);
}
.pedido__cabecera { display: flex; flex-wrap: wrap; gap: var(--tk-sp-3); align-items: center; justify-content: space-between; }
.pedido__numero { font-family: var(--tk-font-mono); font-weight: var(--tk-weight-semi); }
.pedido__estado {
  font-size: var(--tk-fs-xs); padding: var(--tk-sp-1) var(--tk-sp-3);
  border-radius: var(--tk-radius-pill);
  background: var(--tk-surface-sunken); color: var(--tk-text-muted);
}
.pedido__estado[data-estado="delivered"] { background: var(--tk-success-subtle); color: var(--tk-success); }
.pedido__estado[data-estado="cancelled"],
.pedido__estado[data-estado="refunded"]  { background: var(--tk-danger-subtle); color: var(--tk-danger); }
.pedido__estado[data-estado="shipped"]   { background: var(--tk-info-subtle); color: var(--tk-info); }
.pedido__detalle { margin: var(--tk-sp-2) 0 0; font-size: var(--tk-fs-sm); color: var(--tk-text-muted); }
.pedido__pie { display: flex; justify-content: space-between; align-items: baseline;
               margin: var(--tk-sp-3) 0 0; }
.pedido__fecha { font-size: var(--tk-fs-xs); color: var(--tk-text-muted); }
.pedido__total { color: var(--tk-price); font-size: var(--tk-fs-md); }

/* --- El estilo del encabezado, que el comerciante elige --------------------- */
/* Eran dos botones del panel desconectados de todo: elegir "oscuro" o "en color
   de marca" dejaba la pantalla idéntica. El preset de ferretería pide encabezado
   oscuro, que es justamente lo que haría que un corralón no se vea igual que una
   tienda de ropa. */
.header,
.header-container .menu-container 
  /* La fila principal (logo, acciones, buscador) lleva el fondo del estilo de
   encabezado elegido. La franja del menú (.nav) ya lo pinta arriba; el
   .menu-container que vive adentro queda transparente para no taparlo. */
.header {
  background-color: var(--tk-header-bg, var(--tk-surface));
  color: var(--tk-header-text, var(--tk-text));
  border-bottom: var(--tk-border-width) solid var(--tk-header-border, var(--tk-border));
}
.header .right a:not(.btn) { color: var(--tk-header-text, var(--tk-text)); }


/* --- La densidad, que tampoco hacía nada ----------------------------------- */
/* `--tk-density` se compilaba y ningún archivo lo leía. Ahora encoge el espaciado
   de las superficies grandes: en un catálogo de ferretería, con cientos de
   artículos, entrar una fila más en pantalla es la diferencia entre desplazarse
   dos veces o cinco. */
.page { padding-block: calc(var(--tk-sp-10) * var(--tk-density, 1)); }
.catalogo { gap: calc(var(--tk-sp-6) * var(--tk-density, 1)); }
.pcard__body { padding: calc(var(--tk-sp-4) * var(--tk-density, 1)); }
.checkout-card,
.cuenta__acceso,
.pedido { padding: calc(var(--tk-sp-4) * var(--tk-density, 1)); }
