.hbp-project-grid { display:grid; grid-template-columns:repeat(var(--hbp-project-columns,3),minmax(0,1fr)); gap:28px; font-family:var(--font-body,Archivo,sans-serif); }
.hbp-project-card { min-width:0; }
.hbp-project-card img { width:100%; aspect-ratio:4/3; object-fit:cover; border-radius:12px; }
.hbp-project-card a { color:inherit; text-decoration:none; }
.hbp-project-card h3 { margin:16px 0 10px; font-family:var(--font-display,Archivo,sans-serif); font-size:clamp(22px,2vw,30px); }
.hbp-project-card p { margin:0; line-height:1.5; }
.hbp-project-card a:focus-visible,.hbp-media-play:focus-visible { outline:3px solid currentColor; outline-offset:5px; }
/* Alto por padding-top en vez de aspect-ratio: dentro de un carrusel de Elementor, el ancho del slide
   lo fija JS después de la carga, y aspect-ratio puede no tener todavía un ancho del que partir. El
   truco del padding-top solo necesita el ancho del contenedor, así que no depende de ese timing. */
.hbp-media { position:relative; width:100%; height:0; padding-top:56.25%; border-radius:12px; overflow:hidden; background:#151515; color:white; }
.hbp-media.hbp-media-portrait { padding-top:177.7778%; }
.hbp-media.hbp-media-square { padding-top:100%; }
.hbp-media :is(iframe,video) { position:absolute; inset:0; width:100%;height:100%;border:0;display:block;object-fit:cover; }
.hbp-media img { position:absolute; inset:0; width:100%!important;height:100%!important;object-fit:cover;display:block; }
.hbp-media-play { position:absolute;inset:0; width:100%; height:100%; padding:0; border:0; border-radius:0; background:#151515; cursor:pointer; color:white; }
.hbp-media-play-symbol { position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:#e72b2b;color:white;width:56px;height:56px;display:grid;place-items:center;border-radius:50%;font-size:23px; }
.hbp-media-setup { position:absolute;inset:auto 12px 12px;background:#111d;padding:10px;font:14px/1.4 sans-serif; }
.hbp-media-mute { position:absolute; right:12px; bottom:12px; width:34px; height:34px; border-radius:50%; border:0; background:#00000080; color:#fff; display:grid; place-items:center; cursor:pointer; padding:0; }
.hbp-media-mute .i-on { display:none; }
.hbp-media-mute[aria-pressed="true"] .i-on { display:block; }
.hbp-media-mute[aria-pressed="true"] .i-off { display:none; }
.hbp-media-mute:focus-visible { outline:3px solid currentColor; outline-offset:3px; }
.hbp-media-zoom { position:absolute; inset:0; width:100%; height:100%; padding:0; border:0; border-radius:0; background:transparent; cursor:zoom-in; }
.hbp-lightbox { position:fixed; inset:0; background:#000000e0; display:grid; place-items:center; padding:28px; z-index:9999; }
.hbp-lightbox img { max-width:100%; max-height:100%; border-radius:8px; display:block; }
.hbp-lightbox-close { position:absolute; top:18px; right:18px; width:42px; height:42px; border-radius:50%; border:0; background:#ffffff26; color:#fff; font-size:22px; line-height:1; cursor:pointer; }
.hbp-lightbox-close:focus-visible { outline:3px solid currentColor; outline-offset:3px; }
/* El carrusel nativo de Elementor (Swiper) fija swiper-wrapper/swiper-slide a height:100% de su
   contenedor. Sin una "Altura" fija cargada en el widget, ese contenedor no tiene alto propio, así
   que el 100% de nada da 0 y el carrusel desaparece. Nuestra caja .hbp-media ya trae su alto real
   (padding-top), así que le pedimos al carrusel que se ajuste a ese contenido en vez de heredarlo. */
.e-n-carousel:has(.hbp-media) .swiper-wrapper,
.e-n-carousel:has(.hbp-media) .swiper-slide { height:auto; }
@media(max-width:900px){.hbp-project-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media(max-width:600px){.hbp-project-grid{grid-template-columns:1fr;}}
