@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,600;9..144,700&family=Work+Sans:wght@400;500;600&display=swap');

:root {
  --bg: #e9f4fa;
  --bg-alt: #eaf5fb;
  --panel: #f5fafd;
  --card: #ffffff;
  --line: #cfe6f2;
  --accent: #2f9fc4;
  --accent-soft: #5fb8d9;
  --deep: #1c5f7d;
  /* Siempre oscuro (a diferencia de --deep, que en modo noche se vuelve
     claro a propósito) — usar para fondos sólidos con texto blanco. Ver
     deriveThemeTokens() en app.js / effective_theme_tokens() en helpers.php. */
  --deep-contrast: #1c5f7d;
  --text: #12324a;
  --muted: #5f8299;
  --danger: #c94f4f;
  --on-dark: #ffffff;
  --shadow: 0 10px 30px rgba(28,95,125,0.10);
  /* Escala tipográfica: un solo tamaño para cada rol de contenido (título,
     subtítulo, párrafo) en todo el sitio, en vez de un valor distinto por
     pantalla. No aplica a botones/badges/inputs/precios — esos son UI,
     no texto editorial, y tienen su propio tamaño funcional. */
  --fs-title: 2rem;
  --fs-subtitle: 1.15rem;
  --fs-paragraph: 0.9rem;
  /* Botones: no es texto editorial (no cuenta para el límite de 3 de
     arriba), pero tampoco tiene que tener 5 tamaños sueltos — 2 alcanzan:
     el CTA principal de cada pantalla, y todo lo demás clicable. */
  --fs-button: 0.95rem;
  --fs-button-secondary: 0.85rem;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  /* Resplandor radial sutil arriba, igual que las dos maquetas (admin y
     tienda) — antes era un color plano acá, sin este brillo. */
  background:
    radial-gradient(1100px 460px at 50% -8%, rgba(95,184,217,0.20), transparent 60%),
    var(--bg);
  color: var(--text);
  font-family: 'Work Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.display { font-family: 'Fraunces', Georgia, 'Times New Roman', serif; }
a { color: inherit; }
button { font-family: inherit; cursor: pointer; }
img { display: block; max-width: 100%; }
.hidden { display: none !important; }
/* Con un modal/drawer abierto (ver open()/close() en app.js), la grilla de
   atrás no debe scrollear — el overlay ya tiene su propio scroll interno
   para el contenido del modal. overflow:hidden solo no alcanza en iOS
   Safari (reportado: en iPad se podía seguir scrolleando la página de
   fondo) — position:fixed sí bloquea el scroll táctil ahí. "top" lo pisa
   app.js con el scroll actual en negativo para que no se note el salto;
   width:100% porque position:fixed saca al body del flujo normal y sin
   esto se angostaría al ancho del contenido. */
body.scroll-locked { position: fixed; top: 0; left: 0; right: 0; width: 100%; overflow: hidden; }
button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px;
}

/* Header */
header.site-header {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; background: var(--bg-alt); border-bottom: 1px solid var(--line);
  gap: 12px; flex-wrap: wrap; box-shadow: 0 1px 4px rgba(18,50,74,0.06);
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand img { height: 72px; width: 72px; object-fit: contain; }
.brand h1 { font-size: 1.6rem; margin: 0; }
.header-actions { display: flex; align-items: center; gap: 8px; }

/* Barra de navegación secundaria */
/* Se pega justo debajo del header al hacer scroll (en vez de desaparecer)
   — el offset es la altura REAL del header (var seteada por JS, ver
   setupStickyOffsets() en app.js), no un valor fijo, porque el header
   cambia de alto según pantalla. */
.site-nav {
  display: flex; gap: 4px; overflow-x: auto; padding: 8px 16px; background: var(--card);
  border-bottom: 1px solid var(--line); scrollbar-width: none;
  position: sticky; top: var(--stick-nav-top, 0px); z-index: 29;
  box-shadow: 0 2px 6px rgba(18,50,74,0.06);
}
.site-nav::-webkit-scrollbar { display: none; }
.site-nav a {
  white-space: nowrap; font-size: 0.82rem; font-weight: 600; color: var(--muted);
  text-decoration: none; padding: 6px 12px; border-radius: 8px;
  transition: background-color .15s ease, color .15s ease;
}
.site-nav a:hover, .site-nav a.active { color: var(--deep); background: var(--bg-alt); }

.page-size-select {
  padding: 8px 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel);
  font-size: 0.85rem; color: var(--text); flex: 0 0 auto; width: auto; max-width: 150px;
}
.load-more-wrap { grid-column: 1/-1; display: flex; justify-content: center; padding: 10px 0 4px; }
.btn-ghost {
  display: flex; align-items: center; gap: 6px; font-size: var(--fs-button-secondary); padding: 6px 12px;
  border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--muted);
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn-ghost:hover { background: var(--bg-alt); border-color: var(--accent); color: var(--deep); }
.btn-cart {
  position: relative; display: flex; align-items: center; gap: 8px; padding: 8px 14px;
  border-radius: 999px; border: none; background: var(--accent); color: var(--on-dark); font-size: 0.9rem;
  transition: background-color .15s ease;
}
.btn-cart:hover { background: var(--accent-soft); }
.cart-badge {
  position: absolute; top: -6px; right: -6px; background: var(--accent); color: #fff;
  font-size: 0.7rem; border-radius: 999px; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
}

/* Hero */
.hero {
  position: relative; padding: 40px 16px 0; overflow: hidden; border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; justify-content: space-between; min-height: 760px;
  background:
    radial-gradient(ellipse 260px 120px at 12% 20%, rgba(255,255,255,0.9), rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 320px 140px at 85% 15%, rgba(255,255,255,0.85), rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 300px 130px at 70% 75%, rgba(255,255,255,0.7), rgba(255,255,255,0) 70%),
    radial-gradient(ellipse 220px 100px at 20% 85%, rgba(255,255,255,0.6), rgba(255,255,255,0) 70%),
    linear-gradient(180deg, #bfe6f7 0%, #dcf1fa 55%, #ffffff 100%);
}
@media (min-width: 768px) { .hero { min-height: 760px; } }
.hero.has-image {
  background-image: var(--hero-img-desktop); background-size: contain; background-position: center 70%;
  background-repeat: no-repeat; background-color: var(--bg-alt);
}
/* En computadora, "contain" dejaba franjas de color liso a los costados en
   monitores anchos (la foto no llega al ancho completo) — cover la estira
   para que siempre llegue al ancho, recortando arriba/abajo si hace falta
   en vez de encoger a lo ancho. Solo desktop: en mobile (ver media query
   de abajo) "contain" evita que se recorte mal una foto pensada para
   horizontal en una pantalla angosta y alta. */
@media (min-width: 768px) {
  .hero.has-image { background-size: cover; }
}
.hero.has-image::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0.2) 50%, rgba(255,255,255,0) 72%);
}
/* Si se cargó una foto vertical especial para celular, se usa esa a pantalla
   completa (sin necesitar el "contain" de resguardo) en vez de la horizontal. */
@media (max-width: 767px) {
  .hero.has-image.has-mobile-image {
    background-image: var(--hero-img-mobile); background-size: cover; background-position: center top;
  }
  .hero.has-image.has-mobile-image::before {
    background: linear-gradient(180deg, rgba(255,255,255,0.55) 0%, rgba(255,255,255,0) 140px);
  }
}
.hero-content { position: relative; max-width: 640px; }
/* El hero siempre tiene de fondo una foto/degradé de cielo CLARO, sin
   importar la paleta elegida (no es parte del sistema de colores del
   sitio) — por eso su texto usa un color de tinta fijo en vez de las
   variables del tema, que en modo noche se vuelven claras y quedarían
   invisibles sobre esa misma foto clara. */
.hero h2, .hero p.sub, .hero-contact-item { color: #16232c; }
.hero p.sub { opacity: 0.75; }
.hero-contact-item small { color: #5f7385; }
/* Desplegable de categorías: cuelga del link "Categorías" del nav
   (renderHeroCategories() en app.js lo abre/cierra y calcula top/left
   contra el link real). position:fixed (no absolute) porque .site-nav
   tiene overflow-x:auto — un hijo absolute quedaría recortado por ese
   scroll horizontal en vez de flotar libre encima de todo. */
.nav-cat-dropdown {
  display: none; position: fixed; z-index: 50;
  background: var(--card); border-radius: 14px; box-shadow: 0 8px 24px rgba(18,50,74,0.18);
  padding: 8px; min-width: 220px; max-height: 60vh; overflow-y: auto; flex-direction: column; gap: 4px;
}
.nav-cat-dropdown.open { display: flex; animation: dropdownFadeIn .12s ease; }
.nav-cat-dropdown button {
  text-align: left; background: transparent; border: none; padding: 9px 12px; border-radius: 8px;
  font-size: 0.88rem; color: var(--text); font-weight: 500; transition: background-color .15s ease;
}
.nav-cat-dropdown button:hover { background: var(--bg-alt); }
.hero h2 { font-size: var(--fs-title); line-height: 1.15; margin: 0; position: relative; }
.hero-divider { display: flex; align-items: center; gap: 10px; max-width: 220px; margin: 14px 0; color: var(--accent); font-size: 0.85rem; position: relative; }
.hero-divider span { flex: 1; height: 1px; background: rgba(28,95,125,0.3); }
.hero p.sub { margin: 0 0 20px; position: relative; font-size: var(--fs-paragraph); }
.hero-cta {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 8px; padding: 12px 26px; border-radius: 999px;
  background: var(--accent); color: #fff; font-weight: 600; font-size: var(--fs-button); letter-spacing: 0.02em;
  text-decoration: none; position: relative; box-shadow: 0 8px 20px rgba(18,50,74,0.18);
  transition: filter .15s ease, box-shadow .15s ease, transform .1s ease;
}
/* filter en vez de var(--deep): un botón sólido con texto blanco siempre
   necesita oscurecerse al hover, nunca aclararse — y --deep en modo noche
   es un color CLARO (para que sirva de tinta de títulos ahí), así que
   usarlo acá rompería el contraste del texto blanco. */
.hero-cta:hover { filter: brightness(0.85); box-shadow: 0 10px 24px rgba(18,50,74,0.25); transform: translateY(-1px); }
.hero-contact-bar {
  position: relative; z-index: 2; margin: 32px -16px 0;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px 26px;
  padding: 14px 16px; background: rgba(255,255,255,0.6); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border-top: 1px solid rgba(255,255,255,0.6);
}
.hero-contact-item {
  display: flex; align-items: center; gap: 7px; text-decoration: none;
  font-weight: 600; font-size: 0.8rem; transition: color .15s ease;
}
.hero-contact-item small { display: block; font-weight: 500; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.03em; }
.hero-contact-item:hover { color: var(--accent); }
.cloud { position: absolute; border-radius: 999px; background: #fff; filter: blur(20px); opacity: 0.7; }
.cloud-1 { top: -20px; left: -40px; width: 280px; height: 110px; animation: drift1 40s linear infinite; }
.cloud-2 { top: 40px; right: 0; width: 360px; height: 130px; animation: drift2 55s linear infinite; }
@keyframes drift1 { 0%,100% { transform: translateX(-6%);} 50% { transform: translateX(4%);} }
@keyframes drift2 { 0%,100% { transform: translateX(3%);} 50% { transform: translateX(-5%);} }
@keyframes dropdownFadeIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes overlayFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalSlideUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes drawerSlideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes toastSlideUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .cloud, .wing-icon, .overlay, .modal, .drawer-overlay, .drawer, .toast, .nav-cat-dropdown.open { animation: none !important; }
}

/* Nosotros */
.about {
  padding: 40px 16px; border-bottom: 1px solid var(--line); background: var(--panel);
}
.about-inner { max-width: 720px; margin: 0 auto; text-align: center; }
.about h3 { margin: 0 0 12px; font-size: var(--fs-subtitle); }
.about p { color: var(--muted); line-height: 1.6; white-space: pre-line; text-align: left; }
.catalog-link {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; padding: 10px 18px;
  border-radius: 999px; background: var(--accent); color: #fff; font-size: 0.9rem; text-decoration: none;
  transition: background-color .15s ease, box-shadow .15s ease;
}
.catalog-link:hover { background: var(--accent-soft); box-shadow: 0 4px 12px rgba(18,50,74,0.18); }

/* Filtros */
/* Se pega justo debajo de .site-nav al hacer scroll, completando el
   "imantado" header → nav → filtros (ver comentario en .site-nav). */
.filters {
  display: flex; flex-direction: row; align-items: center; flex-wrap: nowrap; gap: 10px;
  /* padding horizontal: NO 16px fijo — .grid de abajo (las tarjetas) tiene
     max-width:2050px centrado con margin:auto, así que en un monitor
     ancho (>2050px + este padding) el buscador quedaba pegado al borde
     de la ventana mientras las tarjetas arrancaban bien más adentro (se
     midió: ~260px de diferencia en una pantalla de 2400px). El padding
     crece con max() una vez que el viewport supera ese mismo ancho, para
     que el contenido de esta barra quede metido en la misma columna de
     2050px que el resto de la página — por debajo de eso, sigue siendo
     16px fijo, ningún cambio de comportamiento actual. El fondo/sombra
     de la barra sigue ocupando el ancho completo (no se le puso
     max-width a .filters en sí) — solo se centra el CONTENIDO. */
  padding: 16px max(16px, calc((100% - 2050px) / 2 + 16px));
  border-bottom: 1px solid var(--line);
  position: sticky; top: var(--stick-filters-top, 0px); z-index: 28; background: var(--card);
  scroll-margin-top: var(--stick-filters-top, 96px); /* deja lugar al header+nav fijos cuando se hace scroll hasta acá */
  box-shadow: 0 18px 40px rgba(18,50,74,0.26);
}
/* flex-wrap SIEMPRE nowrap (no solo mobile): con wrap, el navegador podía
   decidir mandar el buscador a su propia línea arriba del scroll de
   categorías en pantallas anchas — justo lo que se quería evitar al
   ponerlos en la misma fila. */
.search-box {
  display: flex; align-items: center; gap: 6px; padding: 6px 14px;
  border: 1px solid var(--line); border-radius: 999px; background: transparent;
  transition: border-color .15s ease;
  /* font-size acá (no solo en #search-input): el 🔎 es un nodo de texto
     suelto, hijo directo de .search-box, no del input — sin esto heredaba
     el tamaño base de la página (16px/24px de línea) en vez del tamaño
     chico de acá, quedando ~9px más alto que un .chip (mismo padding
     vertical que ellos, 6px) y con las esquinas más cuadradas (8px) en
     vez de píldora — se leía como un elemento aparte, no de la misma
     familia que las categorías al lado. Mismo font-size que .chip para
     que ambos midan exactamente igual de alto. */
  font-size: 0.82rem;
  /* line-height:1 (no el 1.5 heredado de body): .chip es un <button>, y
     los controles de formulario NO heredan line-height/font del body por
     default (estilo propio del navegador) — su alto sale del propio
     <input> (15px). El 🔎 en cambio es texto suelto, si hereda el 1.5 de
     body (19.68px de línea) su caja anónima queda más alta que el
     <input> de al lado y termina mandando el alto de .search-box entero
     (probado: con line-height:normal quedaban 31px vs 29px del chip —
     "normal" en un texto suelto no es igual de compacto que en un
     <input>). Con line-height:1 el 🔎 queda MÁS bajo que el <input>
     (15px), así que es el <input> el que manda — mismo alto final que
     .chip (29px), medido exacto. */
  line-height: 1;
  /* Minimalista: sin caja/fondo/sombra, solo el ícono y una línea — así
     ocupa menos espacio al lado de las categorías. Buscador a la
     izquierda, categorías a la derecha, en la misma fila siempre (antes
     el buscador ocupaba todo el ancho y las categorías quedaban en una
     fila propia debajo, solo en mobile). */
  flex: 0 1 150px; min-width: 132px;
}
.search-box:focus-within { border-color: var(--accent); }
@media (min-width: 768px) { .search-box { flex: 1 1 240px; min-width: 200px; max-width: 340px; } }
/* #search-input (no ".search-box input"): tiene que ganarle en
   especificidad a la regla genérica de "input[type=text]" de más abajo
   (forms de admin/login) que si no le pisa el reset acá. */
#search-input { border: none; background: transparent; outline: none; font-size: 0.82rem; width: 100%; color: var(--text); min-width: 0; appearance: none; -webkit-appearance: none; box-shadow: none; padding: 0; border-radius: 0; }
/* Sin esto, .category-scroll mostraba la scrollbar nativa del sistema
   (gruesa, gris) — pesaba varios px de alto DEBAJO de los chips, más que
   el buscador de al lado (que no scrollea), así que con align-items:center
   en .filters los chips quedaban corridos hacia arriba respecto al
   buscador: la fila se veía descentrada. Misma receta fina+color de
   página que ya usan .modal/.side (ver scrollbar-width/color ahí). */
.category-scroll {
  display: flex; gap: 8px; overflow-x: auto; padding: 4px 0; flex: 1 1 auto; min-width: 0;
  /* padding SIMÉTRICO (no solo abajo): con solo padding-bottom, los chips
     quedaban centrados en la MITAD SUPERIOR de esta caja, no en el medio
     real — y como .filters centra esta caja entera contra .search-box
     (align-items:center), esos 4px de más abajo corrían los chips ~2px
     para arriba respecto al buscador. Con el mismo margen arriba y abajo
     el centro visual de los chips coincide con el centro de la caja. */
  scrollbar-width: thin; scrollbar-color: var(--line) transparent;
}
.category-scroll::-webkit-scrollbar { height: 5px; }
.category-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
.category-scroll::-webkit-scrollbar-track { background: transparent; }
.chip {
  white-space: nowrap; font-size: 0.82rem; padding: 6px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: transparent; color: var(--muted);
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .15s ease, box-shadow .15s ease;
}
@media (hover: hover) {
  .chip:hover:not(.active):not(.variant-opt-oos) { color: var(--accent); transform: translateY(-2px); box-shadow: 0 6px 14px rgba(18,50,74,0.14); }
}
.chip.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.variant-opt-oos { opacity: 0.5; text-decoration: line-through; cursor: not-allowed; }
.variant-opt-oos:hover { border-color: var(--line); color: var(--muted); }

/* --- Selector de variante adaptativo (imagen 1 del rediseño) --------------- */
/* Pocas opciones: botones grandes. */
.variant-btn-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.variant-big {
  flex: 1 1 auto; min-width: 92px; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line); background: var(--panel);
  color: var(--text); font-size: 0.92rem; font-weight: 600;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .15s ease, box-shadow .15s ease;
}
@media (hover: hover) {
  .variant-big:hover:not(.active):not(.variant-opt-oos):not(:disabled) { color: var(--accent); transform: translateY(-2px); box-shadow: 0 6px 14px rgba(18,50,74,0.14); }
}
@media (prefers-reduced-motion: reduce) { .chip, .variant-big { transition: none; } }
.variant-big.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.variant-oos-tag {
  font-size: 0.66rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--danger); background: rgba(201, 79, 79, 0.1); border-radius: 999px; padding: 1px 7px;
}
.variant-big.variant-opt-oos { text-decoration: none; }

/* Muchas opciones: fila colapsada + lista con buscador. */
.variant-select {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px; border-radius: 12px; border: 1px solid var(--line); background: var(--panel);
  color: var(--text); font-size: 0.92rem; font-weight: 600; cursor: pointer;
  transition: border-color .15s ease;
}
.variant-select:hover, .variant-select.open { border-color: var(--accent); }
.variant-select-val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.variant-select-chevron { color: var(--muted); font-size: 0.8rem; flex-shrink: 0; }
.variant-dropdown {
  margin-top: 8px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); overflow: hidden;
}
.variant-search { border: none !important; border-bottom: 1px solid var(--line) !important; border-radius: 0 !important; background: transparent !important; }
.variant-list { max-height: 240px; overflow-y: auto; padding: 6px; display: flex; flex-direction: column; gap: 2px; }
.variant-list-item {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border-radius: 8px; border: none; background: transparent; color: var(--text);
  font-size: 0.9rem; text-align: left; cursor: pointer; transition: background-color .12s ease;
}
.variant-list-item:hover:not(.variant-opt-oos) { background: var(--bg-alt); }
.variant-list-item.active { background: var(--bg-alt); font-weight: 700; }
.variant-list-item.variant-opt-oos { text-decoration: none; }
.variant-check { color: var(--accent); font-weight: 700; }

/* Detalles del recuadro de producto que igualan la imagen 1 (solo piloto).
   El encabezado "Elegí tu variante" decorativo se reemplazó por pasos
   numerados (.velones-step/.step-num, ya definidos más abajo), igual que
   en la maqueta — no queda ningún uso de .variant-heading/.stock-dot. */
.price-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 14px 0; }
.price-cu { font-family: inherit; font-size: 1.5rem; font-weight: 800; color: var(--accent); }
.price-cu small { font-size: 0.9rem; font-weight: 600; color: var(--muted); margin-left: 4px; }
.trust-line { text-align: center; color: var(--muted); font-size: 0.8rem; margin: 10px 0 2px; }
/* Botón "+ Agregar al pedido" (armador de "Tu pedido") y su caja vacía,
   calcados de la maqueta: contorno punteado en vez de botón sólido. */
.combo-btn {
  width: 100%; padding: 11px; border-radius: 10px; border: 1px dashed var(--accent);
  background: var(--panel); color: var(--accent); font-weight: 600; font-size: 0.9rem;
  margin-top: 6px; cursor: pointer; font-family: inherit;
}
.tiers-note { font-size: 0.76rem; color: var(--muted); margin: 0 0 10px; }
.empty-order {
  font-size: 0.84rem; color: var(--muted); margin: 14px 0 2px; padding: 14px;
  border: 1px dashed var(--line); border-radius: 10px; text-align: center;
}

/* --- Sistema de "pasos" del modal de producto (selectorStyle elegido) ----
   Todo producto con selectorStyle (simple/one/search/two/custom — ver
   useRedesign en app.js) arma su modal como una cadena de bloques
   .snap-section: intro (foto ya aparte) + un .velones-step por cada grupo
   de variantes + un .velones-step final de Cantidad. Es UN solo sistema
   compartido por los 4 tipos de producto (no uno por tipo) — un producto
   nuevo que declare selectorStyle lo hereda automático, sin tocar CSS.
   Regla de espaciado (para que un futuro paso agregado sea consistente):
     - ENTRE un paso y el siguiente (ej. fin de los botones de "① Categoría"
       al texto de "② Elegí una opción"): 32px — el margin-top de acá abajo.
     - DENTRO de un paso (su etiqueta a su propio control): 6px — el
       margin-bottom de acá abajo. Tiene que ser bastante más chico que el
       de arriba: así se lee como "etiqueta pegada a su control" en vez de
       que los 3 pasos se mezclen en un solo bloque (bug real, corregido
       en esta misma sesión — medido con Playwright, con 16px arriba el
       salto entre pasos casi no se distinguía del gap interno).
   Layout de dos columnas en pantallas anchas (foto fija a la izquierda,
   pasos con scroll propio a la derecha) y los puntitos de navegación:
   ver setupSnapSections() en app.js y las reglas .wide-split más abajo. */
/* margin-top:32px (no 16px): es el espacio real entre un paso y el
   siguiente (ej. los botones "1 día 1 noche" de "① Categoría" contra la
   etiqueta "② Elegí una opción") — medido con Playwright: con 16px ese
   salto quedaba casi igual de apretado que el gap interno etiqueta→control
   (6px, el margin-bottom de acá abajo), leyéndose como un solo bloque en
   vez de 3 pasos separados. El margin-bottom sigue en 6px a propósito:
   ESE gap chico es el que agrupa visualmente la etiqueta con su control. */
.velones-step { display: flex; align-items: center; gap: 8px; margin: 32px 0 6px; font-weight: 700; color: var(--deep); font-size: var(--fs-subtitle); }
.step-num {
  display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
  border-radius: 999px; background: var(--accent); color: #fff; font-size: 0.78rem; font-weight: 700; flex-shrink: 0;
}
.velones-color-list { max-height: 220px; }
.velones-avail { font-size: 0.78rem; font-weight: 600; color: #2e9b57; }
.velones-avail::before { content: "✓ "; }
.velones-info {
  margin: 10px 0 2px; padding: 10px 12px; border-radius: 10px; font-size: 0.85rem; color: var(--deep);
  background: var(--bg-alt); border: 1px solid var(--line);
}
.velones-mayorista { font-size: 0.78rem; font-weight: 600; color: #2e9b57; }
.velones-mayorista::before { content: "✓ "; }
.velones-order { margin: 16px 0 8px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.velones-order-title { padding: 10px 12px; background: var(--bg-alt); font-weight: 700; color: var(--deep); font-size: var(--fs-subtitle); }
.velones-order-line { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--line); font-size: 0.86rem; }
.velones-order-desc { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.velones-order-qty { color: var(--muted); flex-shrink: 0; }
.velones-order-sub { font-weight: 700; color: var(--accent); flex-shrink: 0; }
.velones-order-del { background: none; border: none; cursor: pointer; opacity: 0.6; flex-shrink: 0; }
.velones-order-del:hover { opacity: 1; }
.velones-order-total { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 10px 0 2px; font-size: 1rem; color: var(--deep); }

/* Grid de productos (estilo Pinterest): antes tenía 3 breakpoints fijos
   (2/4/6 columnas) — medido que eso hacía que al hacer zoom con
   Ctrl+rueda, al cruzar justo esos anchos la tarjeta "saltaba" de tamaño
   de golpe en vez de escalar suave. Se probó con una fórmula continua
   (clamp()+vw, sin breakpoints fijos) para evitar eso — funcionaba bien
   hasta que el usuario empezó a pedir columnas EXACTAS en anchos
   puntuales (1550px→4, 1700px→5, +1700px→6): con una sola fórmula
   continua, ajustar un punto corría TODOS los demás (probado: subir el
   piso lo suficiente para forzar 4 columnas a 1550px hacía que a veces
   el conteo de columnas bajara al VOLVER a subir el ancho — no
   monótono, se sentía roto). Vuelta a breakpoints explícitos por
   ancho — control exacto en cada punto que se pida, sin efectos
   colaterales en los demás. Eso sí: CADA breakpoint sigue usando 1fr
   (no un track fijo), así que las tarjetas escalan suave DENTRO de
   cada rango de columnas — el salto solo pasa al cruzar un breakpoint,
   igual que en Pinterest. */
.grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 295px));
  justify-content: center;
  gap: 16px; padding: 24px 16px; max-width: 2050px; margin: 0 auto;
}
/* Celular (360-959px): 2 columnas garantizadas, con el mismo techo de
   295px que la zona de arriba — antes eran repeat(2,1fr) (se estiraban
   hasta 456px) y de 960px en adelante caían de golpe a 295px fijos: un
   salto de 140px en 1px de diferencia de ancho, se notaba como un
   error. Con el mismo techo acá, la transición a los 960px queda
   invisible (295px de los dos lados). Por debajo de donde 2 tarjetas
   de 295px ya no entran holgadas, minmax(0,...) las deja encoger en
   vez de desbordar. De 960px en adelante: auto-fit decide sola cuántas
   295px entran por fila (2, 3, 4… según el ancho). justify-content:
   center reparte el espacio que sobra centrando la fila en vez de
   estirar tarjetas — mismo motivo por el que antes esto se probó y se
   volvió atrás (Pinterest estira), pero ahora es lo que se pidió a
   propósito. Bajado 316px→300px→295px: en Windows con barra de scroll
   clásica (no "overlay"), el ancho real de layout (document
   .documentElement.clientWidth, lo que usan las media queries) es
   MENOR que el ancho de la ventana — la barra se come ~15-17px que
   antes no se estaban descontando (el contador de píxeles mismo tenía
   este error, ver fix en index.html: mostraba window.innerWidth, que
   SÍ incluye la barra). Con 295px, 6 columnas necesitan 1902px
   (6×295 + 5×16 + 32) — entra con margen incluso si la barra se lleva
   hasta ~18px de una ventana de 1920px. */
@media (min-width: 960px) {
  .grid { grid-template-columns: repeat(auto-fit, 295px); justify-content: center; }
}
.card {
  text-align: left; border-radius: 14px; overflow: hidden; border: 1px solid var(--line);
  background: var(--panel); transition: transform .2s ease, box-shadow .2s ease; position: relative;
}
@media (hover: hover) {
  .card:hover { transform: translateY(-5px); box-shadow: 0 18px 42px rgba(0,0,0,0.16); }
}
@media (prefers-reduced-motion: reduce) { .card { transition: none; } }
/* Margen chico alrededor de la foto + esquinas redondeadas solo arriba
   (abajo sigue derecho porque ahí empieza el texto de la tarjeta) — es
   estructural, así que le queda igual a cualquier foto, la que ya está
   cargada y la que se cargue después, sin tocar nada por producto. Radio
   de 6px = radio de la card (14px) menos el margen+borde hasta la foto
   (8px + 1px), así el redondeo interno queda concéntrico con el externo
   en vez de verse desproporcionado. */
.card .thumb {
  width: calc(100% - 16px); margin: 8px 8px 0; aspect-ratio: 1/1; border-radius: 6px 6px 0 0;
  background: var(--bg-alt); display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.card .thumb img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
.card .body { padding: 10px 12px; }
.card .cat { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); margin-bottom: 4px; }
.card h3 { margin: 0; font-size: var(--fs-subtitle); line-height: 1.3; }
.card .price { margin-top: 4px; font-size: 0.85rem; color: var(--muted); }
.card .price .old { text-decoration: line-through; margin-right: 6px; opacity: 0.7; }
.badge {
  position: absolute; top: 8px; left: 8px; font-size: 0.65rem; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; color: #fff; letter-spacing: 0.04em;
  box-shadow: 0 2px 6px rgba(18,50,74,0.15);
}
.badge.new { background: var(--accent); }
.badge.offer { background: var(--danger); }
.badge + .badge { top: 32px; }

/* Overlays / modales */
.overlay {
  position: fixed; inset: 0; z-index: 40; background: rgba(10,20,30,0.55);
  display: flex; align-items: center; justify-content: center; padding: 12px; overflow-y: auto;
  animation: overlayFadeIn .15s ease;
}
/* El modal de producto necesita más aire vertical que el resto (foto +
   texto + selector + cantidad, todo en un scroll segmentado) — menos
   padding/margen alrededor y más alto máximo, solo para este modal. */
#modal-product { padding: 6px; }
/* max-width angosto (no 520px como el resto de los modales) para que el
   modal se ajuste al tamaño de la foto en vez de quedar una card ancha con
   la foto chica flotando en el medio — 280px de foto + 22px de padding a
   cada lado = 324px. Si el ancho de la foto cambia (#product-detail-content
   .thumb más abajo), este número hay que actualizarlo junto con ese. */
/* max-height en vh Y dvh (esta última pisa a la primera donde el
   navegador la entiende, si no la ignora y queda la de vh) — en celular,
   vh se calcula contra la pantalla completa SIN contar la barra de
   direcciones, así que con la barra visible (la mayoría del tiempo) el
   modal terminaba ocupando más del % pensado, a veces pegado al borde de
   lo que realmente se ve. dvh sí tiene en cuenta la barra. */
#modal-product .modal { margin: 8px 0; max-height: 96vh; max-height: 96dvh; max-width: 324px; }
.modal {
  width: 100%; max-width: 520px; margin: 24px 0; border-radius: 16px; background: var(--card);
  border: 1px solid var(--line); position: relative; max-height: 90vh; max-height: 90dvh; overflow-y: auto;
  animation: modalSlideUp .2s ease; transition: transform .2s ease, box-shadow .2s ease;
  scrollbar-width: thin; scrollbar-color: var(--line) transparent;
}
@media (hover: hover) {
  .modal:hover { transform: translateY(-5px); box-shadow: 0 18px 42px rgba(0,0,0,0.16); }
}
@media (prefers-reduced-motion: reduce) { .modal { transition: none; } }
/* Título de lo que se abre en un modal/drawer (producto, checkout, "Tu
   carrito"): es el encabezado de una superficie compacta y secundaria a la
   página, no el título de una pantalla completa — mismo tamaño que las
   demás cabeceras secundarias (.sec-title, .card h3, etc). */
.modal .content h3.display, .drawer-header h3.display { font-size: var(--fs-subtitle); }
.modal::-webkit-scrollbar { width: 6px; }
.modal::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
/* .close-btn-wrap: mismo problema y misma solución que ya se probó con
   los puntitos del selector de 2 niveles — position:absolute dentro de
   .modal (que scrollea) NO queda fijo, se va con el contenido (medido:
   llegaba a -436px, invisible, al scrollear hasta el final). sticky +
   height:0 lo deja pegado arriba de verdad sin ocupar espacio en el flujo. */
.modal .close-btn-wrap { position: sticky; top: 0; height: 0; overflow: visible; z-index: 3; }
.modal .close-btn {
  position: absolute; top: 12px; right: 12px; z-index: 2; width: 30px; height: 30px; border-radius: 999px;
  border: none; background: rgba(255,255,255,0.92); color: var(--muted); font-size: 0.95rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 1px 5px rgba(18,50,74,0.18);
  transition: background-color .15s ease, color .15s ease, transform .15s ease, box-shadow .15s ease;
}
@media (hover: hover) {
  .modal .close-btn:hover { background: var(--bg-alt); color: var(--text); transform: translateY(-2px); box-shadow: 0 6px 14px rgba(18,50,74,0.18); }
}
@media (prefers-reduced-motion: reduce) { .modal .close-btn { transition: none; } }
.modal .content { padding: 22px; }

/* Modal de producto: la foto queda flotante (sticky) al hacer scroll dentro
   del modal, igual que el header con la página — así el cliente sigue
   viendo la foto mientras elige variantes/cantidad más abajo, en vez de que
   se pierda de la vista. Acotado a #product-detail-content (el modal de
   producto) para no afectar los .thumb de las cards de la grilla.
   top:22px (no 0) para que, ya "pegada" arriba, mantenga el mismo margen
   que tenía con el padding del modal en vez de tocar el borde. Empieza
   plana (sin sombra) y recién se "levanta" con sombra al scrollear — la
   clase .lifted la pone/saca app.js según el scroll del modal. */
#product-detail-content .thumb {
  position: sticky; top: 22px; z-index: 1; /* menos que .close-btn (z-index:2), para no taparlo */
  overflow: hidden; /* el border-radius del contenedor no recorta la imagen sin esto */
  transition: transform .2s ease, box-shadow .2s ease;
}
/* 100% del ancho de su contenedor (el modal, ahora angosto — ver
   max-width en #modal-product .modal más arriba, calibrado junto con
   este ancho de foto). El modo comprimido (.thumb-left, columna a la
   izquierda) pisa este width a mano por JS según el espacio disponible. */
#product-detail-content .thumb.lifted {
  transform: translateY(-4px);
  /* Un poco más marcada que antes (0 8px 16px 0.24) — para referencia, la
     sombra del hover de las cards de la grilla es 0 18px 42px 0.16, pero
     acá el margen hasta el texto de abajo es chico, así que se sube
     opacidad/blur con cuidado en vez de copiar esos valores tal cual
     (se repetiría el problema de taparle texto a lo que sigue). */
  box-shadow: 0 10px 22px rgba(18,50,74,0.32);
}
#product-detail-content .thumb img { width: 100%; height: 100%; object-fit: cover; object-position: center; }

/* Modo comprimido: cuando la ventana queda tan baja (zoom alto, notebook
   con poca altura) que la foto a ancho completo no entra dejando lugar al
   contenido, en vez de aplastarla contra el ancho (dejaría de verse
   cuadrada) se pasa a una columna angosta a la izquierda — conserva el
   mismo aspect-ratio 1/1 (cuadrada), solo más chica, y el contenido pasa
   a un costado en vez de abajo. app.js decide cuándo activar esto
   (setupSnapSections) y calcula el ancho de la foto a mano. */
#product-detail-content.thumb-left {
  display: flex; align-items: flex-start; gap: 14px;
}
#product-detail-content.thumb-left .thumb {
  flex-shrink: 0; margin-bottom: 0 !important;
}
#product-detail-content.thumb-left .detail-body {
  flex: 1 1 auto; min-width: 0;
}

/* Panel dividido: con ancho de sobra (ver WIDE_SPLIT_BREAKPOINT en
   setupSnapSections), la foto pasa a ser una columna FIJA a la izquierda a
   todo el alto (deja de estar sticky arriba, deja de scrollear con el
   resto) y el contenido con su scroll-snap propio pasa a la derecha —
   mismo mecanismo de puntitos/secciones/sombra de siempre, solo que ahora
   el que scrollea es .detail-body en vez de .modal entera. Selector
   compuesto con .snap-sections (no solo .wide-split) a propósito: mismo
   nivel de especificidad que las reglas de .snap-sections de más abajo, así
   esto les gana sin depender del orden en el archivo. */
#modal-product .modal.snap-sections.wide-split {
  /* min(1200px, 90vw) en vez de un número fijo: así crece PROPORCIONAL a
     la pantalla (en un monitor grande llega más lejos que en uno chico)
     en vez de quedar pegado siempre al mismo tope — 1200px es el techo
     para que no se vuelva gigante en monitores enormes. Alto y ancho
     siguen 1:1 solos (columna=cuadrado, ver .thumb/.detail-body más abajo),
     así que agrandar el ancho agranda el alto en la misma proporción. */
  max-width: min(1200px, 90vw);
  scroll-snap-type: none; /* .modal ya no es lo que scrollea con snap en este modo — eso pasa a .detail-body */
  /* El redondeo de 16px (heredado de .modal base) se ve cada vez más chico
     a medida que el modal crece con la pantalla — clamp(mínimo, escala,
     máximo) en vez de un px fijo: crece con el ancho de ventana (1.8vw)
     pero nunca baja de 16px (el valor de siempre) ni pasa de 30px (para
     que no se vuelva una forma rara en monitores enormes, donde el modal
     ya está topado en 1200px de todos modos). */
  border-radius: clamp(16px, 1.8vw, 30px);
}
/* La máscara de "scroll-chaining" (ver .snap-sections::before más abajo)
   era para tapar texto que se asoma arriba de la foto sticky al encadenar
   scroll hacia .modal — acá la foto no comparte scroll con el contenido
   (es una columna aparte), así que ese glitch no puede pasar: no hace
   falta la máscara. */
#modal-product .modal.snap-sections.wide-split::before { display: none; }
#modal-product .modal.snap-sections.wide-split #product-detail-content {
  display: flex; align-items: flex-start; gap: 40px;
}
#modal-product .modal.snap-sections.wide-split #product-detail-content .thumb {
  flex: 1 1 0; min-width: 0;
  position: static;
  /* !important: el margin-bottom:20px viene puesto inline (style="...") en
     el HTML que arma app.js — un estilo inline le gana a cualquier regla de
     hoja de estilos por más específica que sea, ¡important es la única
     forma de pisarlo desde acá. Mismo truco que ya usa .thumb-left .thumb
     para lo mismo, ver arriba. */
  margin: 0 !important;
  /* Mismo criterio que el border-radius de .modal más arriba (clamp que
     escala con la pantalla) — pero el mínimo/máximo son los de la foto
     (10px de base, no los 16px de la tarjeta) y !important porque acá SÍ
     hay que pisar el border-radius:10px que viene inline. */
  border-radius: clamp(10px, 1.2vw, 20px) !important;
  box-shadow: 0 18px 38px rgba(18,50,74,0.40); /* flotando siempre — acá no hay "scroll de la foto" que la levante o no */
}
#modal-product .modal.snap-sections.wide-split #product-detail-content .thumb.lifted {
  transform: none; /* no se mueve nunca en este modo, a diferencia del translateY(-4px) de .lifted en angosto */
}
#modal-product .modal.snap-sections.wide-split #product-detail-content .detail-body {
  flex: 1 1 0; min-width: 0; position: relative;
  /* overflow-x:hidden EXPLÍCITO (no dejar que el navegador lo infiera):
     con solo overflow-y:auto, el navegador pone overflow-x en auto
     también (regla del spec para no dejar un eje "visible" y el otro no) —
     eso convertía a .detail-body en contenedor con scroll horizontal
     real, y el margin-right:-12px de .snap-dots (truco pensado para
     modo angosto, donde .detail-body no tiene overflow propio) hacía que
     ese eje nuevo corriera TODO el contenido 16px a la izquierda — el
     numerito "①" quedaba cortado contra el borde. Con overflow-x:hidden
     puesto a propósito, ese eje no se activa y el corrimiento desaparece. */
  overflow-x: hidden; overflow-y: auto;
  scroll-snap-type: y mandatory; scroll-behavior: smooth; scrollbar-width: none;
  /* padding-right: recorte de la caja de .detail-body para que overflow-x:
     hidden no se coma a los puntitos (ver más abajo por qué necesitan
     asomar hacia afuera del borde de contenido). 40px = el sobresaliente
     de .snap-dots (28px, ver esa regla) + 8px más de margen para el
     puntito activo (crece con scale(2) + halo hacia el lado derecho). */
  padding-right: 40px;
}
/* .snap-dots (por defecto -12px, pensado para el padding de 22px de
   .content en modo angosto) necesita sobresalir MÁS acá: el borde derecho
   de los botones/contenido (variant-btn-grid, selects, etc.) termina justo
   en el mismo borde de caja que usa .snap-dots para su margin-right — un
   -12px alcanzaba para el puntito quieto, pero el ACTIVO (agrandado por
   scale(2) + halo box-shadow, ver .snap-dot.active en el CSS) crece hacia
   la izquierda y le tapaba la esquina a botones de opción largos (ej.
   "Tarots FOURNIER importados") cuando, al centrarse verticalmente (ver
   setupSnapSections en el JS), el puntito activo cae a la altura de esos
   botones. Con -28px el puntito en reposo queda separado del borde del
   contenido por 16px libres — ni el scale(2) ni el halo, que juntos
   crecen 8px hacia cada lado, llegan a tocarlo. */
#modal-product .modal.snap-sections.wide-split #product-detail-content .snap-dots {
  margin-right: -28px;
}
#modal-product .modal.snap-sections.wide-split #product-detail-content .detail-body::-webkit-scrollbar { display: none; }

/* Scroll segmentado por bloques (selector de 2 niveles): en vez de un
   scroll largo, cada tirón de scroll "salta" directo al siguiente bloque
   de info (título+descripción / categoría / elegí una opción / cantidad).
   scroll-padding-top se pisa por JS con el alto real de la foto (que sigue
   flotando fija arriba) para que el bloque no quede tapado al saltar. */
#modal-product .modal.snap-sections {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth; /* así un click en un puntito también anima suave, no solo el swipe */
  scrollbar-width: none; /* Firefox: la barra de scroll ahora la reemplazan los puntitos */
}
#modal-product .modal.snap-sections::-webkit-scrollbar { display: none; } /* Chrome/Safari */
/* Con una descripción muy larga (scrollea dentro de su propia sección), al
   llegar al tope de ese scroll interno el navegador sigue "encadenando" el
   scroll hacia .modal (nativo del navegador, no algo que se pueda evitar
   sin perder la fluidez del scroll) — eso puede disparar el snap de golpe
   y dejar, por una fracción de segundo, texto de la sección anterior
   asomando arriba de la foto. En vez de frenar ese scroll (se sentía
   peor), se tapa: una franja fija arriba, del mismo color que el modal,
   que oculta cualquier cosa que se asome ahí — la foto (sticky, top:22px)
   empieza justo debajo, así que nunca se nota el corte. margin-bottom
   negativo (mismo alto que height) para no ocupar espacio en el flujo —
   variante del truco que ya usan los puntitos y el botón de cerrar
   (ahí con height:0, acá con margin negativo porque este SÍ necesita
   altura propia para tener algo pintable). */
#modal-product .modal.snap-sections::before {
  content: ""; position: sticky; top: 0; z-index: 1;
  display: block; height: 22px; margin-bottom: -22px;
  background: var(--card); border-radius: 16px 16px 0 0; pointer-events: none;
}
#modal-product .modal.snap-sections .snap-section {
  scroll-snap-align: start;
  /* OJO: scroll-snap-stop:always se probó acá y se sacó — rompía el
     scroll por completo en iPad (Safari), sin arreglar el salteo en
     celular real tampoco. No volver a agregarlo sin probar en un
     dispositivo iOS real primero. */
  /* max-height/overflow-y los pisa app.js con el alto real disponible —
     un bloque con más contenido del que entra (ej. una descripción larga)
     scrollea DENTRO de sí mismo en vez de derramarse sobre el bloque
     siguiente. Barra finita en vez de ocultarla del todo (a diferencia de
     la de .modal, acá no hay puntitos que avisen que se puede scrollear
     más adentro de un bloque). */
  scrollbar-width: thin;
  /* Efecto de foco: la sección activa (la que "eligió" el puntito
     encendido — mismo cálculo de activeIdx que ya existía, ver el
     listener de scroll en app.js) crece un poco entera (texto, botones,
     todo junto vía transform:scale). Se probaron primero opacity en las
     inactivas (leía como error, texto "apagado") y después levantar con
     sombra (no convenció) — esto quedó como versión final.
     transform-origin:left top para que crezca hacia la derecha/abajo
     sin correr el borde izquierdo (quedaría desalineado con las
     secciones de arriba/abajo, que no escalan).
     width:96.6% (1 / 1.035) ANTES de escalar: medido que scale(1.035) sin
     esto agrandaba también el ANCHO de la caja, no solo el texto — el
     contenido terminaba 9.7px más ancho que la foto de arriba, se veía
     sin margen a la derecha. Achicando el ancho base ese mismo 3.5% de
     antemano, al escalarlo el resultado final vuelve a quedar exacto al
     ancho de la foto. */
  transition: transform .3s ease, width .3s ease;
  transform-origin: left top;
}
#modal-product .modal.snap-sections .snap-section.section-active {
  width: 96.6%;
  transform: scale(1.035);
}
#modal-product .modal.snap-sections .snap-section::-webkit-scrollbar { width: 4px; }
#modal-product .modal.snap-sections .snap-section::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }

/* Puntitos de progreso (reemplazan la barra de scroll — van donde iba
   ella, no encima de la foto): columna vertical pegada al borde derecho,
   a la altura del bloque de contenido (justo debajo de la foto). OJO:
   position:absolute (lo que había antes) NO queda fijo — un hijo absolute
   de un ancestro con scroll SÍ se mueve con ese scroll (el .close-btn
   "parece" quieto por otro motivo, no por ser absolute). position:sticky
   es lo que de verdad fija un elemento mientras el resto scrollea —misma
   técnica que ya usa la foto. height:0 + overflow:visible para que no
   empuje nada hacia abajo (ocupa cero alto en el flujo); app.js pisa
   "top" con el alto real de la foto. */
.snap-dots {
  position: sticky; top: 0; z-index: 2; height: 0; overflow: visible;
  display: flex; flex-direction: column; align-items: flex-end; gap: 9px;
  /* Medido: el borde derecho de .snap-section (ahí aparece su barra
     interna cuando el texto no entra) coincide con el de .snap-dots — con
     padding-right positivo el puntito quedaba DENTRO de esa franja de
     4px, no a la derecha. padding no admite negativos para "salirse" del
     borde, así que se usa margin-right negativo (agranda la caja del
     contenedor hacia afuera) para que el puntito, alineado al final,
     llegue más allá del borde de .snap-section — hacia el padding propio
     de .content (que sigue hasta el borde real del modal). */
  margin-right: -12px;
}
.snap-dot {
  width: 8px; height: 8px; flex-shrink: 0; border-radius: 999px; border: none; padding: 0; cursor: pointer;
  background: var(--line); transition: background-color .25s ease, transform .25s ease, box-shadow .25s ease;
}
/* Más marcado que antes (era solo un cambio de color + scale:1.4, se
   notaba poco): halo alrededor del punto activo, además de agrandarlo
   más — mismo estilo "foco" que .snap-section.section-active más abajo,
   para que puntito + sección activa lean como un solo efecto coordinado. */
.snap-dot.active {
  background: var(--accent); transform: scale(2);
  box-shadow: 0 0 0 4px rgba(47,159,196,0.22);
}

/* Ojito flotante: abre la vista previa en vivo del formulario de producto.
   Solo por debajo de 920px — en pantallas anchas la vista previa ya está
   siempre visible en la columna fija (.side), así no compite con el resto
   del formulario ni lo tapa al hacer scroll. */
#preview-fab { display: none; }
@media (max-width: 919px) {
  #preview-fab {
    display: inline-flex; position: fixed; right: 16px; bottom: 16px; z-index: 39;
    border-radius: 999px; padding: 12px 18px; box-shadow: 0 8px 24px rgba(18,50,74,0.28);
  }
}
/* Vista previa del admin: UNA sola tarjeta que envuelve todo (imagen,
   categoría, nombre, descripción, selector, precio, botón, pedido y línea
   de confianza), calcada de #pv-card/.card-body en admin-maqueta.html —
   antes eran dos bloques separados con leyendas que la maqueta no tiene.
   Scope por .preview-content-target (no #preview-content): la columna fija
   de escritorio usa id="preview-content-side", el modal del ojito usa
   id="preview-content" — ambos comparten esta clase. */
.preview-content-target .live-preview-card {
  background: var(--card); border: 1px solid var(--line); border-radius: 18px;
  box-shadow: var(--shadow); padding: 16px; margin-bottom: 18px; overflow: hidden;
}
.preview-content-target .pv-thumb {
  aspect-ratio: 1/1; border-radius: 10px; margin-bottom: 14px; display: flex; align-items: center; justify-content: center;
  /* Mismo degradado que .thumb en admin-maqueta.html (panel-2→panel ahí es
     bg-alt→panel acá, mismos hex — --bg-alt: #eaf5fb === su --panel-2). */
  background: linear-gradient(135deg, var(--bg-alt), var(--panel));
  border: 1px solid var(--line); font-size: 2rem; color: var(--accent-soft); position: relative; overflow: hidden;
}
.preview-content-target .pv-thumb img { width: 100%; height: 100%; object-fit: cover; }
.preview-content-target .pv-thumb-cap {
  position: absolute; left: 8px; right: 8px; bottom: 8px; text-align: center;
  font-size: 0.82rem; font-weight: 700; color: #fff; background: rgba(28,95,125,0.62);
  border-radius: 8px; padding: 5px 8px; line-height: 1.15;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.preview-content-target .pv-cat { color: var(--accent); text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.05em; margin: 0 0 12px; }
.preview-content-target .pv-title { font-size: var(--fs-subtitle); margin: 0 0 14px; line-height: 1.12; }
.preview-content-target .pv-desc { color: var(--muted); font-size: var(--fs-paragraph); line-height: 1.5; margin: 0; }

.drawer-overlay {
  position: fixed; inset: 0; z-index: 40; background: rgba(10,20,30,0.55); display: flex; justify-content: flex-end;
  animation: overlayFadeIn .15s ease;
}
.drawer {
  width: 100%; max-width: 380px; background: var(--card); border-left: 1px solid var(--line); display: flex; flex-direction: column; height: 100%;
  animation: drawerSlideIn .2s ease;
}
.drawer-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.drawer-body { flex: 1; overflow-y: auto; padding: 12px 20px; }
.drawer-footer { padding: 16px 20px; border-top: 1px solid var(--line); }

/* Formularios */
label.field-label { display: block; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin-bottom: 4px; }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=tel], textarea, select {
  width: 100%; padding: 9px 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel);
  font-size: 0.9rem; color: var(--text); outline: none; transition: border-color .15s ease, box-shadow .15s ease;
}
input[type=text]:focus, input[type=email]:focus, input[type=password]:focus, input[type=number]:focus,
input[type=tel]:focus, textarea:focus, select:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px rgba(47,159,196,0.15);
}
textarea { resize: vertical; min-height: 74px; }
.field { margin-bottom: 12px; }
.pw-wrap { position: relative; }
.pw-wrap input[type=password], .pw-wrap input[type=text] { padding-right: 38px; }
.pw-toggle {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border: none; background: none; cursor: pointer;
  font-size: 0.95rem; color: var(--muted); display: flex; align-items: center; justify-content: center;
  border-radius: 999px; transition: background-color .15s ease, color .15s ease;
}
.pw-toggle:hover { background: var(--bg-alt); color: var(--text); }
.btn-primary {
  /* El botón de acción principal es el foco real de la pantalla (10%): usa
     el color más vivo (accent), no el más oscuro — ese queda para texto y
     superficies grandes. */
  width: 100%; padding: 12px; border-radius: 10px; border: none; background: var(--accent); color: #fff; font-weight: 500; font-size: var(--fs-button);
  transition: filter .15s ease, transform .1s ease;
}
/* filter, no var(--deep): ver el comentario igual en .hero-cta:hover. */
.btn-primary:hover:not(:disabled) { filter: brightness(0.85); }
.btn-primary:active:not(:disabled) { transform: scale(0.98); }
.btn-primary:disabled { background: var(--line); color: var(--muted); }
.btn-secondary {
  padding: 8px 14px; border-radius: 10px; border: 1px solid var(--line); background: transparent; color: var(--accent); font-size: var(--fs-button-secondary);
  transition: background-color .15s ease, border-color .15s ease, transform .1s ease;
}
.btn-secondary:hover { background: var(--bg-alt); border-color: var(--accent); }
.btn-secondary:active { transform: scale(0.98); }
.btn-danger { background: none; border: none; color: var(--danger); transition: opacity .15s ease; }
.btn-danger:hover { opacity: 0.65; }
.qty-control { display: flex; align-items: center; gap: 10px; }
.qty-btn {
  width: 30px; height: 30px; border-radius: 999px; border: 1px solid var(--line); background: var(--card);
  transition: background-color .15s ease;
}
.qty-btn:hover:not(:disabled) { background: var(--bg-alt); }
.error-text { color: var(--danger); font-size: 0.78rem; margin: 4px 0; }
.toast {
  position: fixed; bottom: 16px; left: 16px; right: 16px; z-index: 50; background: var(--danger); color: #fff;
  padding: 12px 16px; border-radius: 10px; font-size: 0.85rem; max-width: 380px; margin: 0 auto;
  animation: toastSlideUp .2s ease;
}

/* WhatsApp flotante */
.wa-float {
  position: fixed; bottom: 20px; right: 20px; z-index: 35; background: #25D366; color: #0b1a10;
  width: 56px; height: 56px; border-radius: 999px; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 16px rgba(0,0,0,0.2); text-decoration: none; font-size: 1.5rem;
  transition: transform .15s ease, box-shadow .15s ease;
}
.wa-float:hover { transform: scale(1.06); box-shadow: 0 8px 20px rgba(0,0,0,0.25); }

/* Botón de administrar: flotante abajo a la derecha, temporal hasta tener otro acceso */
.admin-float {
  position: fixed; bottom: 88px; right: 20px; z-index: 35; background: var(--card); color: var(--deep);
  width: 48px; height: 48px; border-radius: 999px; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 16px rgba(0,0,0,0.18); border: 1px solid var(--line); font-size: 1.2rem; cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease;
}
.admin-float:hover { transform: scale(1.06); box-shadow: 0 8px 20px rgba(18,50,74,0.24); }

/* Tabs simples */
.tabs { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.tab-btn {
  padding: 6px 14px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--text); font-size: 0.85rem;
  transition: background-color .15s ease, border-color .15s ease;
}
.tab-btn:hover:not(.active) { background: var(--bg-alt); }
.tab-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Listas admin */
.admin-row {
  display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: 10px; background: var(--panel);
  border: 1px solid var(--line); margin-bottom: 8px; font-size: 0.88rem;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
@media (hover: hover) {
  .admin-row:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(28,95,125,0.14); }
}
@media (prefers-reduced-motion: reduce) { .admin-row { transition: none; } }
.admin-row .thumb-sm { width: 40px; height: 40px; border-radius: 8px; overflow: hidden; background: var(--bg-alt); flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.admin-row .grow { flex: 1; min-width: 0; }
.admin-row .grow p { margin: 0; }
.admin-row .grow .muted { color: var(--muted); font-size: 0.75rem; }
.stock-inline-wrap { display: flex; flex-direction: column; align-items: center; gap: 2px; flex-shrink: 0; }
.stock-inline-label { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.stock-inline-input {
  width: 56px; padding: 6px 4px; text-align: center; border-radius: 8px; border: 1px solid var(--line);
  background: var(--panel); font-size: 0.9rem; font-weight: 700; color: var(--text);
}
.stock-inline-input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px rgba(47,159,196,0.15); }
.stock-inline-input.stock-zero { border-color: var(--danger); color: var(--danger); }
.variant-count-badge {
  display: flex; align-items: center; justify-content: center; width: 56px; height: 33px;
  border-radius: 8px; border: 1px dashed var(--line); background: var(--bg-alt);
  font-size: 0.9rem; font-weight: 700; color: var(--muted); cursor: help;
}

/* Formulario de producto: 2 columnas en pantallas anchas (form + vista
   previa fija al costado), 1 columna en el resto (la vista previa pasa a
   vivir solo en el ojito flotante). */
.admin-grid { display: grid; grid-template-columns: 1fr; gap: 20px; }
@media (min-width: 920px) { .admin-grid { grid-template-columns: 1fr 348px; align-items: start; } }
.side { display: none; }
@media (min-width: 920px) {
  .side {
    display: block; position: sticky; top: 12px; align-self: start;
    max-height: calc(100vh - 84px); overflow-y: auto; padding-right: 4px;
  }
  .side::-webkit-scrollbar { width: 6px; }
  .side::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
}
.pv-head, .rs-head { font-weight: 700; color: var(--deep); margin-bottom: 10px; }
.rs-head { margin-top: 18px; }
.resumen { border-top: 1px solid var(--line); padding-top: 4px; }
.rs-row {
  display: flex; justify-content: space-between; gap: 10px; padding: 7px 0;
  border-top: 1px solid var(--line); font-size: 0.85rem;
}
.rs-row:first-child { border-top: none; }
.rs-row span { color: var(--muted); }
.rs-row b { color: var(--accent); }

/* Tabla de escalones mayoristas. */
.tiers-tbl { width: 100%; border-collapse: collapse; font-size: 0.85rem; margin-bottom: 8px; }
.tiers-tbl th, .tiers-tbl td { border: 1px solid var(--line); padding: 5px 6px; text-align: center; }
.tiers-tbl th { background: var(--bg-alt); color: var(--muted); font-weight: 600; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.03em; }
.tiers-tbl input { width: 88px; border: none; background: transparent; text-align: center; font-family: inherit; color: var(--text); font-size: 0.85rem; }
.tiers-tbl input:focus { outline: none; background: var(--bg-alt); border-radius: 4px; }

/* Título/subtítulo de una pantalla del admin (ej. "Productos" / "¿Qué
   querés hacer?"), y las 2 tarjetas flotantes de entrada. */
.h-title { font-family: 'Fraunces', Georgia, serif; font-size: var(--fs-title); color: var(--deep); margin: 2px 0 4px; }
.h-sub { color: var(--muted); font-size: var(--fs-paragraph); margin: 0 0 18px; }
.back { color: var(--accent); font-size: 0.85rem; font-weight: 600; background: none; border: none; cursor: pointer; padding: 8px 0; font-family: inherit; }
.back:hover { text-decoration: underline; }
.home-cards { display: grid; grid-template-columns: 1fr; gap: 16px; max-width: 640px; margin-top: 10px; }
@media (min-width: 560px) { .home-cards { grid-template-columns: 1fr 1fr; } }
.home-card {
  text-align: left; background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 10px 30px rgba(28,95,125,0.10); padding: 22px; cursor: pointer; font-family: inherit;
  transition: transform .15s ease, box-shadow .15s ease;
}
@media (hover: hover) {
  .home-card:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(28,95,125,0.14); }
}
@media (prefers-reduced-motion: reduce) { .home-card { transition: none; } }
.hc-ic { font-size: 1.9rem; }
.hc-n { font-weight: 700; color: var(--deep); font-size: var(--fs-subtitle); margin: 8px 0 4px; }
.hc-d { color: var(--muted); font-size: 0.85rem; line-height: 1.4; }

/* Agrupa los controles (stock, flechas, editar, borrar...) que van después
   del nombre en una fila de admin, para poder mandarlos a una segunda línea
   completa en pantallas chicas — en vez de aplastarse todos en una sola
   fila y terminar tapando el nombre (pasaba en el celular). */
.admin-row-controls { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
@media (max-width: 640px) {
  .admin-row, .variant-group-header, .variant-option-row { flex-wrap: wrap; }
  .admin-row-controls {
    flex: 1 1 100%; flex-wrap: wrap; justify-content: flex-end; margin-top: 8px; padding-top: 8px;
    border-top: 1px dashed var(--line);
  }
}

/* Reordenar (drag & drop + flechas): productos, grupos de variantes y opciones */
.dragging { opacity: 0.6; box-shadow: 0 6px 16px rgba(18,50,74,0.18); }
.drag-handle {
  cursor: grab; touch-action: none; color: var(--muted); font-size: 1.1rem; padding: 4px 2px;
  flex-shrink: 0; user-select: none; -webkit-user-select: none;
}
.drag-handle:active { cursor: grabbing; }
.reorder-arrows { display: flex; flex-direction: column; gap: 3px; flex-shrink: 0; }
.reorder-btn {
  width: 28px; height: 24px; line-height: 1; font-size: 1rem; font-weight: 700; padding: 0; border-radius: 5px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted); cursor: pointer;
}
.reorder-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.reorder-btn:disabled { opacity: 0.35; cursor: default; }

/* Tarjetas de "tipo de producto" (variantes): reemplazan los 2 checkboxes
   sueltos por algo más claro de leer. "Sin variantes" es un estado derivado
   (cero grupos) — no tiene acción propia, solo informa. */
/* minmax(130px…) y gap:12px (no 150px/10px): el panel admin real usa una
   columna de formulario más angosta que la maqueta (contenedor compartido
   con el resto de las vistas del admin), así que con el umbral de la
   maqueta tal cual las 5 tarjetas no entraban en una sola fila a este ancho. */
.type-picker-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(124px, 1fr)); gap: 12px; margin-bottom: 14px; }
.type-card {
  /* Mismo fondo y sombra que .sec ("Información básica", etc.) — antes
     usaba --panel (celeste tenue) y no tenía sombra propia, así que se veía
     como un tipo de tarjeta distinto en vez de una card más adentro de la
     misma sección. */
  text-align: center; padding: 14px 12px; border-radius: 14px; background: var(--card); border: 1.5px solid var(--line);
  box-shadow: var(--shadow);
  font-family: inherit; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease; position: relative;
}
@media (hover: hover) { .type-card:hover:not(.is-static) { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(28,95,125,0.14); } }
@media (prefers-reduced-motion: reduce) { .type-card { transition: none; } }
.type-card.active { border-color: var(--accent); background: #eef7fb; }
.type-card.is-static { cursor: default; }
.type-card .check { position: absolute; top: 8px; right: 10px; color: var(--accent); font-weight: 700; opacity: 0; }
.type-card.active .check { opacity: 1; }
.type-card .ti { font-size: 1.5rem; }
.type-card .tn { font-weight: 700; color: var(--deep); font-size: var(--fs-subtitle); margin: 6px 0 3px; overflow-wrap: break-word; }
.type-card .td { font-size: 0.76rem; color: var(--muted); line-height: 1.35; overflow-wrap: break-word; }
.legacy-note {
  font-size: 0.78rem; color: var(--muted); background: var(--bg-alt); border: 1px dashed var(--line);
  border-radius: 8px; padding: 8px 10px; margin: 10px 0 0;
}
.cust-config { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.cust-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.cust-row .field-label { margin: 0; min-width: 150px; }
.cust-hint { font-size: 0.72rem; color: var(--muted); }
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.seg-btn {
  padding: 6px 12px; border: none; background: var(--panel); color: var(--text); font-size: 0.82rem;
  font-family: inherit; cursor: pointer; border-right: 1px solid var(--line);
}
.seg-btn:last-child { border-right: none; }
.seg-btn.active { background: var(--accent); color: #fff; font-weight: 600; }

/* Cabecera de la lista de opciones ("N opciones" + Pegar varias) e igual a
   .opts-head de la maqueta. */
.opts-head { display: flex; justify-content: space-between; align-items: center; margin: 4px 0 8px; }
.opts-head .muted { font-size: 0.75rem; color: var(--muted); }
.paste-box { margin: 0 0 8px; }
.paste-box textarea {
  width: 100%; min-height: 66px; border: 1px solid var(--line); border-radius: 10px; padding: 8px;
  font-family: inherit; font-size: 0.85rem; background: var(--panel); color: var(--text); margin-bottom: 6px;
}

.variant-group-box {
  padding: 10px; border-radius: 10px; background: var(--panel); border: 1px solid var(--line); margin-bottom: 12px;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
@media (hover: hover) {
  .variant-group-box:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(28,95,125,0.14); }
}
@media (prefers-reduced-motion: reduce) { .variant-group-box { transition: none; } }

/* Las 4 secciones numeradas del formulario de producto (Información básica,
   Tipo de producto, Variantes, Precios y stock) — igual a .sec de la
   maqueta: tarjeta blanca con sombra propia (no solo al hacer hover), más
   espaciada entre sí que las cards internas de .variant-group-box. */
.sec {
  background: var(--card); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow);
  padding: 18px; margin-bottom: 18px; transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
@media (hover: hover) {
  .sec:hover { transform: translateY(-3px); box-shadow: 0 16px 38px rgba(28,95,125,0.14); }
}
@media (prefers-reduced-motion: reduce) { .sec { transition: none; } }
.sec-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.sec-num { width: 30px; height: 30px; border-radius: 10px; background: var(--accent); color: #fff; display: grid; place-items: center; font-weight: 700; flex-shrink: 0; }
/* Cartelito al lado del título de cada sección de Configuración, para que
   alguien que nunca vio el panel sepa de un vistazo qué hace falta completar
   para que la tienda funcione y qué es solo estético. */
.sec-tag { font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; padding: 4px 10px; border-radius: 999px; white-space: nowrap; margin-left: auto; }
.sec-tag-required { background: var(--accent); color: #fff; }
.sec-tag-optional { background: var(--panel); color: var(--muted); border: 1px solid var(--line); }
/* Barra de "Guardar configuración" fija abajo: la pantalla de Configuración
   tiene muchas secciones largas, así que sin esto habría que scrollear hasta
   el final cada vez que se quiere guardar un cambio hecho arriba de todo. */
.settings-savebar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  background: var(--card); border-top: 1px solid var(--line); box-shadow: 0 -8px 24px rgba(18,50,74,0.12);
  padding: 12px 16px; display: flex; align-items: center; justify-content: flex-end; gap: 14px;
}
.settings-savebar-inner { max-width: 1100px; margin: 0 auto; width: 100%; display: flex; align-items: center; justify-content: flex-end; gap: 14px; }
.settings-savebar a { font-size: 0.85rem; color: var(--deep); font-weight: 600; }
.settings-savebar .btn-primary { width: auto; margin: 0; }
@media (max-width: 480px) { .settings-savebar a { display: none; } }
.sec-title { font-weight: 700; color: var(--deep); font-size: var(--fs-subtitle); }
.row2 { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 560px) { .row2 { grid-template-columns: 150px 1fr; } }
.foto {
  border: 1.5px dashed var(--line); border-radius: 12px; aspect-ratio: 1/1; display: grid; place-items: center;
  color: var(--muted); font-size: 0.78rem; text-align: center; cursor: pointer; background: var(--panel); line-height: 1.5;
  overflow: hidden;
}
.foto img { width: 100%; height: 100%; object-fit: cover; }
.hint { font-size: 0.78rem; color: var(--muted); margin-top: 6px; }
.variant-group-header { display: flex; align-items: center; gap: 8px; }
.variant-group-title { flex: 1; min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.variant-group-title .muted { font-weight: 400; color: var(--muted); font-size: 0.78rem; }
.variant-group-body { margin-top: 4px; }
/* Etiqueta chica de sección dentro de "Variantes" (ej: "Opciones (nombre y
   stock)"), igual a .g-title de la maqueta. */
.g-title { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); font-weight: 700; margin: 14px 0 8px; }
/* Pestañas de categoría del editor "Dos niveles" — igual a .lvl-tab de la
   maqueta: píldora vacía por defecto, sólida en acento cuando está activa. */
.lvl-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.lvl-tab {
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: transparent;
  color: var(--muted); font-size: 0.82rem; font-weight: 600; cursor: pointer; font-family: inherit;
  display: inline-flex; align-items: center; gap: 6px;
}
.lvl-tab.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.lvl-tab .drag-handle { font-size: 0.9rem; padding: 0; color: inherit; }
.lvl-tab [data-dellvl] { cursor: pointer; opacity: 0.75; }
.lvl-tab [data-dellvl]:hover { opacity: 1; }
.lvl-tab.dragging { opacity: 0.4; }
.variant-option-block { margin-bottom: 6px; }
/* Fila de opción = .orow de la maqueta: la tarjetita (borde+fondo+radio) va
   en la fila en sí, no en el bloque que la envuelve (a diferencia de antes). */
.variant-option-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
}
.variant-option-row .drag-handle { flex-shrink: 0; }
.variant-option-row .opt-preview { width: 34px; height: 34px; cursor: pointer; }
/* Nombre de la opción: sin borde propio, se funde en la fila (igual que
   .oname en la maqueta) en vez de verse como un mini-input aparte. */
.variant-option-row .option-value {
  flex: 1; min-width: 60px; border: none; background: transparent; padding: 4px 2px; font-size: 0.88rem;
}
.variant-option-row .option-value:focus { box-shadow: none; }
.variant-option-row .stock-inline-input { width: 54px; padding: 4px 2px; font-size: 0.82rem; font-weight: 400; background: var(--card); flex-shrink: 0; }
.variant-option-row .reorder-arrows { flex-shrink: 0; }
/* Botón de solo ícono (💲 precio propio, 🗑 quitar, ✕ de un escalón) — igual
   a .oicon de la maqueta: sin fondo ni borde, se resalta con color. */
.oicon { background: none; border: none; padding: 3px; font-size: 0.92rem; color: var(--muted); cursor: pointer; font-family: inherit; flex-shrink: 0; }
.oicon:hover { color: var(--accent); }
.oicon.on { color: var(--accent); }
/* Botón con borde punteado (+ Agregar opción, Pegar varias, + Escalón…) —
   igual a .addbtn de la maqueta: ni sólido ni link, borde punteado color acento. */
.addbtn {
  background: none; border: 1px dashed var(--accent); color: var(--accent); border-radius: 10px;
  padding: 8px 12px; font-weight: 600; font-size: 0.82rem; cursor: pointer; font-family: inherit;
}
.addbtn:hover { background: var(--bg-alt); }
/* Panel de precio propio de una opción — igual a .opanel: indentado para
   quedar alineado debajo del nombre (pasando el drag handle + la miniatura). */
.option-tiers-box { padding: 9px 10px; margin: 2px 0 8px 44px; background: var(--bg-alt); border-radius: 8px; font-size: 0.82rem; }
.option-tiers-box .opanel-title { margin-bottom: 6px; }
.option-tiers-box .prow { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
.option-tiers-box .muted { font-size: 0.72rem; color: var(--muted); }
.option-tiers-box input { width: 84px; border: 1px solid var(--line); border-radius: 6px; padding: 3px 6px; font-family: inherit; background: var(--card); color: var(--text); }

/* Pestaña chica centrada (ej: colapsar un grupo de variantes) */
.center-tab-wrap { text-align: center; margin: 6px 0; }
.center-tab {
  display: inline-flex; align-items: center; justify-content: center; padding: 8px 22px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted); cursor: pointer;
}
.center-tab:hover { color: var(--accent); border-color: var(--accent); }
/* Triángulo dibujado con bordes (en vez de un glifo de texto) para que
   gire siempre perfectamente centrado sobre sí mismo, sin saltos. */
.center-tab .chevron {
  display: inline-block; width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid currentColor;
  transition: transform .15s ease;
}
.center-tab .chevron.open { transform: rotate(180deg); }
.upload-preview { width: 60px; height: 60px; border-radius: 10px; overflow: hidden; background: var(--bg-alt); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.upload-preview.sm { width: 36px; height: 36px; }

/* Sistema 60/30/10: el footer es una superficie GRANDE, así que se queda en
   el 60% neutro (como el resto de la página) en vez de un bloque sólido del
   color más fuerte — ese color se reserva para los focos reales (botones,
   estados activos), no para superficies grandes. */
footer.site-footer { background: var(--panel); color: var(--muted); margin-top: 40px; border-top: 1px solid var(--line); }
.footer-inner {
  max-width: 1120px; margin: 0 auto; padding: 44px 16px 8px;
  display: grid; grid-template-columns: 1fr; gap: 30px;
}
@media (min-width: 720px) { .footer-inner { grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 24px; } }
.footer-col h4 { color: var(--deep); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; margin: 0 0 14px; }
.footer-col a, .footer-col p {
  display: block; color: var(--muted); text-decoration: none; font-size: 0.85rem;
  margin: 0 0 10px; line-height: 1.55; transition: color .15s ease;
}
.footer-col a:hover { color: var(--accent); }
.footer-brand img { height: 46px; width: 46px; object-fit: contain; margin-bottom: 12px; }
.footer-brand h3 { color: var(--deep); font-size: 1.15rem; margin: 0 0 10px; }
.footer-brand p { color: var(--muted); margin-bottom: 16px; }
.footer-social { display: flex; gap: 10px; }
.footer-social a {
  width: 36px; height: 36px; border-radius: 999px; background: var(--card); border: 1px solid var(--line); color: var(--deep);
  display: flex; align-items: center; justify-content: center; font-size: 1rem; margin: 0;
  transition: background-color .15s ease, color .15s ease;
}
.footer-social a:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.footer-bottom {
  margin-top: 26px; border-top: 1px solid var(--line); padding: 18px 16px;
  text-align: center; font-size: 0.78rem; color: var(--muted);
}

.order-card { border: 1px solid var(--line); border-radius: 10px; margin-bottom: 10px; background: var(--panel); font-size: 0.85rem; overflow: hidden; }
.order-card .status {
  display: inline-block; padding: 3px 12px; border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 0.72rem; font-weight: 600;
}
.order-card .status.status-pending { background: #fff4e0; color: #8a5a00; }
.order-card .status.status-done { background: #e6f7ee; color: #1a6b3f; }
.order-card .status.status-cancelled { background: rgba(201,79,79,0.15); color: var(--danger); }

/* "Mis pedidos": tarjeta colapsable (<details>/<summary>) */
.order-summary {
  position: relative; padding: 12px 34px 12px 12px; cursor: pointer; list-style: none;
  -webkit-tap-highlight-color: transparent;
}
.order-summary::-webkit-details-marker { display: none; }
.order-summary::marker { content: ""; }
.order-summary::after {
  content: "⌄"; position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  font-size: 1rem; color: var(--muted); transition: transform .15s ease;
}
.order-card[open] .order-summary::after { transform: translateY(-50%) rotate(180deg); }
.order-card[open] .order-summary { border-bottom: 1px solid var(--line); }
.order-summary-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 5px; }
.order-summary-total { font-weight: 700; color: var(--text); }
.order-summary-bottom { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 0.8rem; color: var(--muted); }
.order-details { padding: 10px 12px 12px; }
.order-group-header {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); font-weight: 600;
  margin: 18px 0 8px;
}
.order-group-header:first-child { margin-top: 0; }

/* Tarjetas de resumen (Dashboard admin / Resumen cliente) */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-bottom: 16px; }
.stat-card { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 14px; }
.stat-card .stat-value { font-size: 1.5rem; font-weight: 700; color: var(--text); line-height: 1.1; }
.stat-card .stat-label { font-size: 0.78rem; color: var(--muted); margin-top: 4px; }
.stat-card.accent { border-color: var(--accent); }
.stat-card.accent .stat-value { color: var(--accent); }
.status-breakdown { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.status-breakdown-item { font-size: 0.82rem; font-weight: 700; color: var(--accent); background: rgba(47,159,196,0.12); padding: 5px 12px; border-radius: 999px; }
.status-breakdown-item.status-pending { background: #fff4e0; color: #8a5a00; }
.status-breakdown-item.status-done { background: #e6f7ee; color: #1a6b3f; }
.status-breakdown-item.status-cancelled { background: rgba(201,79,79,0.15); color: var(--danger); }

/* Dashboard del admin: tarjetas de resumen + listas "Necesitan atención" y
   "Últimos pedidos", calcadas de admin-maqueta.html (.stat/.prow-prod/
   .chip-status) — con nombres propios para no tocar .stat-grid/.admin-row,
   que ya se usan en Mi cuenta, el carrito, categorías y la lista de productos. */
.dash-stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin: 6px 0 20px; }
@media (min-width: 720px) { .dash-stat-grid { grid-template-columns: repeat(4, 1fr); } }
.dash-stat { background: var(--card); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); padding: 16px; }
.dash-stat .n { font-family: 'Fraunces', Georgia, serif; font-size: 1.9rem; color: var(--deep); font-variant-numeric: tabular-nums; line-height: 1.1; }
.dash-stat .l { font-size: 0.8rem; color: var(--muted); margin-top: 2px; }
.dash-stat.warn .n { color: var(--danger); }
.dash-block-title { font-weight: 700; color: var(--deep); margin: 22px 0 10px; font-size: var(--fs-subtitle); }
.dash-row {
  display: flex; align-items: center; gap: 12px; background: var(--card); border: 1px solid var(--line);
  border-radius: 12px; padding: 10px 12px; margin-bottom: 10px; box-shadow: var(--shadow); flex-wrap: wrap;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
@media (hover: hover) { .dash-row:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(28,95,125,0.14); } }
@media (prefers-reduced-motion: reduce) { .dash-row { transition: none; } }
.dash-row .pth { width: 46px; height: 46px; border-radius: 10px; background: var(--bg-alt); display: flex; align-items: center; justify-content: center; font-size: 1.1rem; flex-shrink: 0; overflow: hidden; }
.dash-row .pth img { width: 100%; height: 100%; object-fit: cover; }
.dash-row .pinfo { flex: 1; min-width: 120px; }
.dash-row .pn { font-weight: 700; color: var(--deep); font-size: 0.95rem; }
.dash-row .pmeta { font-size: 0.78rem; color: var(--muted); }
.dash-row .pstock { font-size: 0.82rem; font-weight: 700; white-space: nowrap; }
.dash-row .pstock.ok { color: #2e9b57; }
.dash-row .pstock.low { color: var(--danger); }
.dash-pbtn {
  padding: 7px 12px; border-radius: 9px; border: 1px solid var(--line); background: transparent; color: var(--accent);
  font-weight: 600; font-size: var(--fs-button-secondary); cursor: pointer; font-family: inherit; white-space: nowrap;
}
.dash-pbtn.edit { background: var(--accent); color: #fff; border-color: var(--accent); }
.dash-chip-status { font-size: 0.72rem; font-weight: 700; padding: 3px 10px; border-radius: 999px; white-space: nowrap; background: var(--accent); color: #fff; }
.dash-chip-status.status-pending { background: #fff4e0; color: #8a5a00; }
.dash-chip-status.status-done { background: #e6f7ee; color: #1a6b3f; }
.dash-chip-status.status-cancelled { background: rgba(201,79,79,0.15); color: var(--danger); }
.dash-cta-btn { margin-bottom: 22px; padding: 12px 20px; }
.dash-eye-btn { border: none; background: none; cursor: pointer; font-size: 0.85rem; margin-left: 4px; padding: 2px; opacity: 0.65; vertical-align: -1px; }
.dash-eye-btn:hover { opacity: 1; }
.dash-sales-unlock { display: flex; gap: 8px; align-items: flex-start; margin: -10px 0 14px; max-width: 360px; }
.dash-sales-unlock .btn-secondary { flex-shrink: 0; margin-top: 1px; }

/* Pedidos del admin: mismo look de fila (.pth/.pinfo/.pn/.pmeta/
   .dash-chip-status, de arriba) + tarjeta colapsable con nombre propio
   (.dash-order-card, no .order-card) para no tocar el componente que ya
   usa "Mis pedidos" (cliente). */
.dash-order-card {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px; margin-bottom: 10px;
  box-shadow: var(--shadow); overflow: hidden; transition: box-shadow .18s ease, border-color .18s ease;
}
@media (hover: hover) { .dash-order-card:hover { box-shadow: 0 12px 28px rgba(28,95,125,0.14); } }
@media (prefers-reduced-motion: reduce) { .dash-order-card { transition: none; } }
.dash-order-summary {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px; cursor: pointer; list-style: none;
  flex-wrap: wrap; -webkit-tap-highlight-color: transparent;
}
.dash-order-summary::-webkit-details-marker { display: none; }
.dash-order-summary::marker { content: ""; }
.dash-order-card[open] .dash-order-summary { border-bottom: 1px solid var(--line); }
.dash-order-details { padding: 12px; }

/* Filtro por pagar / realizados en la lista de pedidos */
.order-filter { display: flex; gap: 8px; margin-bottom: 14px; }

/* Vistas de página completa: cuenta y administrador (reemplazan al popup) */
.page-view { min-height: 60vh; padding: 32px 0 60px; }
.page-view-wrap { max-width: 640px; margin: 0 auto; padding: 0 16px; }
.page-view-wrap-wide { max-width: 1100px; }
.back-link {
  display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem;
  color: var(--accent); text-decoration: none; margin-bottom: 20px;
}
.back-link:hover { text-decoration: underline; }

/* Cabecera de los popups de cuenta / admin */
.account-header { text-align: center; margin-bottom: 18px; }
.account-header-icon {
  width: 52px; height: 52px; border-radius: 999px; background: var(--bg-alt); color: var(--deep);
  display: flex; align-items: center; justify-content: center; font-size: 1.4rem; margin: 0 auto 12px;
}
.account-header-admin .account-header-icon { background: var(--accent); color: #fff; }
/* El h3 de "Mi cuenta" (saludo ya logueado, o "Creá tu cuenta"/"Bienvenido de
   nuevo" antes de loguearse) es el título de esa pantalla completa, no un
   encabezado secundario — por eso usa el mismo tamaño que .h-title/.hero h2. */
#account-content h3 { margin: 0 0 4px; font-size: var(--fs-title); font-family: 'Fraunces', Georgia, serif; }
.account-header-sub { color: var(--muted); font-size: var(--fs-paragraph); margin: 0; }
/* Nota: Contacto/Empresa/Distribuidores/Código de ética tienen su propio
   <style> inline en cada .html (así se armaron desde el principio) — sus
   títulos/subtítulos/párrafos se ajustan ahí, no acá, porque esas reglas
   locales siempre ganan por orden de cascada. */

/* Portón de entrada del admin: overlay fijo de pantalla completa, igual a la maqueta */
.login-gate { position: fixed; inset: 0; z-index: 80; background: linear-gradient(160deg, var(--bg-alt), var(--panel)); display: grid; place-items: center; padding: 20px; }
/* Mismo fondo que la landing (Configuración > Fondos e imágenes) — a
   diferencia del hero (que fluye en la página y usa "contain" para no
   recortar la foto), acá es un overlay fijo a pantalla completa, así que
   "cover" es lo que la llena de punta a punta sin franjas vacías. */
.login-gate.has-image {
  background-image: var(--hero-img-desktop); background-size: cover; background-position: center;
  background-repeat: no-repeat; background-color: var(--bg-alt);
}
.login-gate.has-image::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(160deg, rgba(255,255,255,0.55), rgba(255,255,255,0.82));
}
@media (max-width: 767px) {
  .login-gate.has-image.has-mobile-image { background-image: var(--hero-img-mobile); background-position: center top; }
}
.login-card {
  position: relative;
  background: var(--card); border: 1px solid var(--line); border-radius: 18px;
  box-shadow: 0 18px 50px rgba(28,95,125,0.18); padding: 30px 26px; width: 100%; max-width: 360px; text-align: center;
}
.login-card .lbrand { font-family: 'Fraunces', Georgia, serif; font-size: var(--fs-title); color: var(--deep); margin-bottom: 2px; }
.login-card .lsub { color: var(--muted); font-size: var(--fs-paragraph); margin-bottom: 18px; }
.login-card input, .login-card .pw-wrap { margin: 6px 0; }
.login-card .error-text { text-align: left; }
.login-card .btn-primary { margin-top: 10px; }

/* Configuración > Colores: paletas prearmadas + selectores finos */
.theme-group-label { font-size: 0.76rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 8px; }
.theme-preset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 10px; margin-bottom: 16px; }
.theme-preset-btn {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 6px;
  border: 2px solid var(--line); border-radius: 12px; background: var(--panel); cursor: pointer;
  font-family: inherit; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
@media (hover: hover) { .theme-preset-btn:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(28,95,125,0.14); } }
@media (prefers-reduced-motion: reduce) { .theme-preset-btn { transition: none; } }
.theme-preset-btn.active { border-color: var(--accent); }
.theme-preset-swatch { display: flex; border-radius: 999px; overflow: hidden; border: 1px solid rgba(0,0,0,0.08); }
.theme-preset-swatch span { width: 14px; height: 22px; }
.theme-preset-name { font-size: 0.76rem; font-weight: 600; color: var(--text); }
.theme-picker-row { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 14px; }
.theme-picker-row .field { margin-bottom: 0; display: flex; flex-direction: column; gap: 5px; }
.theme-picker-row input[type=color] { width: 52px; height: 38px; padding: 2px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); cursor: pointer; }

/* Grupos de campos (ej: perfil de cliente) */
.field-group-title {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--accent); font-weight: 600;
  margin: 18px 0 10px; padding-top: 14px; border-top: 1px solid var(--line);
}
.field-group-title:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.field-row { display: grid; grid-template-columns: 1fr; gap: 10px; margin-bottom: 12px; }
@media (min-width: 480px) { .field-row { grid-template-columns: 1fr 1fr 1fr; } }
.field-row .field { margin-bottom: 0; }
