/* ============================================================
   Dental — Home. Secciones propias de esta página; los componentes
   compartidos (nav, tags, botones, tarjeta de producto) viven en
   world.style.css, cargado siempre.

   Rediseño 2026-08-11 — "Desfile de vitrinas": referencia real pineada
   por el usuario (sprintray.com) — reemplaza el mundo "dos carriles" de
   la pasada anterior. Un producto real por sección a pantalla completa,
   fondo alternando ink/navy/degradado, titulares enormes, fotografía
   dramática con resplandor de estudio, botones outline (nunca sólidos,
   salvo el CTA de cierre). Ver DESIGN.md para el registro completo.

   Sistema "Vitrinas" (2026-08-19) — reemplaza el hero + vitrina de equipo
   de abajo por hasta 5 bloques 100% configurables desde admin/vitrinas
   (ver views/partials/showcase-render.template.php). Fase 1: 1 diapositiva
   estática, fondo sólido, capas de texto/imagen posicionadas en % — el
   carrusel real (Swiper) llega en la Fase 3. Ver project.md "Spec: Sistema
   Vitrinas".
   ============================================================ */

/* Cierra el espacio estructural entre el nav y la primera vitrina — solo
   en home (pedido explícito del usuario, 2026-08-23: ".dh-nav-offset" es
   compartida con catálogo/producto/cuenta/etc., así que se sobrescribe
   acá en vez de tocar el valor global). El nav mide ~72.2px reales; el
   offset genérico deja 76px (4.75rem) para cubrir casos con nav más alto
   en otras páginas — en home sobra ~4px que se sumaban a los ~5px que ya
   se veían de la propia vitrina, dejando el hueco visible reportado. */
body.page-home .dh-nav-offset {
  padding-top: calc(4.75rem - 5px);
}

/* El fondo (.dh-showcase-block) se extiende todo lo que haga falta a lo
   ancho — la proporción real de la vitrina ya no vive acá (2026-08-24,
   pedido explícito del usuario), vive en .dh-showcase-container de abajo,
   así el fondo nunca fuerza una franja más alta/baja de lo que el
   contenido necesita. Sin aspect-ratio ni height propios: como
   .dh-showcase-container es su único hijo en flujo normal (nunca
   position:absolute), el bloque se ajusta automáticamente a la altura
   real del contenedor. */
.dh-showcase-block {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--dh-ink);
}

/* Contenedor del contenido (2026-08-20, proporción 16:9/4:3 desde
   2026-08-24) — .dh-showcase-layer se posiciona en % relativo a ESTE
   .container (mismo max-width que ya usa el resto del sitio:
   .dh-cat-grid-section/.dh-shelf-section), no al ancho completo de la
   sección — así el texto/imagen/botón de una vitrina queda alineado con
   el resto de los elementos de la página en pantallas anchas. La misma
   proporción 16:9 (escritorio) / 4:3 (pantallas chicas) que usa el lienzo
   del editor admin — lo que el staff arma ahí se ve igual acá (WYSIWYG
   real, no una aproximación). Fase 1 no tiene todavía una vista de
   "pantallas pequeñas" en el editor (ver Próximos pasos) — el cambio de
   proporción en mobile es deliberado para que el texto no quede minúsculo
   en una franja demasiado ancha, pero significa que la posición en % de
   una capa puede leerse un poco distinto en mobile de lo que se vio al
   editar en desktop. */
/* container-type:inline-size (2026-08-20) — hace de este elemento la
   referencia real para las unidades `cqw` que usa dh_showcase_fluid_size()
   (app/helpers.function.php) y el botón de abajo — texto/botón/imagen
   relativos al ancho real de la vitrina, nunca un tamaño fijo. `cqw` en
   vez de `vw` a propósito: el lienzo del editor admin NO ocupa el 100%
   del viewport real (comparte columna con sidebar+panel), así que `vw`
   ahí calcularía mal — `cqw` resuelve correcto en los dos lados con la
   misma fórmula porque cada uno mide su propio contenedor real, ver
   showcase-canvas-container en showcase-editor.template.php. */
.dh-showcase-container { position: relative; aspect-ratio: 16 / 9; container-type: inline-size; }
@media (max-width: 767.98px) {
  .dh-showcase-container { aspect-ratio: 4 / 3; }
}

/* Construcción independiente para escritorio y móvil (2026-08-19) — cada
   diapositiva imprime sus 2 lienzos completos siempre (ver
   showcase-render.template.php::dh_render_showcase_slide()), el CSS decide
   cuál se ve, mismo breakpoint que el aspect-ratio de arriba. Nunca los dos
   a la vez ni JS de por medio — el swap es tan simple como el del
   aspect-ratio. */
.dh-showcase-layers--mobile { display: none; }
@media (max-width: 767.98px) {
  .dh-showcase-layers--desktop { display: none; }
  .dh-showcase-layers--mobile { display: block; }
}
.dh-showcase-layer { position: absolute; box-sizing: border-box; }
.dh-showcase-layer-text { color: var(--dh-bone); }
.dh-showcase-layer-text h1, .dh-showcase-layer-text h2, .dh-showcase-layer-text h3,
.dh-showcase-layer-text h4, .dh-showcase-layer-text h5 {
  margin: 0 0 1rem; font-family: var(--dh-display); line-height: 1.1; font-weight: 700;
}
.dh-showcase-layer-text div { margin: 0 0 .75rem; line-height: 1.6; }
/* Subtítulo (2026-08-19) — tamaño/peso intermedio entre título y párrafo,
   etiqueta fija (nunca h1-h5, a diferencia del título) para que no compita
   con la jerarquía semántica de la página. */
.dh-showcase-layer-text .dh-showcase-layer-subtitle {
  margin: 0 0 .75rem; line-height: 1.35; font-weight: 500;
  font-size: 1.25rem; opacity: .85;
}
.dh-showcase-layer-image img { display: block; width: 100%; height: auto; }

/* Botones de Vitrinas (2026-08-19) — independientes (capa propia,
   posicionada libre) o dentro de un contenedor de texto (flujo normal, sin
   posición absoluta). Colores por --btn-* (ver
   app/helpers.function.php::showcase_button_attrs()) para no generar un
   <style> nuevo por cada botón solo por la regla :hover. */
.dh-showcase-layer-text .dh-showcase-btn { margin-top: .5rem; }
/* Tamaño relativo al ancho real de la vitrina (2026-08-20), mismo criterio
   y misma fórmula que dh_showcase_fluid_size() del lado PHP (referencia
   1140px, piso 70%/techo 130%) — acá a mano porque el tamaño del botón no
   es un campo editable por diapositiva, es parte fija del sistema de
   diseño (nunca .75rem/1.75rem/1rem literal, escala con `cqw` igual que
   el texto de al lado). */
.dh-showcase-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: clamp(8.4px, calc(12 / 1140 * 100cqw), 15.6px) clamp(19.6px, calc(28 / 1140 * 100cqw), 36.4px);
  font-weight: 600; font-size: clamp(11.2px, calc(16 / 1140 * 100cqw), 20.8px);
  text-decoration: none; line-height: 1.2; white-space: nowrap;
  border-radius: .375rem; border: 2px solid transparent;
  background: var(--btn-bg); color: var(--btn-text);
  transition: background-color .2s ease, color .2s ease, border-color .2s ease,
              transform .2s ease, box-shadow .2s ease, background-position .4s ease;
}
/* background-color, no el shorthand background — el shorthand resetea
   background-image/-position a su valor inicial si no se repiten en la
   misma declaración, lo que apagaría el degradado de .is-gradient en cada
   hover (bug real detectado antes de publicar, no en teoría: la regla de
   abajo se aplica a TODOS los presets por especificidad más baja, incluido
   gradient). */
.dh-showcase-btn:hover { background-color: var(--btn-hover-bg); color: var(--btn-hover-text); }
.dh-showcase-btn.is-pill { border-radius: 999px; }
.dh-showcase-btn.is-outline { background: transparent; color: var(--btn-bg); border-color: var(--btn-bg); }
.dh-showcase-btn.is-outline:hover { background: var(--btn-hover-bg); color: var(--btn-hover-text); border-color: var(--btn-hover-bg); }
.dh-showcase-btn.is-ghost { background: transparent; color: var(--btn-bg); border-color: transparent; }
.dh-showcase-btn.is-ghost:hover { background: var(--btn-hover-bg); color: var(--btn-hover-text); }

/* Presets ampliados (2026-08-19, pedido del usuario — "muchas opciones de
   botones con sus respectivas transiciones y formas", referencia:
   cssgradient.io/gradient-backgrounds/ → galería de botones con relleno
   degradado). Cada uno con su propia transición de hover, no la misma
   regla reutilizada 5 veces. */

/* Degradado — tile al doble de ancho (background-size:200%), listo para
   que el efecto "shift" deslice la posición (ver .is-hover-shift más
   abajo) — un solo degradado, nunca dos backgrounds superpuestos. Sin
   comportamiento de hover propio: lo decide is-hover-*, no el relleno. */
.dh-showcase-btn.is-gradient {
  /* sin color acá — .dh-showcase-btn ya lo pone (línea de base), y
     redeclararlo acá con la misma especificidad que .dh-showcase-btn:hover
     ganaba el empate por orden de aparición y anulaba el cambio de color al
     pasar el mouse (bug real detectado en revisión, no en teoría). */
  background: var(--btn-gradient); background-size: 200% auto; background-position: 0% 50%;
  border-color: transparent;
}

/* Efecto de hover — DESACOPLADO del color/forma (2026-08-19, corrección:
   "en la referencia hay muchos botones, cada uno con su color y
   diferentes efectos hover" — antes todo botón degradado compartía el
   mismo efecto fijo sin importar el color elegido). Solo aplica a los
   presets rellenos (solid/pill-solid/gradient/pill-gradient, ver
   showcase_button_attrs()) — 'swap' no necesita regla propia, ya es el
   comportamiento base de .dh-showcase-btn:hover de arriba. */
.dh-showcase-btn.is-hover-shift:hover { background-position: 100% 50%; }
.dh-showcase-btn.is-hover-scale:hover { transform: scale(1.06); }
.dh-showcase-btn.is-hover-lift:hover { transform: translateY(-3px); box-shadow: 0 8px 20px rgba(0, 0, 0, .25); }
.dh-showcase-btn.is-hover-glow:hover { box-shadow: 0 0 22px rgba(var(--btn-bg-rgb), .65); }
.dh-showcase-btn.is-hover-sweep { position: relative; overflow: hidden; }
.dh-showcase-btn.is-hover-sweep::before {
  content: ''; position: absolute; top: 0; left: -60%; width: 40%; height: 100%;
  background: rgba(255, 255, 255, .35); transform: skewX(-20deg); transition: left .5s ease;
}
.dh-showcase-btn.is-hover-sweep:hover::before { left: 120%; }

/* Suave — fondo del mismo color a baja opacidad (rgba real vía --btn-bg-rgb,
   no un hex con alfa que el navegador no siempre soporta igual en todas
   las propiedades), se levanta con sombra al pasar el mouse. */
.dh-showcase-btn.is-soft {
  background: rgba(var(--btn-bg-rgb), .14); color: var(--btn-bg); border-color: transparent;
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease, color .15s ease;
}
.dh-showcase-btn.is-soft:hover {
  background: var(--btn-hover-bg); color: var(--btn-hover-text);
  transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, .18);
}

/* Vidrio — translúcido con blur, se aclara al pasar el mouse (pensado para
   ir sobre una imagen/fondo con contraste, no sobre un color plano). */
.dh-showcase-btn.is-glass {
  /* sin color acá, mismo motivo que .is-gradient más arriba: .dh-showcase-btn
     ya lo pone y redeclararlo acá anulaba el cambio de color al pasar el
     mouse por empate de especificidad con .dh-showcase-btn:hover. */
  background: rgba(255, 255, 255, .12); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-color: rgba(255, 255, 255, .35);
  transition: background-color .2s ease, border-color .2s ease;
}
.dh-showcase-btn.is-glass:hover { background: rgba(255, 255, 255, .22); border-color: rgba(255, 255, 255, .6); }

/* Subrayado — solo texto, sin fondo/borde, una línea crece desde el centro
   al pasar el mouse (::after en vez de border-bottom, para que la línea
   pueda animar su ancho sin mover el layout del texto). */
.dh-showcase-btn.is-underline {
  background: transparent; border-color: transparent; color: var(--btn-bg);
  padding-left: .25rem; padding-right: .25rem; position: relative;
}
.dh-showcase-btn.is-underline::after {
  content: ''; position: absolute; left: 50%; bottom: 2px; width: 0; height: 2px;
  background: var(--btn-hover-bg); transition: width .25s ease, left .25s ease;
}
.dh-showcase-btn.is-underline:hover { color: var(--btn-hover-bg); background: transparent; }
.dh-showcase-btn.is-underline:hover::after { width: calc(100% - .5rem); left: .25rem; }
@media (prefers-reduced-motion: reduce) {
  .dh-showcase-btn.is-soft:hover { transform: none; }
  .dh-showcase-btn.is-hover-scale:hover,
  .dh-showcase-btn.is-hover-lift:hover { transform: none; }
  .dh-showcase-btn.is-hover-sweep::before { transition: none; display: none; }
}

/* Carrusel real (Swiper.js, 2026-08-19) — solo presente en el DOM cuando
   type='carousel' y hay 2+ diapositivas activas (ver
   showcase-render.template.php); swiper-bundle.min.css/.js se cargan
   condicionados a lo mismo (ver HomeController). .dh-showcase-block ya
   trae el aspect-ratio/overflow — acá solo el tema visual de Swiper. */
.dh-showcase-carousel { --swiper-theme-color: var(--dh-bone); --swiper-navigation-size: 22px; }
.dh-showcase-carousel .swiper-button-prev,
.dh-showcase-carousel .swiper-button-next {
  width: 44px; height: 44px; background: rgba(0, 0, 0, .35); border-radius: 999px;
  backdrop-filter: blur(4px);
}
.dh-showcase-carousel .swiper-button-prev:after,
.dh-showcase-carousel .swiper-button-next:after { font-size: 16px; font-weight: 700; }
.dh-showcase-carousel .swiper-pagination-bullet { background: var(--dh-bone); opacity: .5; }
.dh-showcase-carousel .swiper-pagination-bullet-active { opacity: 1; }

/* Subrayado decorativo SVG dentro de una vitrina (plugins/svg_marker_showcase,
   2026-08-19) — mismas reglas que .dh-product-description en world.style.css
   (@keyframes draw-svg-marker vive ahí, cargado siempre en el sitio público,
   no hace falta redefinirlo acá), solo cambia el selector de scope. El SVG
   nunca se persiste en DB, lo inyecta site.function.js (selector global
   .animated-marker, sin scope — recoge estos marcadores sin cambios). */
.dh-showcase-layer-text .animated-marker {
  position: relative;
  display: inline;
  --marker-color: currentColor;
  z-index: 0;
}
.dh-showcase-layer-text .svg-marker {
  position: absolute;
  left: 0;
  bottom: -5px;
  width: 100%;
  height: 14px;
  overflow: visible;
  pointer-events: none;
  z-index: -1;
}
.dh-showcase-layer-text .svg-marker--style5,
.dh-showcase-layer-text .svg-marker--style6 {
  top: -22%;
  bottom: auto;
  left: -20%;
  width: 140%;
  height: 148%;
}
.dh-showcase-layer-text .svg-marker path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: none;
}
.dh-showcase-layer-text .animated-marker.is-visible .svg-marker path {
  animation: draw-svg-marker .65s cubic-bezier(.4, 0, .2, 1) forwards;
}
@media (prefers-reduced-motion: reduce) {
  .dh-showcase-layer-text .animated-marker.is-visible .svg-marker path { animation: none; stroke-dashoffset: 0; }
}

/* ── Hero: dos columnas — copy+CTA a la izquierda, producto real a la
   derecha (rediseño pineado por captura de referencia, ver DESIGN.md;
   reemplaza el hero centrado de una sola columna de la pasada anterior). */
.dh-hero {
  position: relative;
  min-height: calc(100vh - 4.75rem);
  display: flex;
  align-items: center;
  color: var(--dh-bone);
  overflow: hidden;
  padding: 3.5rem 0;
}
/* Color de fondo editable desde admin/inicio (2026-08-18, ver
   AdminHomeContentController) — presets con los mismos tokens/proporciones
   que ya usa .dh-showcase, nunca un color libre bajo este tipo (ver
   DESIGN.md "Restrained"; color sólido/degradado/imagen libres son otros
   tipos de fondo, ver home_section_bg_attrs() en helpers.function.php).
   El resplandor rojo radial es decorativo fijo, no forma parte de la
   variante de color. 'panel'/'wine' agregados 2026-08-19 (control total de
   fondo) — 'wine' reutiliza el token que DESIGN.md documentaba "sin
   consumidor desde 2026-08-11". */
.dh-hero.is-bg-navy     { background: radial-gradient(60% 70% at 78% 45%, rgba(200, 30, 44, .16), transparent 65%), linear-gradient(180deg, var(--dh-navy) 0%, var(--dh-ink) 55%); }
.dh-hero.is-bg-ink      { background: radial-gradient(60% 70% at 78% 45%, rgba(200, 30, 44, .16), transparent 65%), linear-gradient(180deg, var(--dh-ink) 0%, var(--dh-ink-warm) 55%); }
.dh-hero.is-bg-gradient { background: radial-gradient(60% 70% at 78% 45%, rgba(200, 30, 44, .16), transparent 65%), linear-gradient(180deg, var(--dh-navy) 0%, var(--dh-navy-deep) 55%); }
.dh-hero.is-bg-panel    { background: radial-gradient(60% 70% at 78% 45%, rgba(200, 30, 44, .16), transparent 65%), var(--dh-panel); }
.dh-hero.is-bg-wine     { background: radial-gradient(60% 70% at 78% 45%, rgba(200, 30, 44, .16), transparent 65%), linear-gradient(180deg, var(--dh-ink) 0%, var(--dh-wine) 100%); }
.dh-hero-inner {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  align-items: center;
  gap: 3rem;
}
.dh-hero-copy { max-width: 34rem; }
.dh-hero-heading {
  font-family: var(--dh-display);
  font-weight: 700;
  font-size: clamp(2.4rem, 4.6vw, 4rem);
  line-height: 1.03;
  letter-spacing: -0.03em;
  margin: 0 0 1.25rem;
}
.dh-hero-heading em {
  font-style: normal;
  color: var(--dh-red-bright);
}
.dh-hero-sub {
  font-size: clamp(1rem, 1.2vw, 1.1rem);
  line-height: 1.6;
  color: var(--dh-bone-dim);
  max-width: 44ch;
  margin: 0 0 2rem;
}
.dh-hero-actions {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
  margin-bottom: 1.75rem;
}
.dh-hero-actions .dh-btn-primary { border-radius: var(--dh-radius-pill); }

.dh-hero-figure {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 380px;
}
.dh-hero-figure::before {
  content: '';
  position: absolute;
  inset: 6%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(200, 30, 44, .32), transparent 70%);
  filter: blur(10px);
  z-index: 0;
}
.dh-hero-figure img {
  position: relative;
  z-index: 1;
  max-width: 90%;
  max-height: 58vh;
  object-fit: contain;
  filter: drop-shadow(0 32px 48px rgba(0, 0, 0, .55));
}
.dh-hero-badge {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--dh-mono);
  font-size: var(--dh-fs-xs);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--dh-bone-dim);
  margin-top: 1rem;
}
.dh-hero-badge strong { color: var(--dh-bone); font-weight: 600; }
.dh-hero-badge .is-out { color: var(--dh-bone-dim); }
.dh-hero-badge .is-in { color: var(--dh-success); }

@media (max-width: 861px) {
  .dh-hero-inner { grid-template-columns: 1fr; text-align: center; }
  .dh-hero-copy { max-width: none; margin: 0 auto; }
  .dh-hero-sub { max-width: none; margin-left: auto; margin-right: auto; }
  .dh-hero-actions { justify-content: center; }
  .dh-hero-figure { order: -1; margin-bottom: 1rem; min-height: 260px; }
}

/* ── Categorías: grid circular con imagen real del admin (referencia:
   captura pineada por el usuario, layout tipo sprintray.com) ────────── */
.dh-cat-grid-section {
  /* Plano, no degradado — es la sección gris de la referencia (bloque
     sólido, sin transición). `--dh-ink` es ahora el gris principal del
     sitio (ver world.style.css) — ya no hace falta un token aparte. */
  background: var(--dh-ink);
  color: var(--dh-bone);
  padding: 6rem 0;
  text-align: center;
}
.dh-cat-grid-heading {
  font-family: var(--dh-display);
  font-weight: 700;
  font-size: clamp(2.2rem, 4.4vw, 3.4rem);
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 0 auto .9rem;
}
.dh-cat-grid-sub {
  font-size: 1.05rem;
  color: var(--dh-bone-dim);
  max-width: 56ch;
  margin: 0 auto 3.5rem;
  line-height: 1.6;
}
.dh-cat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2.5rem 1.5rem;
}
@media (max-width: 767.98px) {
  .dh-cat-grid { grid-template-columns: repeat(3, 1fr); gap: 1.75rem 1rem; }
}
@media (max-width: 479.98px) {
  .dh-cat-grid { grid-template-columns: repeat(2, 1fr); }
}
.dh-cat-grid-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .9rem;
  text-decoration: none;
  color: inherit;
}
.dh-cat-grid-item-img {
  width: 7.5rem;
  height: 7.5rem;
  border-radius: 50%;
  overflow: hidden;
  background: var(--dh-panel);
  border: 1px solid var(--dh-panel-line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--dh-icon-muted);
  font-size: 1.6rem;
  transition: border-color .2s ease, transform .25s cubic-bezier(.16,1,.3,1);
}
.dh-cat-grid-item:hover .dh-cat-grid-item-img,
.dh-cat-grid-item:focus-visible .dh-cat-grid-item-img {
  border-color: var(--dh-red);
  transform: translateY(-4px);
}
.dh-cat-grid-item-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  transition: filter .25s ease;
}
.dh-cat-grid-item:hover .dh-cat-grid-item-img img,
.dh-cat-grid-item:focus-visible .dh-cat-grid-item-img img {
  filter: grayscale(0);
}
.dh-cat-grid-item-name {
  font-family: var(--dh-mono);
  font-size: var(--dh-fs-sm);
  color: var(--dh-bone-dim);
  letter-spacing: .01em;
  transition: color .2s ease;
}
.dh-cat-grid-item:hover .dh-cat-grid-item-name,
.dh-cat-grid-item:focus-visible .dh-cat-grid-item-name {
  color: var(--dh-bone);
}
/* Stagger corto, tope en el 6º ítem — mismo criterio que .dh-shelf-row. */
.dh-cat-grid .dh-reveal:nth-child(1) { animation-delay: 0ms; }
.dh-cat-grid .dh-reveal:nth-child(2) { animation-delay: 60ms; }
.dh-cat-grid .dh-reveal:nth-child(3) { animation-delay: 120ms; }
.dh-cat-grid .dh-reveal:nth-child(4) { animation-delay: 180ms; }
.dh-cat-grid .dh-reveal:nth-child(5) { animation-delay: 240ms; }
.dh-cat-grid .dh-reveal:nth-child(n+6) { animation-delay: 300ms; }
@media (prefers-reduced-motion: reduce) {
  .dh-cat-grid .dh-reveal { animation-delay: 0ms; }
}

/* ── Vitrina de producto: una por sección, imagen/texto alternando ──── */
.dh-showcase {
  position: relative;
  min-height: 88vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: 5rem 0;
}
.dh-showcase-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3.5rem;
  align-items: center;
}
.dh-showcase.is-reversed .dh-showcase-inner { direction: rtl; }
.dh-showcase.is-reversed .dh-showcase-text,
.dh-showcase.is-reversed .dh-showcase-photo { direction: ltr; }

.dh-showcase-text { color: var(--dh-bone); max-width: 34rem; }
.dh-showcase-heading {
  font-family: var(--dh-display);
  font-weight: 700;
  font-size: clamp(2.4rem, 4.6vw, 4rem);
  line-height: .98;
  letter-spacing: -0.03em;
  margin: 0 0 1rem;
}
.dh-showcase-tagline {
  font-size: 1.15rem;
  color: var(--dh-bone-dim);
  line-height: 1.55;
  margin: 0 0 .6rem;
}
.dh-showcase-desc {
  font-size: .95rem;
  color: var(--dh-bone-dim);
  line-height: 1.65;
  margin: 0 0 1.75rem;
  max-width: 40ch;
}
.dh-showcase-meta {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin-bottom: 1.75rem;
  font-family: var(--dh-mono);
}
.dh-showcase-price {
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--dh-bone);
}
.dh-showcase-stock {
  font-size: var(--dh-fs-xs);
  letter-spacing: .05em;
  text-transform: uppercase;
}
.dh-showcase-stock.is-in { color: var(--dh-success); }
.dh-showcase-stock.is-out { color: var(--dh-bone-dim); }
.dh-showcase-cta { border-radius: var(--dh-radius-pill); }

.dh-showcase-photo {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 380px;
}
.dh-showcase-photo::before {
  content: '';
  position: absolute;
  inset: 8%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(200, 30, 44, .28), transparent 72%);
  filter: blur(6px);
  z-index: 0;
}
.dh-showcase-photo img {
  position: relative;
  z-index: 1;
  max-width: 85%;
  max-height: 62vh;
  object-fit: contain;
  filter: drop-shadow(0 30px 42px rgba(0, 0, 0, .55));
}

/* Alternancia de fondo entre vitrinas (referencia real: sprintray.com
   alterna negro/marino/degradado marino-violeta sección a sección) —
   siempre degradados tonales, nunca color plano, para que cada vitrina
   tenga la misma profundidad de estudio fotográfico que su producto. */
.dh-showcase.is-bg-navy { background: linear-gradient(160deg, var(--dh-navy) 0%, var(--dh-ink) 100%); }
.dh-showcase.is-bg-ink { background: linear-gradient(160deg, var(--dh-ink) 0%, var(--dh-ink-warm) 100%); }
.dh-showcase.is-bg-gradient { background: linear-gradient(160deg, var(--dh-navy) 0%, var(--dh-navy-deep) 100%); }
.dh-showcase.is-bg-panel { background: var(--dh-panel); }
.dh-showcase.is-bg-wine { background: linear-gradient(160deg, var(--dh-ink) 0%, var(--dh-wine) 100%); }

@media (max-width: 861px) {
  .dh-showcase { min-height: auto; padding: 4rem 0; }
  .dh-showcase-inner,
  .dh-showcase.is-reversed .dh-showcase-inner {
    grid-template-columns: 1fr;
    direction: ltr;
  }
  .dh-showcase-photo { order: -1; margin-bottom: 1rem; min-height: 280px; }
  .dh-showcase-text { max-width: none; text-align: center; margin: 0 auto; }
  .dh-showcase-desc { max-width: none; margin-left: auto; margin-right: auto; }
  .dh-showcase-meta { justify-content: center; }
}

/* ── Estante de resinas ───────────────────────────────────────────── */
.dh-shelf-section {
  background: linear-gradient(180deg, var(--dh-ink) 0%, var(--dh-navy) 100%);
  color: var(--dh-bone);
  padding: 6rem 0;
  text-align: center;
}
.dh-shelf-heading {
  font-family: var(--dh-display);
  font-weight: 700;
  font-size: clamp(2.2rem, 4.4vw, 3.4rem);
  letter-spacing: -0.02em;
  line-height: 1.05;
  max-width: 22ch;
  margin: 0 auto .9rem;
}
.dh-shelf-sub {
  font-size: 1.05rem;
  color: var(--dh-bone-dim);
  max-width: 56ch;
  margin: 0 auto 3.5rem;
  line-height: 1.6;
}
.dh-shelf-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  margin-bottom: 2.5rem;
}
@media (max-width: 767.98px) {
  .dh-shelf-row { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
}
.dh-shelf-bottle {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-decoration: none;
  color: inherit;
  padding: 1.5rem 1rem;
  background: var(--dh-panel);
  border: 1px solid var(--dh-panel-line);
  border-radius: var(--dh-radius-md);
  transition: transform .25s cubic-bezier(.16,1,.3,1), border-color .25s ease;
}
.dh-shelf-bottle:hover {
  transform: translateY(-6px);
  border-color: var(--dh-panel-line);
  color: inherit;
}
.dh-shelf-bottle-img {
  height: 220px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1rem;
}
.dh-shelf-bottle-img img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 16px 20px rgba(0, 0, 0, .5));
  transition: transform .3s cubic-bezier(.16,1,.3,1);
}
.dh-shelf-bottle:hover .dh-shelf-bottle-img img { transform: scale(1.04); }
.dh-shelf-bottle-brand {
  font-family: var(--dh-mono);
  font-size: var(--dh-fs-2xs);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--dh-red-bright);
  margin-bottom: .3rem;
}
.dh-shelf-bottle-name {
  font-family: var(--dh-display);
  font-weight: 600;
  font-size: .98rem;
}
/* Stagger corto (criterio Emil Kowalski: 30-80ms entre ítems, nunca más
   — un desfase largo se siente lento). */
.dh-shelf-row .dh-reveal:nth-child(1) { animation-delay: 0ms; }
.dh-shelf-row .dh-reveal:nth-child(2) { animation-delay: 70ms; }
.dh-shelf-row .dh-reveal:nth-child(3) { animation-delay: 140ms; }
.dh-shelf-row .dh-reveal:nth-child(4) { animation-delay: 210ms; }
@media (prefers-reduced-motion: reduce) {
  .dh-shelf-row .dh-reveal { animation-delay: 0ms; }
}

/* ── Marcas (sin cambios de fondo/comportamiento respecto a la pasada
   anterior — marquee real, grayscale→color al hover) ────────────── */
.dh-brands {
  background: var(--dh-panel);
  border-radius: var(--dh-radius-md);
  margin: 0 auto 2rem;
  max-width: 1320px;
  padding: 1.75rem 0;
  overflow: hidden;
}
.dh-brands-label {
  font-size: .68rem;
  color: var(--dh-bone-dim);
  text-transform: uppercase;
  letter-spacing: .08em;
  text-align: center;
  margin: 0 0 1.25rem;
}
.dh-brands-track-wrap {
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%);
}
.dh-brands-track {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  width: max-content;
  animation: dh-brands-scroll 26s linear infinite;
}
.dh-brands-track:hover { animation-play-state: paused; }
@keyframes dh-brands-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.dh-brand-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 128px;
  height: 64px;
  background: var(--dh-bone);
  border-radius: var(--dh-radius-sm);
  padding: .75rem 1.1rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
  transition: transform .2s cubic-bezier(.16,1,.3,1), box-shadow .2s cubic-bezier(.16,1,.3,1);
}
.dh-brand-chip:hover,
.dh-brand-chip:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, .35);
}
.dh-brand-chip img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  filter: grayscale(100%);
  opacity: .7;
  transition: opacity .2s ease, filter .2s ease;
}
.dh-brand-chip:hover img,
.dh-brand-chip:focus-visible img {
  filter: grayscale(0%);
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .dh-brands-track { animation: none; flex-wrap: wrap; justify-content: center; width: 100%; }
  .dh-brands-track [aria-hidden="true"] { display: none; }
}
