/*
 * Tema "default" — hoja de estilos COMPLETA e independiente de @dogtrack/ads-render.
 * El aspecto de referencia: el diseño actual de la librería, el que se ve si no
 * se pide nada en particular. Hoy coincide con `light`; son ficheros distintos a
 * propósito, para que `light` pueda evolucionar como una variante clara concreta
 * sin mover lo que ve quien solo quería "el diseño de la librería".
 *
 * Un tema no depende de ningún CSS base ni del reset del host: contiene todo lo
 * que los formatos necesitan (base, layout, tamaños, transiciones y colores).
 * El consumidor carga exactamente uno, y cambiarlo sustituye el aspecto entero,
 * no solo los colores.
 *
 * Para crear un tema nuevo, copia este fichero y cambia lo que quieras: puedes
 * tocar tamaños, z-index o el layout, no solo los colores.
 *
 * NO tocar los nombres de clase ni de las transiciones (`bubble-tab-fade-*`):
 * los ponen las plantillas de los componentes.
 *
 * OJO con `bubble` y `page-fold`: el layout de esos formatos —posición y tamaño
 * de la bolita, deslizamiento del panel y quién captura los toques en el
 * primero; capas, geometría del doblez y su despliegue en el segundo— lo ponen
 * los propios BubbleAd.vue y PageFoldAd.vue como CSS base, parametrizado por
 * props (`bubbleTop`, `--page-fold-reveal-delay`). El tema NO lo repite: aquí
 * solo va el ASPECTO (fondos, sombras, formas). Si escribes reglas de layout,
 * ganarás al componente —el CSS del componente se inyecta el primero en el
 * <head>— y romperás el formato.
 */

/* ==========================================================================
   Base — lo que en otra librería pondría el reset del host
   ========================================================================== */

/*
 * Sin esto el tema NO es independiente: heredaría del host la tipografía y la
 * alineación, y dejaría al navegador el `box-sizing` y los defaults de <button>
 * (que ni siquiera hereda la fuente). El mismo tema se vería distinto en cada
 * consumidor, y la demo mentiría sobre cómo queda.
 *
 * Alcanza a los tres árboles que montan los formatos —`.bubble-ad` en el slide,
 * `.bubble-ad-overlay` teletransportado a <body>, y `.page-fold`— y a nada más:
 * el CSS es global, así que no tocamos nada del host.
 *
 * Todo va envuelto en `:where()`, que aporta especificidad CERO: cualquier regla
 * de las de abajo lo gana sin depender del orden, y quien copie este fichero
 * para hacerse un tema no tiene que pelearse con la base.
 */

/*
 * Heredadas: se fijan solo en la RAÍZ de cada formato. Ahí cortan la herencia
 * del host, y de la raíz hacia dentro heredan como es debido — si se pusieran
 * en cada elemento, un `text-align` puesto en un contenedor del tema ya no
 * llegaría a su texto.
 */
:where(.bubble-ad, .bubble-ad-overlay, .page-fold) {
    font-family: Arial, sans-serif;
    font-size: 16px;
    font-style: normal;
    font-weight: normal;
    line-height: normal;
    text-align: start;
}

/* No heredadas: hay que darlas elemento a elemento. */
:where(
    .bubble-ad, .bubble-ad *,
    .bubble-ad-overlay, .bubble-ad-overlay *,
    .page-fold, .page-fold *
) {
    box-sizing: border-box;
    margin: 0;
}

/* Los <button> no heredan la tipografía del contenedor: hay que dársela. */
:where(.bubble-ad, .bubble-ad-overlay, .page-fold) button {
    font: inherit;
    color: inherit;
    text-align: inherit;
}

/* ==========================================================================
   BubbleTrigger — la bolita
   ========================================================================== */

.bubble-tab {
    padding: 2px;
    border: none;
    background-color: rgba(255, 255, 255, 0.8);
    backdrop-filter: blur(10px);
    box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.3);
    cursor: pointer;
}

/* Pestaña del borde derecho (móvil). El tamaño lo pone el componente. */
.bubble-tab--pill {
    border-right: 8px solid transparent;
    border-radius: 50px 0 0 50px;
}

/* Círculo. El tamaño lo pone el componente. */
.bubble-tab--ball {
    border-radius: 50%;
}

.bubble-tab__img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-size: cover;
    background-position: center;
}

.bubble-tab__badge {
    position: absolute;
    bottom: 2px;
    right: -5px;
    font-family: Arial, sans-serif;
    font-size: 8px;
    font-weight: bold;
    color: #000;
}

.bubble-tab--ball .bubble-tab__badge {
    right: 3px;
}

/* ==========================================================================
   BubbleAd — contenedor de la bolita (móvil y desktop)
   ========================================================================== */

/* El layout del formato en el slide —bolita, contenedor deslizante, tarjeta del
   panel y el fundido de la bolita— es del componente: `.bubble-ad`,
   `.bubble-ad-container`, `.bubble-ad-slide`, `.bubble-ad__card`, `.bubble-tab`
   y `.bubble-tab-fade-*`. Aquí solo va el overlay de desktop, que el componente
   no toca. */

.bubble-ad-overlay__panel,
.bubble-ad-overlay__close {
    pointer-events: auto;
}

/* ---------- DESKTOP: overlay teletransportado a <body> ---------- */

.bubble-ad-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    pointer-events: none;
}

/* Fondo translúcido + desenfoque, cubre todo el viewport. */
.bubble-ad-overlay .bubble-ad-overlay__backdrop {
    position: fixed;
    inset: 0;
    background: rgba(255, 255, 255, 0.8);
    backdrop-filter: blur(10px);
    opacity: 0;
    transition: opacity 0.8s;
    pointer-events: none;
}

.bubble-ad-overlay.is-open .bubble-ad-overlay__backdrop {
    opacity: 1;
    pointer-events: auto;
}

/* Botón de cerrar arriba a la derecha del overlay. */
.bubble-ad-overlay .bubble-ad-overlay__close {
    position: fixed;
    top: 24px;
    right: 24px;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    cursor: pointer;
    opacity: 1;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
    transition:
        opacity 0.2s ease-in-out,
        background-color 0.2s ease,
        box-shadow 0.2s ease,
        transform 0.2s ease;
}

.bubble-ad-overlay .bubble-ad-overlay__close:not(.is-disabled):hover {
    background: #000;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
    transform: scale(1.08);
}

.bubble-ad-overlay .bubble-ad-overlay__close:not(.is-disabled):active {
    transform: scale(0.96);
}

.bubble-ad-overlay .bubble-ad-overlay__close:focus-visible {
    outline: 2px solid #000;
    outline-offset: 3px;
}


.bubble-ad-overlay:not(.is-open) .bubble-ad-overlay__close {
    opacity: 0;
    pointer-events: none;
}

.bubble-ad-overlay .bubble-ad-overlay__close.is-disabled {
    opacity: 0.3;
    cursor: default;
}

.bubble-ad-overlay .bubble-ad-overlay__stage {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.8s;
    pointer-events: none;
}

.bubble-ad-overlay.is-open .bubble-ad-overlay__stage {
    opacity: 1;
    pointer-events: auto;
}

/* Tarjeta con formato teléfono, centrada sobre el overlay. */
.bubble-ad-overlay .bubble-ad-overlay__card {
    position: relative;
    height: min(90vh, 640px);
    max-width: 90vw;
    aspect-ratio: 9 / 16;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35);
}

/* ---------- El overlay dentro de una caja del host (`overlayTarget`) -------- */
/* Cuando el plugin teletransporta el overlay a un contenedor en vez de a
   <body>, deja de tener sentido medir contra el viewport: lo que estaba
   `fixed` pasa a `absolute` y las medidas en vh/vw a porcentajes del
   contenedor. Ese contenedor debe traer `position: relative`. */

.bubble-ad-overlay.bubble-ad-overlay--contained,
.bubble-ad-overlay.bubble-ad-overlay--contained .bubble-ad-overlay__backdrop,
.bubble-ad-overlay.bubble-ad-overlay--contained .bubble-ad-overlay__stage,
.bubble-ad-overlay.bubble-ad-overlay--contained .bubble-ad-overlay__close {
    position: absolute;
}

.bubble-ad-overlay.bubble-ad-overlay--contained .bubble-ad-overlay__card {
    height: min(90%, 640px);
    max-width: 90%;
}

/* ==========================================================================
   BubblePanel — el panel tipo story
   ========================================================================== */

/*
 * Alto de la cabecera del panel: su padding (22 + 20) más lo que mide dentro
 * (el logo, 40px). Lo consumen el `object-position` de los medias y las zonas
 * de navegación, así que si tocas el padding de `.bubble-panel__header` o el
 * tamaño de `.bubble-panel__logo`, actualiza este número.
 *
 * Va en las dos raíces del formato porque el panel de móvil vive en el slide
 * (`.bubble-ad`) y el de escritorio se teletransporta al overlay.
 */
.bubble-ad,
.bubble-ad-overlay {
    --bubble-panel-header-height: 82px;
}

.bubble-panel {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: #000;
}

.bubble-panel__header {
    position: absolute;
    top: 0px;
    left: 0;
    right: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 22px 12px 20px;
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.55) 0%,
        rgba(0, 0, 0, 0) 100%
    );
}

.bubble-panel__brand {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.bubble-panel__logo {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: 50%;
    background-size: cover;
    background-position: center;
}

/* Las dos líneas de la marca: "Ofrecido por X" y la etiqueta de debajo. */
.bubble-panel__brand-lines {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    min-width: 0;
}

.bubble-panel__brand-text {
    color: #ffffff;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Etiqueta de producto: pastilla translúcida bajo la marca. */
.bubble-panel__brand-note {
    max-width: 100%;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    color: rgba(255, 255, 255, 0.92);
    font-size: 10px;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bubble-panel__close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    min-width: 26px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    color: #ffffff;
    cursor: pointer;
    opacity: 1;
    transition: opacity 0.2s ease-in-out;
}

.bubble-panel__close.is-disabled {
    opacity: 0.3;
    cursor: default;
}

.bubble-panel__progress {
    position: absolute;
    top: 8px;
    left: 12px;
    right: 12px;
    z-index: 6;
}

.bubble-panel__nav {
    position: absolute;
    top: calc(var(--bubble-panel-header-height, 82px) + 5px);
    bottom: 110px;
    width: 28%;
    z-index: 3;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
}

.bubble-panel__nav--prev {
    left: 0;
}

.bubble-panel__nav--next {
    right: 0;
}

/* Con una galería debajo, estas zonas no pueden capturar: el carrusel se
   arrastra y el gesto necesita empezar en cualquier punto, no solo en la franja
   central que dejan libre. Siguen ocupando lo mismo —el panel las mide para
   saber dónde cayó un toque suelto—, así que su tamaño se cambia aquí como
   siempre y el paso de frame lo sigue. */
.bubble-panel--gallery .bubble-panel__nav {
    pointer-events: none;
}

/* ==========================================================================
   AdFrameView — un frame: media + texto + CTA
   ========================================================================== */

.ad-frame {
    position: absolute;
    inset: 0;
}

/* z-index por encima del media: el primer plano del AdMedia va con z-index 1 y,
   al ser hermano posicionado del footer, lo tapaba (el texto y el CTA quedaban
   debajo). Por debajo de la cabecera (5) y de las barras de progreso (6). */
.ad-frame__footer {
    position: absolute;
    z-index: 4;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 70px 20px 28px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    text-align: center;
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.55) 55%,
        rgba(0, 0, 0, 0) 100%
    );
    pointer-events: none;
}

.ad-frame__text {
    margin: 0;
    color: #ffffffd3;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.25;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
}

/* ---------- Texto plegable: 2 líneas y botón para desplegar --------------
   El clamp vive en el <p>, no en la caja: `display: -webkit-box` no convive
   con ser flex item de basis 0 —el ancho colapsa y el texto desaparece bajo
   `overflow: hidden`—. La caja lleva el sizing y el clic. */

.ad-frame__text-wrap {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    align-self: stretch;
    text-align: left;
}

.ad-frame__text-box {
    flex: 1;
    min-width: 0;
}

/* Solo capta el toque cuando hay algo que plegar o desplegar: si el texto cabe
   entero, los toques siguen pasando al panel de debajo. */
.ad-frame__text-box--toggleable {
    pointer-events: auto;
    cursor: pointer;
}

.ad-frame__text--clamped {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.ad-frame__text-toggle {
    pointer-events: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-bottom: 2px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.35);
    color: #ffffff;
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.ad-frame__cta {
    pointer-events: auto;
    padding: 12px 28px;
    border: none;
    border-radius: 999px;
    background: #ffffff;
    color: #111111;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    cursor: pointer;
    transition: transform 0.15s ease;
}

.ad-frame__cta:active {
    transform: scale(0.96);
}

/* ==========================================================================
   AdProgress — barras de progreso tipo story
   ========================================================================== */

/* El color de relleno lo pone el componente en línea (option `accentColor`). */

.ad-progress {
    display: flex;
    gap: 4px;
    width: 100%;
}

.ad-progress__bar {
    flex: 1;
    height: 3px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.35);
    overflow: hidden;
}

.ad-progress__fill {
    height: 100%;
    width: 0;
    border-radius: 2px;
    transition: width 0.1s linear;
    background: #ffffff !important;
}

/* ==========================================================================
   Formato de los medias — data-ad-format / data-ad-fit
   ========================================================================== */

/*
 * Los medias del anuncio (`.ad-image`, `.ad-video`, y cualquier elemento que
 * use `useMediaFormat`) se miden solos y publican en el HTML qué son y cómo
 * quieren colocarse. Los pone el componente, igual que los nombres de clase:
 * aquí solo se seleccionan.
 *
 *   data-ad-format  vertical | square | horizontal   qué es el media
 *   data-ad-fit     cover | contain                  cómo se coloca
 *   data-ad-ready   0 | 1                            0 = aún sin medir
 *   data-ad-crop    0..1                             recorte que asume el cover
 *
 * DECISIÓN DE ESTE TEMA: el media llena SIEMPRE la pantalla (`cover`), y lo que
 * se coloca debajo de la cabecera es su contenido, con `object-position`: la
 * caja va de borde a borde —por eso el `cover` se calcula contra la pantalla
 * entera— pero el objeto arranca justo debajo de la cabecera, con 5px de aire.
 * Lo que queda por encima lo tapa el fondo borroso, que sí va a pantalla
 * completa.
 *
 * Por eso estas reglas no miran `data-ad-fit`: el sistema sigue midiendo y
 * dejando en el HTML lo que HABRÍA elegido, pero el aspecto lo manda el tema.
 * Como efecto secundario, el primer pintado (`data-ad-ready="0"`) ya sale bien:
 * es el mismo aspecto.
 *
 * Para volver a la decisión automática, añade debajo:
 *   .ad-image[data-ad-fit='contain'],
 *   .ad-video[data-ad-fit='contain'] { object-fit: contain }
 */
.ad-image,
.ad-video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center calc(var(--bubble-panel-header-height, 82px) + 5px);
}

/* En una galería, NO. Ahí la banda ya mide lo que mide el media y está colocada
   donde toca, así que no queda hueco que repartir: bajar el contenido otra vez
   lo saca de su caja, y lo que sobresale de un `object-fit` se recorta. Era esto
   lo que cortaba las imágenes por abajo. */
.ad-gallery .ad-image,
.ad-gallery .ad-video {
    object-position: center;
}

/* ==========================================================================
   AdMedia — switch image | video | gallery
   ========================================================================== */

/* De borde a borde, cabecera incluida: el fondo borroso tiene que cubrir toda la
   pantalla, y el `cover` del primer plano se calcula contra ella. Que el
   contenido del media arranque debajo de la cabecera lo hace su
   `object-position` (arriba). */
.ad-media {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: #000;
}

/* Capa de fondo: el mismo media en cover y borroso, para rellenar el hueco
   que deja el primer plano en contain. El scale evita que el blur deje los
   bordes transparentes. La usan el <div> (imagen) y el <video> de detrás. */
.ad-media__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    display: block;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    /* El fondo es la excepción a la regla de arriba: aquí SÍ se recorta y se
       centra, que para eso es un relleno borroso. */
    object-fit: cover;
    object-position: center;
    filter: blur(24px) brightness(0.7) saturate(1.2);
    transform: scale(1.15);
    pointer-events: none;
}

/* Primer plano: encima del fondo borroso. Cómo se coloca dentro (recortado o
   completo) lo dicen sus data-ad-*, arriba. */
.ad-media__img,
.ad-media__video {
    position: relative;
    z-index: 1;
    background: transparent;
}

.ad-media__empty {
    width: 100%;
    height: 100%;
    background: #1a1a1a;
}

/* ==========================================================================
   AdVideo — <video> MP4 nativo
   ========================================================================== */

/* El tamaño y el ajuste van con el resto de los medias, arriba. */
.ad-video {
    background: #000;
}

/* Dentro del AdMedia el negro del <video> taparía el fondo borroso. */
.ad-video.ad-media__bg,
.ad-video.ad-media__video {
    background: transparent;
}

/* ==========================================================================
   AdGallery — carrusel nativo
   ========================================================================== */

/* Solo el ASPECTO. La geometría (el track, los slides al 100%, el recorte y qué
   captura el gesto) la pone AdGallery.vue como CSS base: aquí no se repite,
   porque el tema ganaría al componente y rompería el carrusel.

   Lo que este tema SÍ decide, sin repetir geometría: el fondo, dónde van los
   puntos y cómo se ven, y las tres medidas que el componente lee de variables
   —`--ad-gallery-slide-ms` (velocidad), `--ad-gallery-peek` (margen lateral por
   el que asoman los items de al lado) y `--ad-gallery-gap` (separación entre
   items)—, todas sobre `.ad-gallery`. */

.ad-gallery {
    background: #000;
    /* En % para que el margen sea el mismo a ojo en un móvil estrecho y en la
       tarjeta del overlay de escritorio. */
    --ad-gallery-peek: 6%;
    --ad-gallery-gap: 10px;
    /* El hueco donde se centran la banda y sus puntos: de debajo de la cabecera
       al borde de abajo. Sin el padding de arriba, una galería que no llena la
       pantalla se centraría por detrás de la cabecera. En iPhone con barra de
       gestos, el de abajo la respeta. */
    padding-top: var(--bubble-panel-header-height, 82px);
    padding-bottom: 12px;
    padding-bottom: max(12px, env(safe-area-inset-bottom, 0px));
}

/* Pegados debajo de la imagen, centrados. Por encima del degradado del footer
   (z-index 4), que si no los apaga; el footer no captura toques, así que siguen
   siendo pulsables. */
.ad-gallery__dots {
    position: relative;
    z-index: 5;
    margin-top: 10px;
    display: flex;
    justify-content: center;
    gap: 6px;
}

/* El punto dibujado. Su zona de toque es mayor (la pone el componente), así que
   se puede dejar pequeño sin que cueste acertar. */
.ad-gallery__dot {
    width: 6px;
    height: 6px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.45);
    cursor: pointer;
    transition: 0.2s;
}

.ad-gallery__dot.is-active {
    background: #ffffff;
    transform: scale(1.3);
}

/* ---------- Galería ancha: el texto se va arriba -------------------------
 *
 * Una galería vertical llena la pantalla de arriba abajo y el texto solo cabe
 * encima del media, al pie: es la disposición de siempre y no cambia nada.
 *
 * Una galería cuadrada, casi cuadrada (4:5) u horizontal no llega a llenarla, y
 * deja una franja libre arriba y otra abajo. Ahí el texto sube a la de arriba y
 * el CTA se queda en la de abajo, con el carrusel en medio.
 *
 * Cuál de las dos es lo dice el componente en `data-ad-gallery-shape` (`wide` /
 * `tall`) sobre el `.ad-media`, mirando el formato del conjunto. Mientras no ha
 * podido medir no hay atributo y vale lo de siempre, así que el primer pintado
 * nunca sale roto. */

/* La banda ya se centra sola en el hueco (lo hace el CSS base con el formato
   medido); aquí solo se le reserva abajo el sitio del CTA, para que los puntos
   no acaben pisándolo.

   Y se le pide que ceda alto cuando el texto de arriba se despliega: lo que el
   texto crece (`--ad-frame-text-extra`, que publica el AdFrameView) es lo que
   la banda encoge. El hueco sale POR ARRIBA —el mismo padding lo baja—, que es
   hacia donde crece el texto: así el borde de abajo de la banda, los puntos y
   el CTA se quedan donde estaban. Con tope, para que un texto muy largo no deje
   la imagen en nada. */
.ad-media[data-ad-gallery-shape='wide'] .ad-gallery {
    --ad-gallery-shrink: min(var(--ad-frame-text-extra, 0px), 160px);
    padding-top: calc(
        var(--bubble-panel-header-height, 82px) + var(--ad-gallery-shrink)
    );
    padding-bottom: 64px;
    transition: padding-top var(--ad-gallery-slide-ms, 300ms) ease;
}

/* De barra al pie a columna de lado a lado: el texto arriba, el CTA abajo.
   Sin degradado, porque lo que hay detrás del texto ya es el fondo del media.
   Sigue sin capturar toques (lo hacen sus hijos), así que el carrusel se puede
   arrastrar por debajo. */
.ad-media[data-ad-gallery-shape='wide'] ~ .ad-frame__footer {
    top: 0;
    padding-top: calc(var(--bubble-panel-header-height, 82px) + 14px);
    background: none;
}

/* El CTA se va abajo con `margin-top: auto` y no con un `space-between` en la
   columna: sin texto, el `space-between` lo dejaría arriba. */
.ad-media[data-ad-gallery-shape='wide'] ~ .ad-frame__footer .ad-frame__cta {
    margin-top: auto;
}

/* Arriba el texto va a la izquierda, y el botón de desplegar deja de ser el `+`
   redondo de al lado: pasa a ser un "Leer más" pequeño DEBAJO del texto.
   `column-reverse` lo manda abajo sin tocar la plantilla (el botón va primero en
   el HTML, para que al tabular se llegue antes al mando que al párrafo). */
.ad-media[data-ad-gallery-shape='wide'] ~ .ad-frame__footer .ad-frame__text-wrap {
    flex-direction: column-reverse;
    align-items: flex-start;
    gap: 4px;
    text-align: left;
}

/* Con `flex: 1` en una columna de alto automático el párrafo se quedaría en
   nada: aquí mide lo que ocupe, a todo lo ancho. */
.ad-media[data-ad-gallery-shape='wide'] ~ .ad-frame__footer .ad-frame__text-box {
    flex: 0 0 auto;
    align-self: stretch;
}

/* El mismo botón de siempre —conserva el clic y el `aria-expanded`—, con otra
   pinta: se apaga su glifo con `font-size: 0` y la etiqueta la pone el `::after`,
   que además puede cambiar según esté plegado o no. */
.ad-media[data-ad-gallery-shape='wide'] ~ .ad-frame__footer .ad-frame__text-toggle {
    width: auto;
    height: auto;
    margin-bottom: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    background: none;
    font-size: 0;
    text-decoration: underline;
}

.ad-media[data-ad-gallery-shape='wide'] ~ .ad-frame__footer .ad-frame__text-toggle::after {
    content: 'Leer más';
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    color: rgba(255, 255, 255, 0.75);
}

.ad-media[data-ad-gallery-shape='wide']
    ~ .ad-frame__footer
    .ad-frame__text-toggle[aria-expanded='true']::after {
    content: 'Leer menos';
}

/* ==========================================================================
   PageFoldAd — doblez de página
   ========================================================================== */

/* Solo el ASPECTO del doblez. La geometría (el cuadrado de `--page-fold-size`,
   los clip-path y el despliegue) la pone PageFoldAd.vue como CSS base: aquí no
   se repite, porque el tema ganaría al componente y rompería el formato.

   Con dos excepciones, que un tema SÍ puede tocar porque no repiten geometría:
   el tamaño del doblez, redeclarando `--page-fold-size` sobre `.page-fold` (todo
   lo demás va en % y escala solo), y la velocidad del despliegue, con
   `transition-duration` sobre las capas. El retardo no: lo pone el componente
   desde su prop (`--page-fold-reveal-delay`).

   Todas las capas son el mismo cuadrado del lado del doblez, así que aquí los
   porcentajes (tamaño de la imagen, paradas de los degradados) se miden sobre
   ese lado. */

/* --- Fondo del papel revelado ---
   Debajo de la imagen: sin esto el triángulo es transparente y se ve el slide a
   través del doblez, que se carga el efecto de papel levantado. OPACO a
   propósito.

   El componente lo pasa en `--page-fold-back-color`: el `color` que declare el
   anuncio si lo trae, y si no blanco (la detección del fondo en la propia imagen
   está comentada hoy en PageFoldAd.vue). El literal de aquí es el respaldo del
   respaldo: lo que se ve antes de que el componente diga nada.

   Va con `background` y no con `background-color` porque el `color` del anuncio
   admite cualquier valor de la propiedad, degradados incluidos: con
   `background-color` un `linear-gradient(…)` sería un valor inválido y la capa
   se quedaría TRANSPARENTE, que es justo lo que esta capa existe para evitar. */
.page-fold__back {
    background: var(--page-fold-back-color, #ffffff);
}

/* --- Imagen revelada ---
   `.page-fold__image` es la imagen dentro del triángulo, y su caja depende del
   `type` que declare el anuncio (`data-ad-image-type` en la raíz).

   Las medidas van sobre el lado del doblez, que es lo que mide la caja que llega
   del componente. Este es el único sitio donde se toca el tamaño de la imagen;
   cambiarlo no afecta a la geometría del doblez. */

/* `image`, y cualquier `type` que no se reconozca: la imagen llena el cuadrado
   entero, así que el triángulo la parte por la diagonal y no queda ni una
   esquina sin cubrir. `cover` y no `100%`, que es ancho 100% y alto `auto`: con
   una imagen apaisada dejaría vacía toda la parte de arriba. */
.page-fold__image {
    background-size: cover;
    background-repeat: no-repeat;
    background-position: left bottom;
}

/* `logo`: un círculo despegado de los bordes inferior e izquierdo. */
.page-fold[data-ad-image-type='logo'] .page-fold__image {
    /* Aire hasta esos dos bordes. */
    --page-fold-logo-inset: 3px;
    /* El círculo más grande que cabe en el triángulo dejando ese aire: con el
       centro en (inset + r, inset + r) y el pliegue en `x + y = lado`, sale
       r = (lado - 2·inset) / (2 + √2), y el diámetro es (lado - 2·inset) / 1.7071.
       Si roza demasiado el pliegue, sube el divisor y ya. */
    --page-fold-logo-size: calc(
        (var(--page-fold-size) - 2 * var(--page-fold-logo-inset)) / 1.7071
    );

    left: var(--page-fold-logo-inset);
    bottom: var(--page-fold-logo-inset);
    width: var(--page-fold-logo-size);
    height: var(--page-fold-logo-size);
    border-radius: 50%;
    background-size: cover;
    background-position: center;
}

/* --- Sombra sobre la imagen ---
   Capa entre la imagen y la solapa: oscurece la imagen/logo hacia el pliegue,
   como si la solapa levantada le hiciera sombra. El degradado va a 45° (de la
   esquina inf. izquierda hacia la sup. derecha), perpendicular al pliegue. En un
   cuadrado, el triángulo visible ocupa la primera MITAD de ese eje: el paso de
   transparente a negro arranca en el 32% y se completa un poco antes, en el 52%. */
.page-fold__shade {
    background-image: linear-gradient(
        45deg,
        rgba(0, 0, 0, 0) 32%,
        rgb(0 0 0 / 60%) 52%
    );
}

/* --- Solapa de papel --- */
.page-fold__flap {
    background-color: rgb(9 129 255 / 32%);
    background-image: linear-gradient(
        45deg,
        rgba(150, 150, 150, 0.5) 0%,
        rgba(200, 200, 200, 0.55) 35%,
        rgba(240, 240, 240, 0.65) 70%,
        rgba(255, 255, 255, 0.75) 100%
    );
    filter: drop-shadow(4px 5px 7px rgba(0, 0, 0, 0.3));
}

/* --- Zona interactiva (el cuadrado del doblez) ---
   Solo el cursor: el hit es la última capa y pinta encima de todo, así que
   dejarlo transparente y sin borde es cosa del componente, no del tema. */
.page-fold__hit {
    cursor: pointer;
}
