/*
 Theme Name:   Divi Child - OSCyL Menu
 Theme URI:    https://www.elegantthemes.com/gallery/divi/
 Description:  Child theme de Divi 5 con menú fullscreen responsive (acordeón móvil + columnas desktop), header transparente con estado scrolled, CPT Concierto, CPT Artista, sliders artista↔concierto e importador de artistas (CLI + página admin).
 Author:       abbeto
 Author URI:   https://abbeto.es
 Template:     Divi
 Version:      2.103.1
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Text Domain:  divi-child-oscyl
*/


/* ==========================================================================
   OVERLAY FULLSCREEN — ESTILOS BASE (todas las resoluciones)
   ========================================================================== */

/* ---------- OVERLAY CONTENEDOR ----------
   z-index: 100002 → POR ENCIMA del Divi Theme Builder header (100001).
   Así el beige del overlay cubre todo el viewport cuando está abierto
   y los clicks sobre el botón "✕ Cerrar" llegan al botón (no al header).
   v2.2.6 — antes era 100000 y el header Divi se comía los clicks. */
.oscyl-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #f5f0eb;
  z-index: 100002;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  /* v2.23.5 — Apertura/cierre por opacidad + visibility SIN transición.
     Histórico del bug: el mecanismo anterior animaba transform translateX(100%)→0
     con transition; la CSSTransition se quedaba colgada en estado "running" sin
     completar y dejaba el overlay fuera de pantalla (volado a la derecha). Se probó
     con opacity + transition y el mismo atasco dejaba el overlay a opacity:0
     (invisible aunque presente). Conclusión: CUALQUIER transición CSS sobre este
     overlay se cuelga en este entorno (Divi 5 + el contexto de apilamiento del
     header). Solución definitiva: apertura instantánea (sin transition). El menú
     aparece/desaparece de golpe, sin animación, pero siempre en su sitio y visible. */
  opacity: 0;
  visibility: hidden;
}

.oscyl-overlay.open {
  opacity: 1;
  visibility: visible;
}

/* ---------- NAVEGACIÓN (contenedor de items) ---------- */
.oscyl-menu-nav {
  flex: 1;
  padding: 20px 24px 0;
}

/* ---------- ITEMS DE MENÚ ---------- */
.oscyl-menu-item {
  border-bottom: 1px solid rgba(0,0,0,0.1);
}

.oscyl-menu-item:first-child {
  border-top: 1px solid rgba(0,0,0,0.1);
}

.oscyl-menu-item-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 0;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.oscyl-menu-item-title {
  font-family: var(--oscyl-font-serif);
  font-size: 26px;
  font-weight: 400;
  color: #2a2a2a;
  line-height: 1.2;
  text-decoration: none;
}

/* v2.52.0 — Los títulos de columna sin URL real se emiten como <button> (el
   mando del acordeón en móvil) o como <span>. Al <button> hay que quitarle el
   chrome del control: fondo gris, borde y padding.

   ⚠️ Aquí NO se toca la tipografía, y es deliberado. La hoja del navegador le
   pone al <button> su propia fuente, pero eso es una regla de UA y la regla
   compartida `.oscyl-menu-item-title` (de autor) ya le gana. Declarar aquí
   `font-family: inherit` sería el error: este selector es (0,1,1) y el de
   arriba (0,1,0), así que ganaría — y el título heredaría la sans del
   contenedor en vez de la serif del sistema tipográfico. */
button.oscyl-menu-item-title {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  text-align: left;

  /* v2.80.0 — `default`, no `pointer`.
     En ESCRITORIO este botón no hace nada: el bloque de `min-width: 981px`
     deja el submenú con `max-height: none`, siempre abierto y sin acordeón,
     así que pulsar el título no cambia nada. La mano prometía un clic que no
     existe — es el mismo criterio que la regla de aquí abajo, que reserva el
     hover de enlace para lo que SÍ es un enlace.
     La mano vuelve en móvil, donde el título sí despliega su acordeón. */
  cursor: default;
}

/* El título SÍ es pulsable por debajo de 980px: ahí abre y cierra el acordeón
   (`.oscyl-menu-item.active .oscyl-menu-submenu`). El breakpoint es el mismo
   que separa las dos maquetaciones del overlay, no un número suelto. */
@media (max-width: 980px) {
  button.oscyl-menu-item-title {
    cursor: pointer;
  }
}

/* El hover de enlace solo para lo que ES un enlace. Un título que no navega no
   debe insinuar que se puede pulsar para ir a alguna parte. */
a.oscyl-menu-item-title:hover {
  color: #555;
}

/* ---------- SUBMENÚ LINKS ---------- */
.oscyl-menu-submenu a {
  display: block;
  /* v2.23.17 — separación de 8px entre el texto de un item y el del siguiente
     (ej. "Entradas y Abonos" / "Temporada 26-27"), lo que pide el diseñador.
     Dos cosas contribuían al espacio excesivo:
       1. El LINE-HEIGHT heredado (1.7 ≈ 23.8px sobre 14px) → fix: line-height 1.62.
       2. Un PADDING de 5px que una regla externa (Personalizador/Divi) imponía sobre
          el item, sobrescribiendo nuestro padding → fix: padding 1px con !important
          para que gane. (Sin !important, v2.23.15/16 no surtían efecto: el 5px ganaba.)
     Con line-height 1.62 + padding 1px !important queda exactamente 8px entre textos.
     Verificado en vivo con Chrome DevTools en monitor ancho. */
  padding: 1px 0 !important;
  line-height: 1.62;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 14px;
  font-weight: 300;
  color: #555;
  text-decoration: none;
  transition: color 0.2s ease;
}

.oscyl-menu-submenu a:first-child {
  padding-top: 0;
}

.oscyl-menu-submenu a:last-child {
  padding-bottom: 20px;
}

.oscyl-menu-submenu a:hover {
  color: #1a1a1a;
}

/* ---------- BOTONES CTA ---------- */
.oscyl-menu-ctas {
  display: flex;
  justify-content: center;
  gap: 12px;
  padding: 28px 24px 20px;
}

.oscyl-btn-cta {
  padding: 12px 28px;
  border-radius: 50px;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.5px;
  text-decoration: none;
  transition: all 0.25s ease;
  text-align: center;
}

.oscyl-btn-outline {
  /* v2.45.0 — 1px, antes 1.5px.
     Medio píxel es un valor que cada pantalla resuelve a su manera: el
     navegador lo redondea al pintarlo, así que el mismo botón podía salir a
     1px en una pantalla y a 2px en otra. Se fija a 1px, que además es el valor
     que el cliente configuró en los botones de la home («Conoce la temporada»,
     «Ver toda la programación») y al que van a igualarse los del encabezado.
     Visualmente no cambia nada en pantallas retina, donde ya se pintaba a 1px. */
  border: 1px solid #2a2a2a;
  color: #2a2a2a;
  background: transparent;
}

.oscyl-btn-outline:hover {
  background: #2a2a2a;
  color: #fff;
}

.oscyl-btn-filled {
  border: 1.5px solid #2a2a2a;
  background: #2a2a2a;
  color: #fff;
}

.oscyl-btn-filled:hover {
  background: #444;
  border-color: #444;
}

/* ---------- FOOTER DEL MENÚ ---------- */
.oscyl-menu-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px 30px;
}

.oscyl-social-icons {
  display: flex;
  /* v2.26.6 — 18px → 10px: los iconos se veían muy sueltos en el pie del overlay.
     v2.26.7 — 10px → 6px, a petición del cliente. Con SVG de 22px el bloque de 3
     iconos queda en 78px de ancho (eran 102px con los 18px originales) y cada zona
     pulsable en 28px. No conviene bajar mucho más: a 2px quedarían en 24px, ya en
     el límite de lo cómodo en táctil. */
  gap: 6px;
}

.oscyl-social-icons a {
  color: #2a2a2a;
  transition: opacity 0.2s ease;
  line-height: 1;
}

.oscyl-social-icons a:hover {
  opacity: 0.6;
}

.oscyl-social-icons svg {
  width: 22px;
  height: 22px;
}

.oscyl-institutional-logo img {
  /* v2.26.6 — 50px → 64px (renderiza 113x64 con el ratio 1.763:1 del logo actual).
     El ARCHIVO lo pone el Personalizador (Apariencia → Personalizar → "Logo
     institucional (footer del menú)", theme_mod oscyl_institutional_logo); aquí
     solo se controla el tamaño al que se muestra.
     OJO NITIDEZ: el archivo en uso (Logo-JdCyL.avif) mide solo 134x76 px nativos.
     A 64px de alto en una pantalla retina harían falta 128px de origen, así que se
     ve algo blando. Para que quede nítido hay que subir desde el Personalizador una
     versión de al menos 268x152 px — no requiere tocar este CSS. */
  height: 64px;
  width: auto;
}

/* ---------- ANIMACIÓN DE ENTRADA ---------- */
@keyframes oscylFadeInUp {
  from {
    opacity: 0;
    transform: translateY(15px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.oscyl-overlay.open .oscyl-menu-item {
  animation: oscylFadeInUp 0.4s ease forwards;
  opacity: 0;
}

.oscyl-overlay.open .oscyl-menu-item:nth-child(1) { animation-delay: 0.05s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(2) { animation-delay: 0.1s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(3) { animation-delay: 0.15s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(4) { animation-delay: 0.2s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(5) { animation-delay: 0.25s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(6) { animation-delay: 0.3s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(7) { animation-delay: 0.35s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(8) { animation-delay: 0.4s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(9) { animation-delay: 0.45s; }
.oscyl-overlay.open .oscyl-menu-item:nth-child(10) { animation-delay: 0.5s; }

.oscyl-overlay.open .oscyl-menu-ctas {
  animation: oscylFadeInUp 0.4s ease forwards;
  animation-delay: 0.45s;
  opacity: 0;
}

.oscyl-overlay.open .oscyl-menu-footer {
  animation: oscylFadeInUp 0.4s ease forwards;
  animation-delay: 0.5s;
  opacity: 0;
}

/* ---------- BODY LOCK ---------- */
/* v2.23.5 — Barra de scroll vertical SIEMPRE presente (overflow-y: scroll en html).
   Sin esto, al abrir el menú `body.oscyl-menu-open { overflow: hidden }` elimina la
   scrollbar, el viewport gana ~15px y el contenido del header (logo, botones
   Apóyanos/Programación) se desplaza a la derecha, perdiendo la simetría con la fila
   izquierda del overlay. Reservar la scrollbar de forma permanente mantiene el ancho
   constante con el menú abierto o cerrado. (scrollbar-gutter:stable no servía porque
   el html tiene overflow visible y no es el contenedor de scroll.) */
html {
  overflow-y: scroll;
}

body.oscyl-menu-open {
  overflow: hidden !important;
}

/* ==========================================================================
   ACCESIBILIDAD — Utilidades
   ========================================================================== */

/* Oculta visualmente pero mantiene accesible para lectores de pantalla */
.oscyl-sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Indicador de foco visible consistente (solo con teclado) */
.oscyl-overlay a:focus-visible,
.oscyl-overlay button:focus-visible,
.oscyl-menu-toggle:focus-visible,
.oscyl-close-btn:focus-visible,
#oscylDesktopToggle:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 3px;
  border-radius: 2px;
}

/* v2.23.5 — Sin recuadro de foco en el botón "Cerrar" cuando recibe foco
   PROGRAMÁTICO al abrir el menú (menu.js hace closeBtn.focus()). Chrome dibuja su
   outline nativo de ~3px aunque el botón no matchee :focus-visible, lo que mostraba
   un recuadro feo alrededor de "Cerrar". Se anula el outline en :focus normal y se
   mantiene SOLO en :focus-visible (navegación real por teclado, accesibilidad). */
.oscyl-close-btn:focus {
  outline: none !important;
}

.oscyl-close-btn:focus-visible {
  outline: 2px solid #1a1a1a !important;
  outline-offset: 3px;
}

/* Oculta el outline nativo del overlay (recibe foco por JS al abrir) */
.oscyl-overlay:focus {
  outline: none;
}

/* ==========================================================================
   BOTÓN CERRAR (X + "Cerrar") DEL OVERLAY
   ========================================================================== */

.oscyl-close-btn {
  /* v2.23.5 — Ya NO es position:absolute. Vive dentro de .oscyl-overlay-top
     (fila flex) junto al selector de idioma. El posicionamiento lo da la fila. */
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: transparent;
  border: none;
  color: #2a2a2a;
  cursor: pointer;
  padding: 6px 4px;
  z-index: 10;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.5px;
  text-transform: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.oscyl-close-btn:hover {
  opacity: 0.65;
}

.oscyl-close-btn:active {
  transform: scale(0.97);
}

.oscyl-close-btn svg {
  display: block;
  flex-shrink: 0;
}

.oscyl-close-btn__label {
  line-height: 1;
}

/* En móvil mantenemos el botón un poco más compacto */
@media (max-width: 980px) {
  .oscyl-close-btn {
    top: 18px;
    left: 20px;
    font-size: 13px;
  }
}


/* ==========================================================================
   DESKTOP — Layout columnas (>980px)
   ========================================================================== */

@media (min-width: 981px) {

  /* Overlay desktop: dropdown de ALTURA AUTOMÁTICA (no fullscreen).
     v2.2.4 — El mockup muestra un mega-menú tipo dropdown que solo cubre
     la zona del menú, con la altura del contenido. La sala de conciertos
     queda visible debajo. Por eso quitamos bottom:0 y fijamos max-height. */
  .oscyl-overlay {
    /* v2.23.9 — padding-top 69px (antes 100px) para que el logo del overlay
       quede a la MISMA altura (top:69) que el logo del header normal y no
       "salte" al abrir el menú. El aspa "Cerrar" y los botones suben con él,
       alineándose con el icono de menú y los botones del header normal. */
    padding-top: 69px;
    padding-bottom: 40px;
    bottom: auto;
    height: auto;
    max-height: 100vh;
    overflow-y: auto;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
  }

  /* Grid de columnas: las categorías padre se ponen en fila.
     v2.2.4 — flex: 0 0 auto para que la nav abrace su contenido sin estirarse
     y empujar el footer al final del viewport. El footer queda pegado al
     pie del menú, no del viewport. */
  .oscyl-menu-nav {
    display: flex;
    flex-wrap: nowrap;
    gap: 0;
    /* v2.23.11 — mismo contenedor que la fila superior y el header: max-width 1720px
       centrado + padding 5%. Así las columnas del menú quedan alineadas con el botón
       "Cerrar" y los botones en CUALQUIER ancho (antes, con solo 5%, en pantallas
       >1720px el menú se desalineaba respecto al header limitado a 1720). */
    max-width: 1720px;
    margin: 0 auto;
    padding: 40px 5% 0;
    flex: 0 0 auto;
    align-items: flex-start;
    width: 100%;
    box-sizing: border-box;
  }

  /* Cada categoría padre = columna flexible.
     min-width bajo para que quepan 7 columnas en una sola fila incluso en
     viewports justos (981-1200px). */
  .oscyl-menu-item {
    flex: 1 1 0;
    min-width: 0;
    border-bottom: none;
    border-right: none;
    padding: 0 14px;
  }

  .oscyl-menu-item:first-child {
    border-top: none;
    padding-left: 0;
  }

  .oscyl-menu-item:last-child {
    padding-right: 0;
  }

  /* Header del item: solo título, sin interacción de acordeón */
  .oscyl-menu-item-header {
    padding: 0 0 12px;
    cursor: default;
    /* v2.23.10 — quitada la línea (border-bottom) bajo los títulos de columna. */
    border-bottom: none;
    margin-bottom: 16px;
  }

  .oscyl-menu-item-title {
    /* v2.23.10 — títulos de columna a 43px (antes 22px). */
    font-size: 43px;
  }

  /* Ocultar icono +/- en desktop */
  .oscyl-menu-item-icon {
    display: none;
  }

  /* Submenú siempre visible en desktop, sin acordeón */
  .oscyl-menu-submenu {
    max-height: none !important;
    overflow: visible;
  }

  .oscyl-menu-submenu a {
    padding: 5px 0;
    font-size: 14px;
  }

  .oscyl-menu-submenu a:last-child {
    padding-bottom: 5px;
  }

  /* El título padre que NO tiene hijos también es link clickable */
  a.oscyl-menu-item-title {
    cursor: pointer;
  }

  /* CTAs del overlay: VISIBLES en desktop, posicionados top-right.
     v2.2.6 — El overlay ahora pasa por ENCIMA del Divi Theme Builder header
     (z-index 100002 > 100001), así que los CTAs del header quedan tapados
     por el beige. Volvemos a mostrar los del overlay (son idénticos) y los
     colocamos arriba a la derecha, como en el mockup. */
  .oscyl-menu-ctas {
    display: flex;
    position: absolute;
    /* v2.23.5 — Los botones Apóyanos/Programación del overlay se alinean con la fila
       superior (.oscyl-overlay-top, que arranca en el padding-top 100px del overlay)
       y con el aspa "Cerrar" de la izquierda:
       - top alinea VERTICALMENTE el centro de los botones del overlay con el centro
         de los botones del header de Divi, para que NO "salten" hacia abajo al abrir
         el menú. (v2.23.13: era 107px; v2.23.13 lo dejó en 83px.) Solo se toca la
         posición vertical; el ancho/right no se modifican.
       - OJO — LA REFERENCIA ES LA FILA DEL OVERLAY, NO EL BOTÓN DEL HEADER.
         v2.26.1 bajó este valor a 49px para que el clon no "saltara" respecto al
         botón del header de Divi (que tras reducir su Relleno a 2px quedó centrado
         en y=67). Fue un error: el header queda TAPADO por el overlay, así que esa
         alineación no se ve, y en cambio rompió la que sí se ve — los botones
         quedaron 40px por encima de "Cerrar" y del selector EN/ES.
       - v2.26.2 lo devuelve a la fila del overlay: "Cerrar" está centrado en y=107
         y EN/ES en y=106, así que el clon debe centrarse en ~106. Con los 36px de
         alto que tiene ahora el botón (padding 5px), eso son `top: 88px`
         (106 - 36/2). El valor histórico 83px daba ese mismo centro cuando el
         botón medía 46px (83 + 23 = 106); al cambiar el padding en v2.26.1 había
         que recalcularlo, no moverlo de sitio.
       - Queda un salto de ~39px respecto al botón del header al abrir el menú.
         Es asumido: no se puede alinear con las dos referencias a la vez mientras
         la fila superior del overlay esté más baja que el header. Cerrarlo del todo
         exigiría subir toda la fila (aspa, Cerrar, EN/ES y logo), no solo estos
         botones.
       - right: 5% iguala el margen lateral del aspa (padding-left:5%), de modo que
         izquierda y derecha quedan simétricas en CUALQUIER ancho (verificado a 1241px:
         ambos a 62px). Antes right:60px fijo no coincidía con el 5% del aspa. */
    top: 88px;
    /* v2.23.11 — el right debe coincidir con el borde derecho del contenedor del
       header (max-width 1720px centrado + 5%), NO con el 5% del viewport completo.
       En pantallas >1720px el viewport crece pero el contenido se queda centrado en
       1720, así que un right:5% del viewport dejaba los botones más a la derecha que
       el header (menú "más ancho"). Fórmula: margen de centrado del max-width
       (max(0, (100vw-1720)/2)) + el 5% interno de ese contenedor (5% de 1720 = 86px).
       Con esto los botones caen justo sobre el borde del header en cualquier ancho. */
    right: calc(max(0px, (100vw - 1720px) / 2) + 86px);
    padding: 0;
    gap: 10px;
    z-index: 11;
  }

  .oscyl-menu-ctas .oscyl-btn-cta {
    /* v2.26.1 — de 10px 22px a 5px 18px. El cliente redujo el Relleno vertical de
       los botones del header de Divi a 2px, dejándolos en 35px de alto; con
       10px 22px el clon del overlay medía 46px y se veía claramente más gordo al
       abrir el menú. Con 5px 18px el clon queda en 36px (borde 1.5px x2 +
       line-height 23.8px + 5px x2) y casa con el header. El padding lateral no
       iguala el ancho exacto (el clon lleva letter-spacing 0.5px y borde de 1.5px
       en vez de 2px), pero la diferencia baja de ~30px a ~12px por botón. */
    padding: 5px 18px;
    /* v2.23.12 — tipografía a 16px (antes 12px) para igualar el tamaño de los
       botones del header normal de Divi (que están a 16px). */
    font-size: 16px;
    /* v2.26.3 — el texto del overlay se veía más grande que el del header aunque
       los dos están a 16px: el clon heredaba de .oscyl-btn-cta el peso 500 y un
       letter-spacing de +0.5px, mientras que el header va a peso 300 y -0.02em.
       Sumado, "Entradas" salía 9px más ancho (71.5 vs 62.4) y más grueso. Con
       estos dos valores el ancho renderizado coincide exactamente con el del
       header. Se usa `em` y no px para que siga cuadrando si en el Theme Builder
       se cambia el tamaño de fuente de los botones. Va aquí y NO en la regla base
       .oscyl-btn-cta: por debajo de 981px el header de Divi no se usa y los
       botones del overlay móvil son otro diseño. */
    font-weight: 300;
    letter-spacing: -0.02em;
  }

  /* Footer del overlay: pegado al pie del menú, no del viewport.
     v2.23.11 — padding lateral 5% (antes 60px fijo) para alinear con el resto del
     menú. En >1720px pasa a 86px (ver bloque común más abajo). El valor vertical
     (30px arriba, 10px abajo) se mantiene. */
  .oscyl-menu-footer {
    padding: 30px 5% 10px;
    flex: 0 0 auto;
  }

  /* Ocultar header móvil del child theme en desktop */
  .oscyl-mobile-header {
    display: none !important;
  }

} /* Fin @media min-width: 981px */


/* ==========================================================================
   MÓVIL — Layout acordeón (<=980px)
   ========================================================================== */

@media (max-width: 980px) {

  /* ---------- OCULTAR MENÚ NATIVO DE DIVI ---------- */
  .et_mobile_menu,
  .mobile_menu_bar,
  .et_mobile_nav_menu,
  #et-top-navigation .et_mobile_menu,
  .et_pb_menu__menu--mobile,
  .divi-mobile-menu {
    display: none !important;
  }

  /* ---------- OCULTAR HEADER NATIVO DE DIVI ---------- */
  #main-header,
  .et-l--header {
    display: none !important;
  }

  /* ---------- HEADER MÓVIL CUSTOM ---------- */
  .oscyl-mobile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 20px;
    background: transparent;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100001;
    border-bottom: none;
    transition: background 0.3s ease;
  }

  .oscyl-mobile-header.menu-open {
    background: #f5f0eb;
  }

  /* ---------- v2.90.0 — ESTADO SCROLLED EN MÓVIL ----------
     Hasta ahora NO EXISTÍA. El JS añade `oscyl-scrolled` al body sin mirar el
     ancho —lleva haciéndolo desde siempre— pero **todas** las reglas que la
     usaban estaban dentro de `@media (min-width: 981px)`. En teléfono la clase
     se ponía y no la leía nadie: el encabezado se quedaba transparente con el
     logo y las barras en blanco sobre el contenido de la página.

     Los valores son EXACTAMENTE los del encabezado de escritorio, para que los
     dos se comporten igual. No es un gris plano: es un translúcido con
     desenfoque, que es lo que deja ver el contenido pasando por debajo. */
  body.oscyl-scrolled .oscyl-mobile-header {
    background: rgba(240, 240, 240, 0.72);
    -webkit-backdrop-filter: blur(18px) saturate(1.2);
    backdrop-filter: blur(18px) saturate(1.2);
    box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06);
  }

  /* ⚠️ El menú abierto MANDA sobre el scroll. Su fondo es opaco a propósito
     —el overlay ya cubre la página— y sin esta regla ganaría por orden de
     aparición quien estuviera escrito después, que es justo el tipo de detalle
     que se rompe al reordenar el archivo. Se deja explícito. */
  body.oscyl-scrolled .oscyl-mobile-header.menu-open {
    background: #f5f0eb;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: none;
  }

  .oscyl-header-logo {
    display: flex;
    align-items: center;
    text-decoration: none;
    /* v2.90.0 — contenedor de los dos logos superpuestos. Conserva el alto del
       logo completo para que el encabezado no dé un salto al conmutar. */
    position: relative;
    height: 32px;
  }

  .oscyl-header-logo img {
    height: 32px;
    width: auto;
    display: block;
    transition: opacity 0.35s ease;
  }

  /* ---------- v2.90.0 — CONMUTACIÓN DE LOGOS EN MÓVIL ----------
     Misma idea que el encabezado de escritorio desde la v2.20.4, pero con dos
     `<img>` del propio tema en vez de dos módulos del Theme Builder.

     📐 EL 18px NO ES UN NÚMERO SUELTO. Los dos SVG tienen el MISMO ancho de
     viewBox (438) y distinta altura: 276 el completo y 156 el símbolo. O sea
     que el símbolo es, literalmente, la parte de arriba del logo completo. Con
     el completo a 32px, esa parte mide `32 × 156/276 = 18,1px`.

     Poniéndolo a 18px el símbolo queda del MISMO tamaño y en el MISMO sitio
     que la palabra «OSCYL» del logo grande, así que el cruce se lee como que
     desaparece la línea de «Orquesta Sinfónica de Castilla y León», no como un
     logo que cambia de forma. A 32px mediría 90px de ancho contra los 51 del
     completo: un salto que se vería.

     ⚠️ Por eso va alineado ARRIBA (`top: 0`) y no centrado: es donde está esa
     palabra dentro del logo completo. */
  .oscyl-header-logo__scrolled {
    position: absolute;
    left: 0;
    top: 0;
    height: 18px !important;
    opacity: 0;
    pointer-events: none;
  }

  body.oscyl-scrolled .oscyl-header-logo__normal {
    opacity: 0;
  }

  body.oscyl-scrolled .oscyl-header-logo__scrolled {
    opacity: 1;
  }

  /* 🚨 v2.90.0 — CON EL MENÚ ABIERTO, TAMBIÉN EL LOGO OSCURO. Esto corrige un
     fallo que ya estaba: al abrir el menú el encabezado pasa a `#f5f0eb` y las
     barras y el EN/ES se oscurecen, pero **al logo se le olvidó**. Medido en
     vivo antes de tocarlo: fondo `rgb(245,240,235)` y el logo BLANCO a
     opacidad 1, sin filtro. O sea, invisible sobre su propio fondo.

     No saltaba porque el logo blanco sobre un beige claro no desaparece del
     todo: se intuye. Es el fallo silencioso de siempre — nadie ve un error,
     solo algo que «se ve raro». */
  .oscyl-mobile-header.menu-open .oscyl-header-logo__normal {
    opacity: 0;
  }
  .oscyl-mobile-header.menu-open .oscyl-header-logo__scrolled {
    opacity: 1;
  }

  .oscyl-header-right {
    display: flex;
    align-items: center;
    gap: 16px;
  }

  /* Selector de idioma */
  .oscyl-lang-switcher {
    font-family: 'Inter', -apple-system, sans-serif;
    font-size: 12px;
    font-weight: 400;
    color: #fff;
    letter-spacing: 0.5px;
    display: flex;
    align-items: center;
    gap: 3px;
    transition: color 0.3s ease;
  }

  .oscyl-lang-switcher a {
    color: rgba(255,255,255,0.6);
    text-decoration: none;
    transition: color 0.3s ease;
  }

  .oscyl-lang-switcher a.active {
    color: #fff;
    font-weight: 500;
  }

  .oscyl-lang-switcher span {
    color: rgba(255,255,255,0.4);
    transition: color 0.3s ease;
  }

  /* Cuando el menú está abierto: colores oscuros */
  .oscyl-mobile-header.menu-open .oscyl-lang-switcher a {
    color: #999;
  }
  .oscyl-mobile-header.menu-open .oscyl-lang-switcher a.active {
    color: #1a1a1a;
  }
  .oscyl-mobile-header.menu-open .oscyl-lang-switcher span {
    color: #ccc;
  }

  /* v2.90.0 — los mismos oscuros al hacer scroll. Se repiten los valores del
     bloque de arriba en vez de agrupar los selectores porque los dos estados
     son independientes: se puede estar con scroll y el menú cerrado, con el
     menú abierto sin scroll, o las dos cosas. */
  body.oscyl-scrolled .oscyl-lang-switcher a {
    color: #999;
  }
  body.oscyl-scrolled .oscyl-lang-switcher a.active {
    color: #1a1a1a;
  }
  body.oscyl-scrolled .oscyl-lang-switcher span {
    color: #ccc;
  }

  /* ---------- BOTÓN HAMBURGUESA ---------- */
  .oscyl-menu-toggle {
    width: 36px;
    height: 36px;
    background: none;
    border: none;
    cursor: pointer;
    position: relative;
    z-index: 100002;
    -webkit-tap-highlight-color: transparent;

    /* v2.91.0 — MISMA ESTRUCTURA que `.oscyl-hamburger-desktop`: columna flex
       con `gap: 4px` y las barras alineadas a la IZQUIERDA. Antes era un flex
       centrado con las barras en `position: absolute`, y con dos barras de
       distinta longitud eso las centraba una bajo otra — un dibujo simétrico,
       no el de la marca, que las alinea por su extremo izquierdo.
       Copiar la estructura, y no solo los números, es lo que garantiza que los
       dos iconos salgan idénticos. */
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 4px;
  }

  .oscyl-menu-toggle span {
    display: block;
    /* v2.90.0 — de 24 a 33px, el mismo ancho que la hamburguesa de escritorio
       (`.oscyl-hamburger-desktop`). Son dos componentes distintos —esta la
       emite el tema y aquella un módulo de Código del Theme Builder— y habían
       quedado con medidas distintas: 24px con las barras a 7px en móvil y 33px
       con `gap: 4px` en escritorio. Se igualan al de escritorio, que es el del
       diseño: medido sobre la captura del menú abierto, el aspa ocupa ~32px.
       ⚠️ Caben: el botón mide 36px. */
    width: 33px;
    height: 2px;
    background: #fff;
    border-radius: 1px;   /* como el de escritorio */
    /* v2.91.0 — mismo eje de giro que el de escritorio. Con el origen por
       defecto (centro) las dos barras girarían sobre su punto medio y el aspa
       saldría simétrica; la de marca pivota sobre el extremo IZQUIERDO, que es
       lo que le da su inclinación característica. */
    transform-origin: left center;
    transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .oscyl-mobile-header.menu-open .oscyl-menu-toggle span,
  body.oscyl-scrolled .oscyl-menu-toggle span {
    /* v2.90.0 — las barras se oscurecen también con scroll, igual que ya hacían
       con el menú abierto. Mismo `#1a1a1a` que usa el encabezado de escritorio
       en su estado scrolled. */
    background: #1a1a1a;
  }

  /* ---------- v2.91.0 — EL ICONO DE MARCA, NO TRES BARRAS IGUALES ----------
     Esto es lo que faltaba de verdad. La hamburguesa de escritorio
     (`.oscyl-hamburger-desktop`, del módulo de Código del Theme Builder) NO
     son tres barras iguales:

        span:nth-child(1) { width: 33px }
        span:nth-child(2) { width: 25px }   ← más corta
        span:nth-child(3) { display: none } ← oculta

     Son DOS barras de distinta longitud. Y al abrir no giran 45° como una
     hamburguesa cualquiera, sino **±10°**: el aspa tumbada de la marca, la
     misma que el SVG del botón «Cerrar» del overlay, que el propio código
     describe como «replicando el SVG oficial Hamburguesa - cerrar».

     El móvil tenía tres barras iguales de 24px girando 45°. Por eso no se
     parecían: no era cuestión de tamaño, era otro dibujo.

     📌 Se replican los valores de escritorio uno a uno —33/25px, ±10°,
     `transform-origin: left center`— para que los dos iconos sean el mismo. */
  .oscyl-menu-toggle span:nth-child(1) { width: 33px; }
  .oscyl-menu-toggle span:nth-child(2) { width: 25px; }
  .oscyl-menu-toggle span:nth-child(3) { display: none; }

  /* Abierto: las dos a 33px y cruzadas a ±10° sobre el mismo eje.
     📐 Los ±3px no son estéticos: en la columna flex las dos barras (2px de
     alto y 4px de hueco) tienen sus centros a 6px, o sea a ±3px del punto
     medio. Acercarlas ese medio hueco es lo que las hace cruzarse en un punto
     en vez de quedar como dos rayas paralelas inclinadas. Mismos valores que
     `body.oscyl-menu-open .oscyl-hamburger-desktop span`. */
  .oscyl-menu-toggle.active span {
    width: 33px;
  }
  .oscyl-menu-toggle.active span:nth-child(1) {
    transform: translateY(3px) rotate(10deg);
  }
  .oscyl-menu-toggle.active span:nth-child(2) {
    transform: translateY(-3px) rotate(-10deg);
  }

  /* ---------- OVERLAY MÓVIL ---------- */
  .oscyl-overlay {
    padding-top: 60px;
  }

  /* ---------- ICONO +/- ACORDEÓN ---------- */
  .oscyl-menu-item-icon {
    width: 28px;
    height: 28px;
    position: relative;
    flex-shrink: 0;
    margin-left: 16px;
  }

  .oscyl-menu-item-icon::before,
  .oscyl-menu-item-icon::after {
    content: '';
    position: absolute;
    background: #2a2a2a;
    top: 50%;
    left: 50%;
    transition: transform 0.3s ease;
  }

  .oscyl-menu-item-icon::before {
    width: 18px;
    height: 1.5px;
    transform: translate(-50%, -50%);
  }

  .oscyl-menu-item-icon::after {
    width: 1.5px;
    height: 18px;
    transform: translate(-50%, -50%);
  }

  .oscyl-menu-item.active .oscyl-menu-item-icon::after {
    transform: translate(-50%, -50%) rotate(90deg);
  }

  /* ---------- SUBMENÚ ACORDEÓN ---------- */
  .oscyl-menu-submenu {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .oscyl-menu-item.active .oscyl-menu-submenu {
    max-height: 400px;
  }

} /* Fin @media max-width: 980px */


/* ==========================================================================
   ESTILOS HAMBURGUESA DESKTOP (dentro del módulo de código Divi Builder)
   Estos estilos se aplican al botón del Theme Builder en >980px
   ========================================================================== */

/* v2.23.5 — Hamburguesa de marca de 2 líneas (icono oficial OSCyL).
   Reposo: 2 trazos de 2px, esquinas redondeadas, color #f0f0f0.
     · Línea 1 (superior): 33px de ancho
     · Línea 2 (inferior): 25px de ancho
     · Separación 6px de eje a eje (2px de alto + 4px de gap)
   El 3er <span> del módulo Divi se oculta (el icono de marca solo tiene 2 líneas).
   Abierto (overlay): las 2 líneas pasan a 33px y se cruzan en aspa suave (±10°),
   color #1a1a1a, replicando el SVG "Hamburguesa - cerrar". */
.oscyl-hamburger-desktop {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 33px !important;   /* !important: el módulo Divi Code impone su propio ancho */
}

.oscyl-hamburger-desktop span {
  display: block;
  height: 2px;
  border-radius: 1px;
  background: #f0f0f0;
  transition: transform 0.3s ease, width 0.3s ease, opacity 0.3s ease, background 0.3s ease;
  transform-origin: left center;
}

/* Línea superior: 33px (ancho completo) */
.oscyl-hamburger-desktop span:nth-child(1) {
  width: 33px !important;
}

/* Línea inferior: 25px */
.oscyl-hamburger-desktop span:nth-child(2) {
  width: 25px !important;
}

/* El icono de marca solo tiene 2 líneas: ocultamos la 3ª del módulo Divi */
.oscyl-hamburger-desktop span:nth-child(3) {
  display: none !important;
}

/* --- Estado abierto: aspa suave (±10°) replicando el SVG "Hamburguesa - cerrar" --- */
body.oscyl-menu-open .oscyl-hamburger-desktop span {
  background: #1a1a1a !important;
  width: 33px !important;
}

/* Ambas líneas se llevan al mismo eje vertical y se cruzan con ±10° */
body.oscyl-menu-open .oscyl-hamburger-desktop span:nth-child(1) {
  transform: translateY(3px) rotate(10deg);
}

body.oscyl-menu-open .oscyl-hamburger-desktop span:nth-child(2) {
  transform: translateY(-3px) rotate(-10deg);
}

/* v2.23.4 — Capitalización tipo título del label del menú del header desktop:
   "Menú" / "Cerrar" (1ª letra mayúscula, resto minúsculas).
   El label es un <span> con estilo INLINE (text-transform: uppercase) dentro del
   módulo Divi Code del Theme Builder, hijo del botón #oscylDesktopToggle. Por estar
   el uppercase en el atributo style="" inline, hace falta !important para vencerlo.
   Se cubren ambos: el .oscyl-desktop-label (por si en otra plantilla lleva clase) y
   el span directo dentro de #oscylDesktopToggle (el caso real de la web). */
.oscyl-desktop-label,
#oscylDesktopToggle span {
  text-transform: capitalize !important;
}

/* Texto "Menú" cambia a "Cerrar" via JS, pero el color cambia aquí */
body.oscyl-menu-open .oscyl-desktop-label {
  color: #1a1a1a !important;
}

body.oscyl-menu-open .oscyl-desktop-lang a {
  color: #1a1a1a !important;
}

/* ==========================================================================
   HEADER DESKTOP — Transparente sobre hero + estado SCROLLED
   Solo aplica en desktop (>980px). En móvil se usa .oscyl-mobile-header.
   ========================================================================== */

@media (min-width: 981px) {

  /* --- Contenedor del Theme Builder: flotante fijo arriba --- */
  /* z-index 100001 → POR ENCIMA del overlay (100000) para que el botón
     "Cerrar" del header siga clicable cuando el menú está abierto. */
  .et-l--header {
    position: fixed !important;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    z-index: 100001;
  }

  /* Desplazamiento cuando la admin bar de WordPress está visible */
  .admin-bar .et-l--header {
    top: 32px;
  }

  /* --- Section del header: fondo transparente por defecto sobre el hero ---
     v2.6.0: selector reforzado con body .et-l--header > .et_builder_inner_content
     para ganar a los estilos inline+!important que genera Divi 5.
     Divi inyecta rgba(20,18,18,0.29)!important en un <style> tag posterior,
     así que necesitamos más especificidad (body al inicio). */
  body .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header {
    background-color: transparent !important;
    background-image: none !important;
    box-shadow: none;
    transition: background-color 0.35s ease,
                padding 0.35s ease,
                box-shadow 0.35s ease;
  }

  /* Textos en blanco sobre el hero oscuro */
  body .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header,
  body .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header p,
  body .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header a,
  body .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header span,
  body .et-l--header .et_pb_section.et_pb_section_0_tb_header #oscylDesktopToggle,
  body .et-l--header .et_pb_section.et_pb_section_0_tb_header #oscylDesktopToggle span {
    color: #ffffff !important;
  }

  body .et-l--header .et_pb_section.et_pb_section_0_tb_header .oscyl-hamburger-desktop span {
    background: #ffffff !important;
  }

  /* Logo NORMAL: centrado absoluto en el header, independiente de anchos
     de columna. Migrado en v2.20.5 de et_pb_image_0_tb_header (selector
     frágil al renumerado de Divi) a .oscyl-logo-normal (clase CSS asignada
     manualmente en el módulo de imagen del Theme Builder).
     Su contrapartida .oscyl-logo-scrolled ya se posiciona en absolute
     desde el bloque de conmutación (más abajo en este mismo archivo). */
  body #page-container #et-boc .et-l--header .et_pb_row_0_tb_header {
    position: relative;
  }
  body #page-container #et-boc .et-l--header .oscyl-logo-normal {
    position: absolute !important;
    left: 50% !important;
    top: 50% !important;
    transform: translate(-50%, -50%) !important;
    width: auto !important;
    z-index: 2;
  }
  body .et-l--header .oscyl-logo-normal img {
    /* v2.23.3 — añadido max-height en estado base. Antes solo se definía
       en estado scrolled (44px) y el normal salía al tamaño natural del
       SVG (varios cientos de px de alto), invadiendo el hero. La
       transición ya estaba preparada para animar entre los dos valores.
       v2.23.7 — bajado de 100px a 75px: el nuevo logo lleva el texto
       "Orquesta Sinfónica de Castilla y León" en UNA línea (SVG apaisado,
       ratio ~2.85:1) en lugar de a dos líneas. A 75px de alto ocupa ~214px
       de ancho, manteniendo una presencia visual similar a la anterior sin
       agrandarse de más. Ajustable si se quiere más grande/pequeño. */
    max-height: 75px !important;
    width: auto !important;
    height: auto !important;
    transition: filter 0.35s ease, max-height 0.3s ease;
  }

  /* --- Botón "Programación" (default): fondo blanco, texto negro ---
     Divi inyecta: body.et-db #page-container #et-boc .et-l .et_pb_button_0_tb_header
     con !important, así que necesitamos IDs para ganar en especificidad. */
  body #page-container #et-boc .et-l--header .et_pb_section.et_pb_section_0_tb_header .et_pb_button_0_tb_header {
    background-color: #ffffff !important;
    color: #1a1a1a !important;
    border-color: #ffffff !important;
    transition: all 0.3s ease;
  }

  /* --- Botón "Apóyanos" (default): transparente, borde blanco, texto blanco --- */
  body #page-container #et-boc .et-l--header .et_pb_section.et_pb_section_0_tb_header .et_pb_button_1_tb_header {
    background-color: transparent !important;
    color: #ffffff !important;
    border-color: #ffffff !important;
    transition: all 0.3s ease;
  }

  /* --- ESTADO SCROLLED: fondo blanco sólido + textos oscuros --- */
  body.oscyl-scrolled .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header {
    background-color: rgba(240, 240, 240, 0.72) !important;
    -webkit-backdrop-filter: blur(18px) saturate(1.2);
    backdrop-filter: blur(18px) saturate(1.2);
    padding-top: 10px !important;
    padding-bottom: 10px !important;
    box-shadow: 0 2px 20px rgba(0, 0, 0, 0.06);
  }

  body.oscyl-scrolled .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header,
  body.oscyl-scrolled .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header p,
  body.oscyl-scrolled .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header a,
  body.oscyl-scrolled .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header span,
  body.oscyl-scrolled .et-l--header .et_pb_section.et_pb_section_0_tb_header #oscylDesktopToggle,
  body.oscyl-scrolled .et-l--header .et_pb_section.et_pb_section_0_tb_header #oscylDesktopToggle span {
    color: #1a1a1a !important;
  }

  body.oscyl-scrolled .et-l--header .et_pb_section.et_pb_section_0_tb_header .oscyl-hamburger-desktop span {
    background: #1a1a1a !important;
  }

  /* Conmutación de logos del header desktop (v2.20.4):
     -----------------------------------------------------------------
     El header tiene DOS módulos de imagen superpuestos en la misma
     columna del Theme Builder, identificados por CLASES CSS personalizadas
     (no por su número de módulo Divi, que es frágil al rename):
       · .oscyl-logo-normal   → "Logo A vert white" (logo grande,
         versión vertical con OSCYL + subtítulo "Orquesta Sinfónica de
         Castilla y León"). Visible cuando estamos sobre el hero.
       · .oscyl-logo-scrolled → "OSCYL symbol only" (apaisado,
         solo el logotipo OSCYL sin subtítulo institucional). Visible
         cuando body.oscyl-scrolled.
     Las clases se asignan a cada módulo desde Divi Theme Builder →
     Avanzado → CSS ID y Clases → Clase CSS.
     La conmutación es 100 % CSS — los dos módulos están siempre en
     el DOM, solo cambia la visibilidad y la opacidad para hacer un
     cross-fade limpio. Posicionamos el módulo scrolled en absolute
     sobre el normal usando el padre como referencia.
     ----------------------------------------------------------------- */

  /* Padre con relative para que el módulo absoluto del logo scrolled
     se posicione correctamente sobre el otro. Aplicamos al wrapper de
     columna que contiene los dos módulos (cualquier columna que tenga
     al menos uno de los dos logos dentro). */
  /* v2.20.6: eliminado el selector :has() (problemas en navegadores móviles
     viejos que descartan toda la regla al no entender :has). Aplicamos
     position: relative al row y a la columna por nombre explícito
     (et_pb_row_X_tb_header / et_pb_column_X_tb_header) del Theme Builder
     actual. Si el cliente reordena la fila, repetir esta regla apuntando
     al row/column nuevos.
     NOTA: como el módulo .oscyl-logo-normal ya está en position: absolute
     (su regla específica más abajo lo coloca con left:50% top:50%
     transform:translate(-50%,-50%)), su contenedor debe tener
     position:relative — y la regla 'body #page-container … .et_pb_row_0_tb_header'
     justo arriba ya lo aplica al row. Por tanto basta con eso para que
     funcione. La regla :has eliminada era redundante. */

  /* Logo SCROLLED — oculto por defecto, posicionado en absolute sobre
     el normal y centrado vertical+horizontal con transform. */
  .et-l--header .oscyl-logo-scrolled {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.35s ease;
    z-index: 2;
  }

  /* Logo NORMAL — visible por defecto, transición preparada para fade. */
  .et-l--header .oscyl-logo-normal {
    opacity: 1;
    transition: opacity 0.35s ease;
  }

  /* En estado scrolled: cross-fade. Logo vertical se oculta, símbolo
     apaisado aparece centrado. */
  body.oscyl-scrolled .et-l--header .oscyl-logo-normal {
    opacity: 0;
    pointer-events: none;
  }
  body.oscyl-scrolled .et-l--header .oscyl-logo-scrolled {
    opacity: 1;
    pointer-events: auto;
  }

  /* Tamaño del logo apaisado en scrolled.
     El header en scrolled tiene padding 10+10px de chrome vertical
     (~20px). Limitamos max-height a 44px para que el total del
     header quede en 64px — compacto, sin que el SVG se salga por
     arriba/abajo (fix análogo al v2.16.1). */
  body.oscyl-scrolled .et-l--header .oscyl-logo-scrolled img {
    max-height: 44px !important;
    width: auto !important;
    height: auto !important;
    max-width: 100% !important;
  }

  /* --- Botón "Programación" (scrolled): fondo negro, texto blanco --- */
  body.oscyl-scrolled #page-container #et-boc .et-l--header .et_pb_section.et_pb_section_0_tb_header .et_pb_button_0_tb_header {
    background-color: #1a1a1a !important;
    color: #ffffff !important;
    border-color: #1a1a1a !important;
  }

  /* --- Botón "Apóyanos" (scrolled): transparente, borde negro, texto negro --- */
  body.oscyl-scrolled #page-container #et-boc .et-l--header .et_pb_section.et_pb_section_0_tb_header .et_pb_button_1_tb_header {
    background-color: transparent !important;
    color: #1a1a1a !important;
    border-color: #1a1a1a !important;
  }

}

/* --------------------------------------------------------------------------
   Header Divi al abrir overlay:
   - Fondo beige continuo (mismo color que el overlay) para que no haya
     salto visual entre el header y la zona de columnas.
   - Sin padding vertical extra (anula el `padding: 10px` del estado scrolled).
   - Botón hamburguesa/X del header OCULTO en desktop: sobra porque el
     overlay ya tiene su propio botón "✕ Cerrar" top-left (v2.2.5).
   - En móvil el header de Divi sigue oculto por otra regla, así que
     este bloque solo afecta desktop en la práctica.
   -------------------------------------------------------------------------- */
body.oscyl-menu-open .et-l--header > .et_builder_inner_content .et_pb_section,
body.oscyl-menu-open .et-l--header > .et_builder_inner_content .et_pb_section_0_tb_header,
body.oscyl-menu-open.oscyl-scrolled .et-l--header > .et_builder_inner_content .et_pb_section.et_pb_section_0_tb_header {
  background-color: #f5f0eb !important;
  background-image: none !important;
  box-shadow: none !important;
}

body.oscyl-menu-open .et-l--header > .et_builder_inner_content .et_pb_section,
body.oscyl-menu-open .et-l--header > .et_builder_inner_content .et_pb_section p,
body.oscyl-menu-open .et-l--header > .et_builder_inner_content .et_pb_section a,
body.oscyl-menu-open .et-l--header > .et_builder_inner_content .et_pb_section span,
body.oscyl-menu-open .et-l--header .et_pb_section #oscylDesktopToggle,
body.oscyl-menu-open .et-l--header .et_pb_section #oscylDesktopToggle span {
  color: #1a1a1a !important;
}

/* Logo: negro con menú abierto.
   Migrado en v2.20.5 de et_pb_image_0_tb_header a .oscyl-logo-normal
   (clase explícita asignada al módulo desde el Theme Builder). */
body.oscyl-menu-open .et-l--header .oscyl-logo-normal img {
  filter: brightness(0) !important;
}

/* --- Botón "Programación" (menú abierto): fondo negro, texto blanco --- */
body.oscyl-menu-open #page-container #et-boc .et-l--header .et_pb_section .et_pb_button_0_tb_header {
  background-color: #1a1a1a !important;
  color: #ffffff !important;
  border-color: #1a1a1a !important;
}

/* --- Botón "Apóyanos" (menú abierto): transparente, borde negro, texto negro --- */
body.oscyl-menu-open #page-container #et-boc .et-l--header .et_pb_section .et_pb_button_1_tb_header {
  background-color: transparent !important;
  color: #1a1a1a !important;
  border-color: #1a1a1a !important;
}

/* Ocultar el botón hamburguesa/X del Divi Theme Builder header cuando el overlay
   está abierto: el overlay (position:fixed, z-index 100002) cubre el header, así que
   la hamburguesa quedaría tapada. El control de cierre dentro del overlay es el
   .oscyl-close-btn, que muestra el aspa de marca (v2.23.5). Evita duplicados. */
@media (min-width: 981px) {
  body.oscyl-menu-open #oscylDesktopToggle {
    display: none !important;
  }
}

/* v2.23.5 — Fila superior del overlay en 3 zonas (izq · centro · der) para que el
   logo OSCYL quede centrado de verdad, con la fila izquierda (aspa "Cerrar" + EN/ES)
   y un hueco simétrico a la derecha. Replica el header (logo centrado). */
.oscyl-overlay-top {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  /* v2.23.11 — REPLICA EXACTA del contenedor del row del header de Divi:
     max-width 1720px centrado + padding lateral 5%. El padding 5% solo no bastaba:
     en pantallas MÁS ANCHAS que 1720px el header se queda en 1720 centrado mientras
     el 5% del overlay seguía creciendo, así que el menú se veía más ancho que el
     header (el icono/logo/botones no coincidían). Con el mismo max-width + 5%, header
     y menú ocupan EXACTAMENTE lo mismo en cualquier ancho:
       · pantalla < 1720px → el 5% da el margen lateral (igual que el header).
       · pantalla > 1720px → el max-width limita a 1720 centrado (igual que el header). */
  width: 100%;
  margin: 0 auto 24px;
  /* max-width, padding y box-sizing los da el bloque común de abajo. */
}

/* v2.23.11 — CONTENEDOR COMÚN del overlay alineado con el header de Divi.
   El header usa max-width:1720px centrado + padding lateral. Para que TODO el menú
   desplegado (fila superior, columnas, parte inferior con redes/logo Junta) ocupe
   EXACTAMENTE el mismo ancho que el header en cualquier monitor:
     · pantalla ≤ 1720px → padding lateral 5% (el max-width no limita; margen variable
       igual que el header).
     · pantalla > 1720px → max-width fija el contenido a 1720 centrado y el padding
       lateral pasa a 86px (= 5% de 1720), que es el margen interno real del header.
   Sin esto, en monitores anchos (>1720) el menú se veía MÁS ANCHO que el header
   porque usaba 5% del viewport completo (p.ej. 124px a 2484px) en vez de 86px.
   Los botones (.oscyl-menu-ctas) van en position:absolute, así que se alinean con un
   right calc() equivalente, más abajo. */
.oscyl-overlay-top,
.oscyl-menu-footer {
  max-width: 1720px;
  margin-left: auto;
  margin-right: auto;
  width: 100%;
  box-sizing: border-box;
  padding-left: 5%;
  padding-right: 5%;
}

@media (min-width: 1721px) {
  .oscyl-overlay-top,
  .oscyl-menu-footer {
    padding-left: 86px;
    padding-right: 86px;
  }
  /* El nav conserva su padding-top de 40px; solo cambia el lateral a 86px. */
  .oscyl-menu-nav {
    padding: 40px 86px 0 !important;
  }
}

.oscyl-overlay-top__left {
  display: flex;
  align-items: center;
  gap: 28px;
  justify-self: start;
}

/* Logo OSCYL centrado. v2.26.4: pasa a ser el MISMO SVG que el header en estado
   scrolled (OSCYL-Logo-symbol-only-black.svg, ver functions.php) — solo el símbolo,
   sin el subtítulo "Orquesta Sinfónica de Castilla y León". Ese archivo ya viene con
   fill #1a1a1a, así que se retira el `filter: brightness(0)` que hacía falta cuando
   aquí se usaba el SVG blanco con texto. */
.oscyl-overlay-logo {
  justify-self: center;
  display: inline-flex;
  align-items: center;
  line-height: 0;
}

.oscyl-overlay-logo img {
  /* v2.26.5 — 49px. OJO, NO es la altura del logo scrolled (44px): los dos SVG
     tienen distinta proporción de aire alrededor del dibujo, así que igualar la
     altura de la CAJA no iguala el tamaño del SÍMBOLO.
       · Logo del header normal: viewBox de 238.86 de alto, del que el símbolo
         OSCYL ocupa 140.10 (el resto es el subtítulo). Renderizado a 75px, el
         símbolo sale a 140.10/238.86 x 75 = 44.0px de alto y 132.6px de ancho.
       · Symbol-only: viewBox de 156.10, con el símbolo ocupando 140.10.
     Para que el símbolo mida esos mismos 44.0px hay que renderizar la caja a
     140.10/156.10 -> 44.0 / 0.8975 = 49px. Verificado en vivo: 44.0 x 132.6 en
     los dos, diferencia 0.
     v2.26.4 puso 44px por analogía con el logo scrolled y el símbolo salía a
     39.5px — un 10% más pequeño que el del header, y el salto se notaba al abrir
     el menú. Si algún día cambia el `max-height: 75px` del logo normal, hay que
     recalcular este valor. Sin `filter`: el SVG ya es #1a1a1a. */
  height: 49px;
  width: auto;
}

.oscyl-overlay-top__right {
  justify-self: end;
}

@media (max-width: 980px) {
  .oscyl-overlay-top {
    padding-left: 20px;
    padding-right: 20px;
  }
  /* ---------- v2.91.0 — LA FILA SUPERIOR DEL OVERLAY, SEGÚN EL DISEÑO ------
     Hasta ahora en móvil era: aspa + idioma a la IZQUIERDA y el logo OCULTO.
     El comentario que lo ocultaba decía «en móvil el logo central puede
     estorbar» — y estorbaba porque estaba CENTRADO, compitiendo con el aspa.
     El diseño lo quiere a la izquierda, con el idioma y el aspa a la derecha,
     y así no se pisan.

     📌 Por qué el logo no se veía aunque el encabezado móvil ya conmuta al
     oscuro (v2.90.0): con el menú abierto **el overlay tapa el encabezado**.
     `.oscyl-overlay` está en `z-index: 100002` y `.oscyl-mobile-header` en
     100001, así que lo que se ve arriba NO es el encabezado, es esta fila.
     Medido con `elementsFromPoint` sobre el logo: devuelve `oscyl-overlay`.

     📐 El logo va a 18px, el mismo alto que el símbolo del encabezado, para
     que al abrir el menú no dé un salto de tamaño. NO son los 49px de
     escritorio: allí el logo es el protagonista centrado de una fila mucho
     más alta. */
  .oscyl-overlay-top {
    grid-template-columns: auto 1fr;
  }

  .oscyl-overlay-logo {
    display: inline-flex;
    order: -1;            /* el logo va primero aunque en el HTML esté después */
    justify-self: start;  /* anula el `center` de escritorio */
  }

  .oscyl-overlay-logo img {
    height: 18px;
  }

  .oscyl-overlay-top__left {
    gap: 18px;
    justify-self: end;
    /* El HTML trae aspa y luego idioma; el diseño los quiere al revés cuando
       están a la derecha: EN/ES y el aspa pegada al borde. */
    flex-direction: row-reverse;
  }

  /* Solo el aspa, sin la palabra «Cerrar»: en el diseño de móvil no aparece,
     y a este ancho la fila no da para las dos cosas más el logo. */
  .oscyl-close-btn__label {
    display: none;
  }

  /* Era el hueco simétrico que centraba el logo en escritorio. Con el logo a
     la izquierda ya no equilibra nada y solo ocuparía una columna. */
  .oscyl-overlay-top__right {
    display: none;
  }
}

/* Botón "Cerrar": aspa de marca + texto "Cerrar" a su lado */
.oscyl-close-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.oscyl-close-btn__label {
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  letter-spacing: 1px;
  text-transform: capitalize;
  color: inherit;
}

/* Selector de idioma EN / ES dentro del overlay (mismo look que el del header) */
.oscyl-overlay-lang {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  letter-spacing: 1px;
}

.oscyl-overlay-lang a {
  color: inherit;
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 0.2s ease;
}

.oscyl-overlay-lang a:hover,
.oscyl-overlay-lang a.active {
  opacity: 1;
}

.oscyl-overlay-lang span {
  opacity: 0.5;
}

/* --------------------------------------------------------------------------
   Ocultar restos del montaje original del Theme Builder que el menú
   fullscreen sustituyó. Sus copias "canónicas" viven en .oscyl-menu-footer
   (logo de la Junta e iconos sociales) y se renderizan vía Customizer.
   Ver CHANGELOG v2.2.2 para el diagnóstico.

   v2.20.6 — Estrategia simplificada para evitar problemas con :has() en
   algunos navegadores móviles: solo ocultamos el <img> directamente por
   su wp-image-id. El wrapper del módulo de imagen del Theme Builder se
   queda en el flujo pero vacío (no rompe el layout porque .et_pb_image
   tiene margin auto y line-height 0 por defecto). Si en algún momento
   eso causa un hueco visible, asignar manualmente una clase CSS al
   módulo desde Divi (Avanzado → CSS ID y Clases) y añadirla aquí.

   v2.73.0 — 🚨 SALE el logo de la OSCyL del pie (`img.wp-image-188`).
   Estaba aquí por error: el pie tiene TRES logos institucionales en fila
   —Junta (189), OSCyL (188) y marca CyL (191)— y esta regla mataba solo el
   de en medio, que además es el único de los tres SIN copia en el overlay.
   El duplicado real es el de la Junta, y ese sí se ve en el pie. Origen
   probable: la regla apuntaba por número de módulo (`et_pb_image_1_tb_footer`)
   y al migrarla a wp-image-id en la v2.20.5 se congeló lo que hubiera
   entonces en esa posición.

   ⚠️ El selector que queda de redes, `et_pb_social_media_follow_0_tb_header`,
   NO identifica a un módulo concreto: el `_0` es su POSICIÓN, y Divi la
   reasigna. Oculta al primer módulo de redes que haya en el encabezado, sea
   cual sea. Por eso el módulo y esta línea tienen que borrarse JUNTOS — ver
   §9.5.1 del Flujo operativo. Si se va el módulo y la línea se queda, el
   próximo módulo de redes que alguien meta ahí desaparecerá sin explicación.
   Hoy ese módulo sigue existiendo, oculto, y con las URL buenas dentro: es
   lo que hizo perder la tarde del 02-09-2026. */
.et-l--header img.wp-image-79,
.et_pb_social_media_follow_0_tb_header {
  display: none !important;
}


/* ==========================================================================
   LISTADO DE CONCIERTOS — shortcode [oscyl_conciertos]
   v2.4.0 (Abril 2026)

   Namespace: .oscyl-conciertos para el wrapper, .oscyl-card para cada tarjeta.
   Migrado del CSS del módulo Blog (ver Notion "OSCyL — Módulo Blog: Tarjetas
   de Conciertos"). Mantiene el mismo look & feel: imagen cuadrada + título
   blanco abajo en reposo, hover = blur + extracto + botón circular flecha.

   Variables CSS para que el cliente pueda afinar colores desde el
   Customizador de Divi o desde CSS adicional sin tocar este archivo.
   ========================================================================== */

/* ---------- Variables de la TARJETA (.oscyl-card) — v2.65.0: van en :root ----
   🚨 ESTABAN DECLARADAS EN `.oscyl-conciertos`, Y ESO LAS DEJABA FUERA DE
   `[oscyl_mas_conciertos]`.

   `.oscyl-card` la pintan DOS shortcodes, y solo uno de ellos envuelve en
   `.oscyl-conciertos`:

     [oscyl_conciertos]      → .oscyl-conciertos     > __grid > .oscyl-card  ✅
     [oscyl_mas_conciertos]  → .oscyl-mas-conciertos > __grid > .oscyl-card  ❌
                                (así estaba hasta la v2.66.0; hoy ese bloque es
                                 un carrusel y ya no usa .oscyl-card)

   En el segundo, ninguna de las seis variables llegaba: los `var()` se
   quedaban sin valor y las propiedades caían a su valor inicial. Medido en
   `/concierto/programa-1-turno-1/` el 28-08-2026 — radio **0px** en vez de
   12px y `gap: normal` (o sea 0) en vez de 28px, con las tarjetas pegadas y
   en esquina viva. También faltaban el degradado, el overlay y los colores.

   🔑 ES EL MISMO FALLO QUE LA v2.58.0, en otro sitio. Allí `--oscyl-artista-radius`
   estaba en `.oscyl-artistas`, que solo envuelve la REJILLA, y las tarjetas de
   los dos carruseles se quedaban a 0. La regla que se escribió entonces vale
   igual aquí: **una variable declarada en el contenedor de UNO de los usos no
   sirve para un componente que se usa en varios sitios. Si el valor debe ser
   común, va en `:root`.**

   Las de FILTRO se quedan donde estaban a propósito: los filtros solo existen
   en `[oscyl_conciertos]`, así que su ámbito es correcto.
   -------------------------------------------------------------------------- */

:root {
  --oscyl-card-radius:    12px;
  --oscyl-card-gap:       28px;
  --oscyl-card-accent:    rgba(255, 255, 255, 0.8);
  --oscyl-card-titulo:    #ffffff;
  --oscyl-card-gradient:  linear-gradient(to bottom, transparent 35%, rgba(0,0,0,0.82) 100%);
  --oscyl-card-overlay:   rgba(0, 0, 0, 0.6);
}

.oscyl-conciertos {
  /* Solo del listado filtrable: los filtros no existen en el otro bloque. */
  --oscyl-filtro-bg:      #ffffff;
  --oscyl-filtro-border:  rgba(0, 0, 0, 0.15);
  --oscyl-filtro-focus:   #1a1a1a;
  --oscyl-filtro-texto:   #1a1a1a;

  display: block;
  width: 100%;
  max-width: 100%;
}

/* ---------- Filtros ---------- */
.oscyl-conciertos__filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 28px;
  align-items: center;
}

.oscyl-conciertos__campo {
  flex: 0 0 auto;
  min-width: 180px;
}

.oscyl-conciertos__campo--buscar {
  flex: 1 1 280px;
  min-width: 240px;
}

.oscyl-conciertos__input,
.oscyl-conciertos__select {
  width: 100%;
  padding: 10px 14px;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 14px;
  font-weight: 400;
  color: var(--oscyl-filtro-texto);
  background: var(--oscyl-filtro-bg);
  border: 1px solid var(--oscyl-filtro-border);
  border-radius: 50px;
  outline: none;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
}

.oscyl-conciertos__select {
  /* Flecha custom (caret) */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='none' stroke='%231a1a1a' stroke-width='1.6' d='M1 1l5 5 5-5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 12px 8px;
  padding-right: 40px;
  cursor: pointer;
  /* v2.24.4 — Que un sub-abono con nombre largo (p. ej. "Villafranca del
     Bierzo – Ponferrada – Astorga – La Bañeza – Benavente") no ensanche el
     select ni desborde: nunca excede su caja y el texto del valor se trunca
     con elipsis. La lista desplegada sí se ve completa (UI nativa). */
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.oscyl-conciertos__input:focus,
.oscyl-conciertos__select:focus {
  border-color: var(--oscyl-filtro-focus);
  box-shadow: 0 0 0 3px rgba(26, 26, 26, 0.08);
}

/* v2.19.0 — Rango de fechas: dos inputs date pequeños con separador → */
.oscyl-conciertos__campo--fecha-rango {
  display: flex;
  align-items: center;
  gap: 6px;
}

.oscyl-conciertos__campo--fecha-rango .oscyl-conciertos__input--fecha {
  flex: 1 1 0;
  min-width: 0;
  padding: 12px;
  font-size: 13px;
  cursor: pointer;
  position: relative; /* ancla para el placeholder ::before en iOS (v2.24.6) */
}

/* v2.24.6 — Placeholder "dd/mm/aaaa" en iOS para los date VACÍOS.
   iOS Safari, a diferencia de desktop, NO muestra "dd/mm/aaaa" en un
   input[type=date] sin valor: sale en blanco. Lo simulamos con un ::before
   que pinta el data-placeholder cuando el JS marca el campo como vacío
   (data-vacio="1"). Va dentro de @supports(-webkit-touch-callout:none), que
   es verdadero SOLO en iOS, para no duplicar el placeholder nativo de desktop. */
@supports (-webkit-touch-callout: none) {
  .oscyl-conciertos__input--fecha[data-vacio="1"]::before {
    content: attr(data-placeholder);
    color: #8a8a8a;
    pointer-events: none;
    white-space: nowrap;
  }
  /* Cuando ya hay fecha, el valor nativo se ve y ocultamos el ::before. */
  .oscyl-conciertos__input--fecha[data-vacio="0"]::before {
    content: none;
  }
}

/* v2.24.5 — Fix inputs de fecha "vacíos" en móvil.
   `.oscyl-conciertos__input` aplica `-webkit-appearance: none` (para la
   pastilla redondeada de los text/select). Heredado por los input[type=date]
   eso rompe su render nativo en iOS/Android: el control se colapsa y no muestra
   el texto "dd/mm/aaaa" → parecen vacíos. Restauramos la apariencia nativa solo
   para los date, manteniendo borde/radio/padding de la pastilla, y les damos un
   alto mínimo táctil para que no se colapsen. */
.oscyl-conciertos__input--fecha {
  -webkit-appearance: auto;
  appearance: auto;
  min-height: 44px;
}
/* El texto del valor/placeholder alineado a la izquierda (WebKit). */
.oscyl-conciertos__input--fecha::-webkit-date-and-time-value {
  text-align: left;
}

.oscyl-conciertos__fecha-sep {
  flex: 0 0 auto;
  color: var(--oscyl-filtro-texto);
  font-size: 14px;
  line-height: 1;
  opacity: 0.6;
  user-select: none;
}

.oscyl-conciertos__limpiar {
  background: transparent;
  border: 1px solid var(--oscyl-filtro-border);
  color: var(--oscyl-filtro-texto);
  padding: 10px 18px;
  border-radius: 50px;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.oscyl-conciertos__limpiar:hover {
  background: #1a1a1a;
  color: #fff;
}

.oscyl-conciertos__estado {
  font-size: 12px;
  color: #666;
  margin-left: auto;
  font-family: 'Inter', -apple-system, sans-serif;
}

/* ---------- Grid de tarjetas ---------- */
.oscyl-conciertos__grid {
  display: grid;
  gap: var(--oscyl-card-gap);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.oscyl-conciertos__grid--cols-1 { grid-template-columns: 1fr; }
.oscyl-conciertos__grid--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.oscyl-conciertos__grid--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.oscyl-conciertos__grid--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* v2.85.0 — LAS DE TRES COLUMNAS SE QUEDAN EN TRES EN TABLET.
   Antes `--cols-3` caía a 2 aquí, y en el diseño aprobado de tablet (768px)
   las tres tarjetas van en UNA fila. El motivo por el que no se podía hacer
   antes era el titular: a 3 columnas la tarjeta baja a 207px y el titular
   seguía clavado en 34px, así que se partía y la tarjeta lo cortaba. Con el
   tamaño por contenedor de esta misma versión, a 207px da 22,6px y entra en
   una línea.
   `--cols-4` sí sigue cayendo a 2: cuatro tarjetas en 980px dan 230px cada
   una y el bloque se vuelve ilegible. */
@media (max-width: 980px) {
  .oscyl-conciertos__grid--cols-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .oscyl-conciertos__grid,
  .oscyl-conciertos__grid--cols-2,
  .oscyl-conciertos__grid--cols-3,
  .oscyl-conciertos__grid--cols-4 {
    grid-template-columns: 1fr;
  }
  /* v2.24.4 — Filtros a ancho completo y encogibles en móvil. Sin esto, los
     campos son `flex: 0 0 auto` con `min-width: 180px`, así que el <select>
     de abono se ensanchaba hasta su opción más larga y se salía del viewport.
     min-width: 0 permite que el item flex encoja por debajo de su contenido. */
  .oscyl-conciertos__campo,
  .oscyl-conciertos__campo--buscar,
  .oscyl-conciertos__campo--select {
    flex: 1 1 100%;
    min-width: 0;
    max-width: 100%;
  }
}

/* ---------- Tarjeta individual ----------
   v2.21.0 — ratio cambiado a 1/1 (cuadrado) para casar con el nuevo
   "Imagen para el listado" 900×900 del CPT concierto. Si el concierto
   no tiene segunda imagen subida, la featured image principal se
   renderiza recortada al mismo ratio por object-fit: cover.
   Histórico:
     - v2.20.0 (2026-05-19): ratio 660/850 (retrato).
     - v2.4.0  (2026-04):   ratio 1/1 (cuadrado, antes del retrato). */
.oscyl-card {
  position: relative;
  overflow: hidden;
  /* v2.85.0 — convierte la tarjeta en contenedor de consulta para que su
     titular se dimensione con las unidades `cqi` (1cqi = 1% del ancho de la
     tarjeta). Es lo que permite que el mismo componente sirva a 341px en la
     rejilla, a 207px a tres columnas en tablet y a 146px dentro del carrusel
     en móvil, sin una media query por caso. */
  container-type: inline-size;
  border-radius: var(--oscyl-card-radius);
  aspect-ratio: 1 / 1;
  display: block;
  background: #111;
  isolation: isolate; /* stacking context propio */
  /* v2.23.1 — borde blanco fino visible en reposo y hover (mockup) */
  border: 1px solid rgba(255, 255, 255, 0.4);
  box-sizing: border-box;
}

.oscyl-card__link-imagen {
  display: block;
  width: 100%;
  height: 100%;
  position: static; /* sube a absolute en hover para capturar todo el clic */
  text-decoration: none;
}

.oscyl-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.5s ease, filter 0.5s ease;
}

.oscyl-card__img--placeholder {
  width: 100%;
  height: 100%;
  display: block;
  background: linear-gradient(135deg, #2a2a2a, #555);
}

/* Capa oscura en la parte inferior (reposo) → hover = oscuro uniforme */
.oscyl-card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--oscyl-card-gradient);
  z-index: 1;
  pointer-events: none;
  transition: background 0.4s ease;
}

/* ---------- Meta (fecha dd/mm + categoría) ----------
   v2.23.0 — bloque nuevo. Reposo: stackeado al pie del card sobre el título,
   en una línea con la categoría a la derecha de la fecha. Hover: se anima a
   la parte superior del card. */
/* v2.94.0 — CABECERA: meta + titular apilados en un solo bloque.
   Hasta la v2.93.0 eran dos piezas en absoluto, cada una con su distancia:
   el meta a `calc(100% - 78px)` y el titular a `bottom: 4px`. Esos 78px dan
   sitio a UN titular de una línea; con dos, la segunda subía hacia el meta y
   lo tapaba — en reposo desde la v2.85.0 y en hover hasta la v2.93.0.
   Ahora lo único posicionado es esta cabecera, anclada al pie; dentro, meta y
   titular van en flujo normal, así que el meta queda siempre ENCIMA del
   titular, tenga una línea o dos.
   En hover sube con el mismo truco de la v2.93.0: se ancla el borde inferior
   a 24px del techo y se baja la caja su propia altura con `translateY(100%)`,
   de modo que su borde superior —el meta— queda a 24px, mida lo que mida.
   📐 El hueco meta–titular es ahora FIJO: 11px (8 en ≤600px), igual en reposo
   que en hover. Antes el reposo lo dejaba al azar del tamaño de letra, porque
   el meta estaba a 78px del pie y el titular medía lo que midiera: 8px con el
   titular a 46px, 12 a 42px y ~21 a 35px. En hover el titular sigue en el
   mismo píxel: 24 + 13,2 (meta) + 11 = 48. */
.oscyl-card__cabecera {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;              /* reposo: pie de la tarjeta */
  z-index: 3;
  pointer-events: none;
  transition: bottom 0.5s cubic-bezier(0.4, 0, 0.2, 1),
              transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.oscyl-card__meta {
  /* v2.94.0 — ya no va en absoluto: se apila sobre el titular dentro de la
     cabecera. El hueco entre los dos es este margen, el mismo en hover. */
  margin-bottom: 11px;
  padding: 0 22px;
  display: flex;
  align-items: baseline;
  gap: 14px;

  /* v2.40.0 — `nowrap`, antes `wrap`. NO es una preferencia estética: el meta
     y el título están posicionados en absoluto con `top` calculado, y entre
     ellos hay exactamente 22px (`calc(100% - 78px)` vs `calc(100% - 56px)`).
     Una línea de meta mide 13,2px y cabe; dos miden 26,4 y se comen el título.
     La misma cuenta se repite en los otros tres estados —hover 24px/48px, y
     los dos de ≤600px—, así que TODO el diseño da por hecho una sola línea.

     Medido en la home el 11-08-2026: a 1440px la tarjeta mide 258px, el meta
     se iba a 2 líneas y solapaba 4px. A 1100px la tarjeta baja a 192px, el
     meta se partía en CUATRO líneas y solapaba 32px — y no solo con la
     categoría más larga.

     Se descartó reducir el tamaño de letra, que era lo primero que se pensó:
     para la categoría queda un hueco de 163px y «CONCIERTOS EXTRAORDINARIOS»
     mide 207px a 11px, 189 a 10px y 170 a 9px. NO CABE NI A 9px, que además
     ya es ilegible. El tamaño no puede resolverlo. */
  flex-wrap: nowrap;

  pointer-events: none;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

.oscyl-card__meta-fecha {
  color: #fff;
  /* La fecha no se encoge ni se recorta nunca: es el dato que más se consulta
     de la tarjeta. Quien cede espacio es la categoría. */
  flex: 0 0 auto;
}

.oscyl-card__meta-categoria {
  color: rgba(255, 255, 255, 0.85);

  /* v2.40.0 — la categoría absorbe la falta de espacio con puntos suspensivos.
     `min-width: 0` es imprescindible y no es decorativo: el mínimo por defecto
     de un elemento flex es `auto`, o sea su contenido, así que sin esto el
     span se niega a encogerse por debajo del texto completo y `text-overflow`
     no llega a activarse nunca.

     A 1440px «CONCIERTOS EXTRAORDINARIOS» se ve hasta los 161px de sus 207.
     En móvil (tarjeta de 378px) no se trunca nada: el arreglo solo actúa
     donde de verdad falta sitio. */
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ---------- Título ----------
   v2.20.0 — overrides para neutralizar la herencia del estilo global h2 del
   sistema tipográfico (Kepler 90px). Forzamos tamaño proporcional al card,
   letter-spacing neutro, line-height legible y word-spacing explícito para
   que los espacios entre palabras nunca colapsen.
   v2.23.0 — posicionamiento absoluto con `top` animable (en lugar de `bottom`)
   para que pueda subir a la parte superior del card en hover sin desaparecer. */
/* v2.85.0 — TRES CAMBIOS EN ESTE TITULAR, y conviene leerlos juntos porque
   ninguno funciona solo:

   1. TAMAÑO POR ANCHO DE TARJETA, no de ventana. Antes era `46px` fijo en
      escritorio y `34px` por debajo de 980. Pero el ancho de la tarjeta no lo
      decide la ventana: lo deciden las COLUMNAS del bloque. Con
      `columnas="3"` a 768px la tarjeta baja a 207px y el titular seguía a
      34px. `min(46px, 13.5cqi)` lo ata al contenedor: a 341px da 46px —lo
      mismo que antes, sin cambio visible— y a 207px da 22,6px.
      ⚠️ Necesita el `container-type: inline-size` de `.oscyl-card`.

   2. ANCLAJE POR ABAJO en vez de por arriba. Era `top: calc(100% - 56px)`,
      que reserva sitio para UNA línea: la segunda caía entera fuera de la
      tarjeta y el `overflow:hidden` la cortaba A MEDIA LETRA. Medido a 1440:
      «34 Otoño Musical Soriano» se salía 49px. Con `bottom`, las líneas de
      más crecen HACIA DENTRO y la caja queda siempre dentro.
      📌 El valor no es redondo: `4px` es exactamente donde queda hoy la línea
      base de un titular de una línea, para que el reposo no se mueva.

   3. RECORTE DECLARADO a 2 líneas. Antes también se recortaba —por el
      `overflow:hidden` de la tarjeta— pero cortando por la mitad de la letra.
      Con `-webkit-line-clamp` corta por línea completa y con puntos
      suspensivos. Es la misma solución que el extracto (5 líneas) y que el
      titular del slider de noticias (2, v2.54.0).

   🔑 El orden importa: el tamaño fluido hace que casi nunca haga falta la
   segunda línea, y el recorte es la red por si el título es larguísimo. */
.oscyl-card__titulo {
  /* v2.94.0 — sin posición propia: va en flujo dentro de `.oscyl-card__cabecera`,
     que es quien se ancla al pie y se anima (ver allí). */
  margin: 0;
  padding: 0 22px;
  pointer-events: none;
  /* v2.23.14 — titular a 46px desktop (v2.23.8 fue 47px). Tablet/móvil 34px (más abajo).
     v2.85.0 — el 46px pasa a ser el TECHO de una medida por contenedor. */
  font-size: min(46px, 13.5cqi);
  line-height: 1.15;
  letter-spacing: 0;
  word-spacing: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.oscyl-card__titulo a {
  /* v2.23.14 — tipografía Kepler Std Light Condensed Display (var --oscyl-font-serif),
     coherente con "Próximos Conciertos" y el resto de titulares serif del sitio.
     (En v2.23.8 se había puesto Inter; el cliente prefiere Kepler Light.) */
  font-family: var(--oscyl-font-serif);
  color: #fff;
  font-size: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  word-spacing: inherit;
  font-weight: 500;
  text-decoration: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
}

/* ---------- Contenido / extracto (solo visible en hover) ----------
   v2.23.1 — reposicionado al pie del card, alineado a la izquierda y
   dejando hueco a la derecha para el botón circular (right: 80px). */
.oscyl-card__contenido {
  position: absolute;
  left: 0;
  right: 80px;       /* hueco para la flecha en bottom-right */
  bottom: 22px;
  top: auto;
  padding: 0 22px;
  z-index: 3;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.35s ease 0.1s, transform 0.35s ease 0.1s;
  pointer-events: none;
  color: rgba(255, 255, 255, 0.92);
  font-family: 'Inter', -apple-system, sans-serif;
  overflow: hidden;
}

.oscyl-card__extracto {
  font-size: 0.85rem;
  /* v2.23.8 — interlineado reducido de 1.5 a 1.0 (más compacto). */
  line-height: 1.0;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---------- Botón circular flecha (solo visible en hover) ---------- */
/* v2.23.20 — El botón circular del hover usa el MISMO SVG que las flechas del slider
   de noticias (img/oscyl-arrow-right.svg: círculo con borde blanco + flecha derecha).
   El SVG ya incluye el círculo, así que el botón pierde el border y la flecha de
   texto (el <span>→</span> se oculta) y muestra solo el SVG como background. */
.oscyl-card__btn {
  position: absolute;
  bottom: 18px;
  right: 18px;
  width: 33px;
  height: 33px;
  border: none;
  background-color: transparent;
  background-image: url('img/oscyl-arrow-right.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.3s ease 0.15s;
  z-index: 5;
}

.oscyl-card__btn span {
  display: none;   /* ocultar la flecha de texto → (ahora la pinta el SVG) */
}

.oscyl-card__btn:hover {
  opacity: 0.7;
}

/* ---------- HOVER / ACTIVE ----------
   v2.23.0 — meta y título SUBEN a la parte superior del card (en lugar de
   ocultarse). El título sigue visible junto al meta. El extracto y el botón
   se desvanecen hacia visible. */
.oscyl-card:hover .oscyl-card__cabecera,
.oscyl-card.is-active .oscyl-card__cabecera {
  /* v2.94.0 — la cabecera arranca a 24px del techo tenga el titular las líneas
     que tenga. Mismo truco que estrenó la v2.93.0 en el titular: el borde
     inferior se ancla a 24px del techo y `translateY(100%)` —porcentaje del
     PROPIO elemento— baja la caja su altura, dejando su borde superior a 24px.
     Medido en la v2.93.0, antes de este cambio: con el titular solo, a 1440,
     «34 Otoño Musical Soriano» pasó de y 9→89 (montado en el meta) a 49→129. */
  bottom: calc(100% - 24px);
  transform: translateY(100%);
}

.oscyl-card:hover .oscyl-card__contenido,
.oscyl-card.is-active .oscyl-card__contenido {
  opacity: 1;
  transform: translateY(0);
}

.oscyl-card:hover .oscyl-card__btn,
.oscyl-card.is-active .oscyl-card__btn {
  opacity: 1;
}

.oscyl-card:hover .oscyl-card__img,
.oscyl-card.is-active .oscyl-card__img {
  transform: scale(1.05);
  filter: blur(3px) brightness(0.45);
}

.oscyl-card:hover::after,
.oscyl-card.is-active::after {
  background: var(--oscyl-card-overlay);
}

/* En hover/active: el enlace imagen cubre todo para navegar con clic */
.oscyl-card:hover .oscyl-card__link-imagen,
.oscyl-card.is-active .oscyl-card__link-imagen {
  position: absolute;
  inset: 0;
  z-index: 3;
}

/* En móvil estrecho ajustar márgenes y dejar el título un pelín más arriba
   para que la fecha+categoría no se monten con él. */
/* v2.23.8 — Tablet: el titular de 47px (desktop) es grande para tarjetas a 2 columnas.
   Se reduce a 34px (igual que móvil, v2.23.14). */
@media (max-width: 980px) and (min-width: 601px) {
  .oscyl-card__titulo {
    /* v2.85.0 — 34px pasa a ser el techo; por debajo manda el ancho de la
       tarjeta. A 2 columnas (325px) sigue dando 34px, sin cambio. A 3
       columnas (207px) da 22,6px, que es lo que pide el diseño de tablet. */
    font-size: min(34px, 11cqi);
  }
  .oscyl-card__cabecera {
    bottom: 17px;   /* donde queda la línea base a este tamaño (antes, en el titular) */
  }
}

@media (max-width: 600px) {
  .oscyl-card__meta {
    padding: 0 16px;
    font-size: 10px;
    margin-bottom: 8px;   /* v2.94.0 — el hueco que ya tenía el hover en móvil: 18 + 12 + 8 = 38 */
  }
  .oscyl-card__cabecera {
    bottom: 11px;   /* v2.94.0 — antes en el titular: 11 + 39,1 + 8 + 12 = 70, el mismo sitio */
  }
  .oscyl-card__titulo {
    padding: 0 16px;
    /* v2.23.14 — móvil a 34px (igual que tablet). En v2.23.8 era 26px.
       v2.85.0 — techo de 34px; por debajo manda el ancho de la tarjeta. A una
       columna (385px) sigue dando 34px. Es lo que arregla la tarjeta del
       carrusel, que en móvil se queda en 146px y se salía 66px. */
    font-size: min(34px, 11cqi);
  }
  .oscyl-card:hover .oscyl-card__cabecera,
  .oscyl-card.is-active .oscyl-card__cabecera {
    bottom: calc(100% - 18px);   /* meta a 18px del techo; el `transform` viene de la regla general */
  }
  .oscyl-card__contenido {
    padding: 0 16px;
    right: 68px;     /* hueco para botón más pequeño en móvil */
    bottom: 18px;
    top: auto;
  }
  .oscyl-card__extracto {
    -webkit-line-clamp: 4;
  }
}

/* v2.93.0 — en tarjetas ESTRECHAS el extracto baja a 3 líneas.
   Al dejar de montarse sobre el meta, el titular de dos líneas ocupa ahora su
   sitio real bajo él, y en tarjetas pequeñas ya no cabe junto a un extracto de
   5 líneas. A 1100px (tarjeta de 192) se pisaban 7px: titular 49→108, extracto
   desde 101. Con 3 líneas el extracto arranca en 129.
   Es una consulta de CONTENEDOR, no de ventana, por lo mismo que el tamaño del
   titular (v2.85.0): lo que manda es el ancho de la tarjeta, que depende de las
   columnas del bloque. El corte de 220px deja fuera a 1280 (tarjeta de 227,
   que con 5 líneas ya cabe: 49→119 contra 136) y recoge el carrusel de móvil
   (146px), donde con 4 líneas se tocaban por 1px.
   Va DESPUÉS del bloque de ≤600px a propósito: pesa lo mismo (una clase) y
   tiene que ganar a su `-webkit-line-clamp: 4`. */
@container (max-width: 220px) {
  .oscyl-card__extracto {
    -webkit-line-clamp: 3;
  }
}

/* ---------- Estado vacío ---------- */
.oscyl-conciertos__vacio {
  text-align: center;
  padding: 60px 20px;
  font-family: 'Inter', -apple-system, sans-serif;
  color: #666;
  font-size: 1rem;
}

/* ---------- Paginación "cargar más" ---------- */
.oscyl-conciertos__paginacion {
  text-align: center;
  margin-top: 40px;
}

.oscyl-conciertos__cargar-mas {
  padding: 14px 36px;
  border: 1.5px solid #1a1a1a;
  background: transparent;
  color: #1a1a1a;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.5px;
  border-radius: 50px;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease;
}

.oscyl-conciertos__cargar-mas:hover {
  background: #1a1a1a;
  color: #fff;
}

/* Estado cargando */
.oscyl-conciertos--cargando .oscyl-conciertos__grid {
  opacity: 0.55;
  transition: opacity 0.2s ease;
  pointer-events: none;
}


/* ===========================================================================
   SINGLE CONCIERTO — shortcodes para Divi Theme Builder
   v2.5.0
   =========================================================================== */

/* --- Variables del single --- */
:root {
  --oscyl-single-terracota: #b5533c;
  --oscyl-single-terracota-dark: #9a4530;
  --oscyl-single-texto-claro: #ffffff;
  --oscyl-single-texto-oscuro: #2a2a2a;
  --oscyl-single-gris: #646970;
  --oscyl-single-borde: #e0e0e0;
}

/* --- Caja PROGRAMA ---
   !important en color/font para ganar a los estilos inline de Divi modules */
.oscyl-programa {
  background-color: transparent !important;
  color: var(--oscyl-single-texto-claro) !important;
  border-radius: 0;
  padding: 0;
}

.oscyl-programa__titulo {
  font-family: 'Inter', sans-serif !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  text-transform: uppercase;
  letter-spacing: 2px;
  margin: 0 0 28px !important;
  padding: 0 !important;
  color: var(--oscyl-single-texto-claro) !important;
  line-height: 1.4 !important;
}

.oscyl-programa__obra {
  margin: 0 0 20px;
  padding-bottom: 0;
  border-bottom: none;
}

.oscyl-programa__obra:last-of-type {
  margin-bottom: 0;
}

.oscyl-programa__compositor {
  font-family: 'Inter', sans-serif !important;
  font-size: 14px !important;
  /* v2.24.11 — El compositor debe verse EXACTAMENTE como en el editor: ni
     mayúsculas (text-transform) ni negrita forzada. Si el editor escribe
     "Noriko Koide (1982)" en texto plano, sale en peso normal; si pone
     <b>/<strong> (p. ej. "<b>Manuel de Falla</b>"), sale en negrita por el
     propio tag. Por eso el peso base es 300 (como el resto del programa) y la
     negrita la aportan solo los tags del contenido. */
  font-weight: 300 !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
  margin: 0 0 4px !important;
  padding: 0 !important;
  color: var(--oscyl-single-texto-claro) !important;
  line-height: 1.4 !important;
}

.oscyl-programa__titulo-obra {
  font-family: 'Inter', sans-serif !important;
  font-size: 16px !important;
  font-weight: 300 !important;
  /* v2.24.8 — font-style NORMAL: la cursiva la marcan SOLO los <em>/<i> del
     contenido, no la línea entera. Así "op. 31", "K. 366" o "Estreno en España"
     (fuera del <em>) salen rectos y solo lo que el editor marcó en cursiva va
     en cursiva. v2.24.10 — el parser ya no fuerza cursiva en ningún caso. */
  font-style: normal !important;
  text-transform: none !important;
  margin: 0 !important;
  padding: 0 !important;
  line-height: 1.5 !important;
  color: rgba(255, 255, 255, 0.9) !important;
}

/* v2.24.8 — Obras adicionales de un mismo compositor (2ª, 3ª…): mismo estilo
   que el título de obra. Se separan un poco de la obra anterior. NO usan la
   clase __extra (13px gris), que queda reservada para notas secundarias. */
.oscyl-programa__titulo-obra--extra {
  margin-top: 2px !important;
}

.oscyl-programa__extra {
  font-family: 'Inter', sans-serif !important;
  font-size: 13px !important;
  font-weight: 300 !important;
  font-style: normal !important;
  text-transform: none !important;
  margin: 4px 0 0 !important;
  padding: 0 !important;
  color: rgba(255, 255, 255, 0.7) !important;
}

.oscyl-programa__interpretes {
  margin-top: 28px;
  padding-top: 0;
  border-top: none;
}

.oscyl-programa__meta {
  font-family: 'Inter', sans-serif !important;
  font-size: 14px !important;
  font-weight: 300 !important;
  text-transform: none !important;
  margin: 0 0 8px !important;
  padding: 0 !important;
  color: rgba(255, 255, 255, 0.9) !important;
  line-height: 1.5 !important;
}

.oscyl-programa__meta:last-child {
  margin-bottom: 0 !important;
}

.oscyl-programa__meta-label {
  font-weight: 500 !important;
  margin-right: 6px;
}

.oscyl-programa__boton-wrap {
  margin-top: 28px;
  text-align: center;
}

/* v2.57.0 — El botón ocupa TODO el ancho de la caja del programa, igual que
   las líneas de texto de encima. Antes era `inline-block`, así que se ajustaba
   a su texto (188px de los 446 de la caja) y quedaba centrado y suelto.

   No hace falta declarar el ancho de la caja en ningún sitio: el `boton-wrap`
   ya mide lo mismo que el texto, así que un `width: 100%` los ata solos y
   sigue cuadrando si la caja cambia de ancho. Verificado a 1440 (446px) y en
   móvil (242px): 0px de desviación con el texto por los dos lados.

   `box-sizing: border-box` para que los 36px de relleno lateral queden DENTRO
   del ancho y el botón no desborde la caja. */
.oscyl-programa__boton {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 12px 36px;
  border: none !important;
  border-radius: 30px;
  color: var(--oscyl-single-terracota) !important;
  font-family: 'Inter', sans-serif !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  text-decoration: none !important;
  text-transform: none !important;
  background-color: #ffffff !important;
  transition: background-color 0.25s ease, color 0.25s ease, opacity 0.25s ease;
}

.oscyl-programa__boton:hover {
  background-color: #ffffff !important;
  color: var(--oscyl-single-terracota) !important;
  opacity: 0.85;
}

/* --- Badge temporada --- */
.oscyl-badge-temporada {
  display: inline-block;
  padding: 6px 16px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 20px;
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.5px;
  color: var(--oscyl-single-texto-claro);
}

/* --- Bloque intérpretes (hero) --- */
.oscyl-interpretes {
  margin: 0;
}

.oscyl-interpretes__linea {
  font-family: 'Inter', sans-serif;
  font-size: 18px;
  font-weight: 300;
  line-height: 1.4;
  margin: 0;
  color: inherit;
}

/* ==========================================================================
   ABONOS DEL CONCIERTO, AGRUPADOS — [oscyl_dato campo="abonos"]   (v2.77.0)

   El diseño pide ver la jerarquía: el abono padre como rótulo y sus rutas
   debajo. El HTML lo emite oscyl_render_abonos_agrupados().

   Va aquí y no en Divi porque sale de un shortcode del tema y no tiene panel
   donde ajustarlo — el criterio del §9.3.1 del Flujo operativo.

   Todo son <span> y el salto de línea lo da `display: block`, en vez de <div>
   o <p>: el shortcode se coloca dentro de un <div> del módulo, y un <p> ahí
   heredaría los márgenes de párrafo de Divi.
   ========================================================================== */
.oscyl-abonos {
  display: block;
}

.oscyl-abonos__grupo {
  display: block;
}

/* Separación solo ENTRE grupos, no antes del primero. */
.oscyl-abonos__grupo + .oscyl-abonos__grupo {
  margin-top: 0.5em;
}

.oscyl-abonos__titulo {
  display: block;

  /* Explícito y no heredado: la regla `strong { font-weight: 500 }` de la
     v2.60.0 bajó la negrita editorial de todo el sitio, y aquí esto no es
     énfasis dentro de un texto, es el rótulo de un grupo. A 500 apenas se
     distingue de la lista que tiene debajo. */
  font-weight: 700;
}

.oscyl-abonos__items {
  display: block;
}

/* Enlace a la ficha del artista — solo se emite con
   [oscyl_interpretes enlazar_artistas="si"] (v2.24.0).
   La clase existía desde entonces pero nunca se estiló, así que el enlace
   salía con el color global de Divi (`a { color: var(--gcid-link-color,#1c1c1c) }`
   del Personalizador): oscuro sobre el hero terracota.
   Hereda en vez de fijar blanco, por el mismo criterio que .oscyl-enlace-flecha
   (v2.32.0): el color lo manda la línea, así que el bloque sigue valiendo si
   algún día va sobre fondo claro. Una clase (0,1,0) gana al selector `a`
   (0,0,1) de Divi sin necesidad de !important. */
.oscyl-interpretes__enlace {
  color: inherit;
  text-decoration: none;
}

.oscyl-interpretes__enlace:hover,
.oscyl-interpretes__enlace:focus-visible {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --- Botón comprar entradas (independiente, hero) --- */
.oscyl-btn-entradas {
  display: inline-block;
  padding: 14px 40px;
  border: none !important;
  border-radius: 30px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  font-weight: 500;
  text-decoration: none !important;
  color: var(--oscyl-single-terracota) !important;
  background-color: #ffffff !important;
  transition: background-color 0.25s ease, color 0.25s ease, opacity 0.25s ease;
  letter-spacing: 0.5px;
}

.oscyl-btn-entradas:hover {
  background-color: #ffffff !important;
  color: var(--oscyl-single-terracota) !important;
  opacity: 0.85;
}

/* v2.87.0 — EN TELÉFONO, EL BOTÓN DE ENTRADAS VA A ANCHO COMPLETO.
   Medido en /concierto/programa-1-turno-1/ a 428px: el botón ocupaba 209px de
   los 342 de su módulo, o sea que le sobraban 133px a la derecha. Pedido del
   cliente el 25-09-2026.

   📌 El relleno lateral baja de 40 a 16px. Los 40px existen para dar cuerpo a
   un botón que se ajusta a su texto; con el botón a ancho completo no pintan
   nada y solo comen sitio al texto si algún día se alarga.
   📌 `text-align: center` hace falta porque el módulo lo hereda a `start`.
   ⚠️ El alto no cambia: 52px antes y después. */
@media (max-width: 767px) {
  .oscyl-btn-entradas {
    display: block;
    width: 100%;
    box-sizing: border-box;
    text-align: center;
    padding-left: 16px;
    padding-right: 16px;
  }
}

/* --- Botón «Descargar programa en PDF» (v2.83.0) ---
   Lo pinta [oscyl_boton_programa], y solo cuando el concierto tiene un archivo
   adjunto en el meta box «Programa de mano».

   📐 MISMA FORMA que `.oscyl-btn-entradas` —relleno 14/40, radio 30, Inter 14
   a peso 500 y el mismo `letter-spacing`— y DISTINTO color: aquel es macizo
   sobre el hero terracota, y este es de línea porque vive sobre fondo claro.

   🔑 Por qué no comparten un selector agrupado: agrupar la forma obligaba a
   reescribir la regla de `.oscyl-btn-entradas`, que lleva `!important` en
   fondo y borde y está en vivo en las 42 fichas. No compensa arriesgar un
   botón que funciona para ahorrar seis líneas. Si algún día aparece un tercer
   botón con esta misma forma, entonces sí toca factorizarla — y habrá que
   medir el computado del de entradas antes y después.

   ⚠️ Si se cambia la forma de uno, hay que cambiar la del otro. Es el precio
   asumido de tenerlas separadas, y queda dicho aquí para que se vea. */
.oscyl-btn-programa {
  display: inline-block;
  padding: 14px 40px;
  border: 1px solid var(--oscyl-single-terracota);
  border-radius: 30px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.5px;
  text-decoration: none !important;
  color: var(--oscyl-single-terracota) !important;
  background-color: transparent;
  transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.oscyl-btn-programa:hover,
.oscyl-btn-programa:focus-visible {
  background-color: var(--oscyl-single-terracota);
  border-color: var(--oscyl-single-terracota);
  color: #ffffff !important;
}

/* --- Más conciertos ---
   v2.66.0 — el bloque pasó de rejilla a CARRUSEL, así que su `<section>` lleva
   ahora `.oscyl-slider .oscyl-slider--conciertos .oscyl-mas-conciertos`.

   📌 La clase `.oscyl-mas-conciertos` SE MANTIENE en el marcado a propósito,
   aunque la maqueta ya la den las clases del slider: si alguien hubiera escrito
   CSS libre contra ella en un módulo de Divi o en Opciones de tema, seguiría
   aplicando. En este proyecto eso no es hipotético — ver la §9.2 del flujo
   operativo. El `margin` de aquí lo pisa el de `.oscyl-slider` (3rem), que va
   más abajo en la hoja y tiene la misma especificidad; se deja porque es el
   gancho de esa CSS externa, no por el margen.

   ⚠️ `.oscyl-mas-conciertos__titulo` YA NO SE EMITE. El titular es ahora un
   `.oscyl-slider__titulo`, como el de los otros dos carruseles — recto y no en
   cursiva, que es lo que pidió el cliente. La regla se conserva por el mismo
   motivo defensivo que la anterior, pero si alguna vez se hace limpieza de CSS
   muerto, esta y sus dos bloques responsive son las primeras candidatas. */
.oscyl-mas-conciertos {
  margin: 60px 0;
}

.oscyl-mas-conciertos__titulo {
  font-family: var(--oscyl-font-serif);
  font-size: 36px;
  font-weight: 400;
  font-style: italic;
  color: var(--oscyl-single-texto-oscuro);
  margin: 0 0 32px;
}

/* --- Responsive --- */
@media (max-width: 980px) {
  .oscyl-programa {
    padding: 28px 24px;
  }

  .oscyl-mas-conciertos__titulo {
    font-size: 28px;
  }
}

@media (max-width: 600px) {
  .oscyl-programa {
    padding: 24px 20px;
    border-radius: 8px;
  }

  .oscyl-mas-conciertos__titulo {
    font-size: 24px;
  }

  .oscyl-interpretes__linea {
    font-size: 16px;
  }
}


/* ==========================================================================
   LISTADO DE ARTISTAS — shortcode [oscyl_artistas]
   v2.8.0 (Abril 2026)

   Namespace: .oscyl-artistas wrapper, .oscyl-artista-card tarjeta individual.
   Diseño basado en mockup "Profesores" del cliente: retrato vertical con
   gradiente inferior, nombre en Playfair blanco + cargo pequeño en Inter
   blanco 70 %. Filtros como pills horizontales con enlace tipo anchor.

   Variables CSS para afinar desde el Customizador sin tocar este archivo.
   ========================================================================== */

.oscyl-artistas {
  /* v2.58.0 — `--oscyl-artista-radius` se retiró de aquí. Declarada en este
     contenedor solo alcanzaba a la rejilla, no a los dos carruseles, que
     quedaban a 0px. El radio de tarjeta es ahora `--oscyl-card-radius` en
     `:root`, común con la tarjeta de concierto. NO volver a declararlo aquí:
     reaparecería la divergencia entre la rejilla y los carruseles. */
  --oscyl-artista-gap:        20px;
  --oscyl-artista-overlay:    linear-gradient(
                                to bottom,
                                transparent 45%,
                                rgba(0, 0, 0, 0.75) 100%);
  --oscyl-artista-nombre:     #ffffff;
  --oscyl-artista-cargo:      rgba(255, 255, 255, 0.78);
  --oscyl-artista-pill-bg:    transparent;
  --oscyl-artista-pill-brd:   rgba(0, 0, 0, 0.35);
  --oscyl-artista-pill-txt:   #2a2a2a;
  --oscyl-artista-pill-active-bg:  #1a1a1a;
  --oscyl-artista-pill-active-txt: #ffffff;
  /* v2.33.0 — verde institucional, antes #1a1a1a. Es una VARIABLE a propósito:
     el color del encabezado de sección se cambia aquí y afecta a todos los
     listados de [oscyl_artistas] con `agrupar`. Si algún día hiciera falta
     otro color en un listado concreto, se redefine la variable en el módulo de
     esa página en vez de duplicar la regla. */
  --oscyl-artista-grupo-titulo:    #737836;

  display: block;
  width: 100%;
  max-width: 100%;
}

/* ---------- Filtros (barra de pills) ---------- */
.oscyl-artistas__filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin: 0 0 32px;
}

.oscyl-artistas__filtros-label {
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: #555;
  flex: 0 0 auto;
}

.oscyl-artistas__pills {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* v2.46.0 — Los puntos de lista salían igualmente, pese al `list-style: none`
   de arriba. Divi trae `#left-area ul, .entry-content ul, .et-l--body ul, … {
   list-style-type: disc }`, y ese selector tiene (0,1,1) o más, así que le gana
   a `.oscyl-artistas__pills` (0,1,0).

   Síntoma engañoso: además del punto al inicio de cada línea aparecía uno
   DETRÁS de cada pastilla. No eran dos fallos: con `list-style-position:
   outside` el marcador se dibuja a la izquierda de su `<li>`, y en una fila
   flex esa posición cae justo después de la pastilla anterior.

   🔑 NO se arregla subiendo especificidad sobre el `<ul>`, que es lo que se
   hizo en v2.31.1 con las noticias. `list-style-type` es una propiedad
   HEREDADA: Divi la declara en el `<ul>` y el `<li>` la recibe por herencia.
   Una declaración directa sobre el hijo gana SIEMPRE a un valor heredado, sea
   cual sea la especificidad de la regla del padre. Por eso basta con esto y no
   hay que competir con Divi — que además usa `#left-area` en esa lista de
   selectores, con un ID que ninguna cadena de clases podría superar.

   Verificado en /la-orquesta/profesores/: de 16 marcadores a 0. */
.oscyl-artistas__pills li {
  list-style: none;
}

.oscyl-artistas__pill {
  display: inline-block;
  padding: 6px 16px;
  border: 1px solid var(--oscyl-artista-pill-brd);
  border-radius: 50px;
  background: var(--oscyl-artista-pill-bg);
  color: var(--oscyl-artista-pill-txt);
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.3px;
  text-decoration: none;
  line-height: 1.4;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.oscyl-artistas__pill:hover {
  background: #1a1a1a;
  color: #fff;
  border-color: #1a1a1a;
}

.oscyl-artistas__pill.is-active {
  background: var(--oscyl-artista-pill-active-bg);
  color: var(--oscyl-artista-pill-active-txt);
  border-color: var(--oscyl-artista-pill-active-bg);
}

/* ---------- Agrupación por sección ---------- */
.oscyl-artistas__grupo + .oscyl-artistas__grupo {
  margin-top: 56px;
}

.oscyl-artistas__grupo-titulo {
  font-family: var(--oscyl-font-serif);
  /* v2.33.0 — de 28px fijos a un clamp que llega a 56px, el doble, en
     escritorio. Se pasa a clamp en vez de subir el número fijo porque a 56px
     una sección de nombre largo («Violonchelos», «Contrabajos») se comería la
     pantalla en móvil; así escala sola entre 32 y 56px y el override de ≤600px
     deja de hacer falta.
     v2.97.0 — los atributos `grupo_titulo_tam*` lo sobrescriben con variables
     CSS. Sin ellos, el `var()` cae al clamp de siempre. */
  font-size: var(--oscyl-artistas-grupo-titulo-tam, clamp(2rem, 4.4vw, 3.5rem));
  font-weight: 400;
  color: var(--oscyl-artista-grupo-titulo);
  margin: 0 0 24px;
  padding: 0 0 12px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  /* Offset de scroll para que el anchor #seccion-xxx no quede tapado por
     el header fixed del Theme Builder (≈ 100px) */
  scroll-margin-top: 120px;
}

/* ---------- Grid ---------- */
.oscyl-artistas__grid {
  display: grid;
  gap: var(--oscyl-artista-gap);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.oscyl-artistas--cols-1 .oscyl-artistas__grid { grid-template-columns: 1fr; }
.oscyl-artistas--cols-2 .oscyl-artistas__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.oscyl-artistas--cols-3 .oscyl-artistas__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.oscyl-artistas--cols-4 .oscyl-artistas__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 980px) {
  .oscyl-artistas__grid,
  .oscyl-artistas--cols-3 .oscyl-artistas__grid,
  .oscyl-artistas--cols-4 .oscyl-artistas__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 780px) {
  .oscyl-artistas__grid,
  .oscyl-artistas--cols-3 .oscyl-artistas__grid,
  .oscyl-artistas--cols-4 .oscyl-artistas__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 480px) {
  .oscyl-artistas__grid,
  .oscyl-artistas--cols-2 .oscyl-artistas__grid,
  .oscyl-artistas--cols-3 .oscyl-artistas__grid,
  .oscyl-artistas--cols-4 .oscyl-artistas__grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Tarjeta ----------
   v2.21.0 — ratio 1/1 (cuadrado) para casar con el nuevo size
   oscyl-listado (900×900). Antes (v2.8.0 → v2.20.6) era 3/4 retrato. */
.oscyl-artista-card {
  position: relative;
  overflow: hidden;
  /* v2.58.0 — Radio común con la tarjeta de concierto (6px). Antes usaba
     `--oscyl-artista-radius`, declarada en `.oscyl-artistas`: la rejilla la
     heredaba (4px) y los dos carruseles no (0px). Ver la nota del `:root`.
     El nombre dice «slider» pero la variable gobierna también esta rejilla. */
  border-radius: var(--oscyl-slider-card-radius);
  background: #1a1a1a;
  aspect-ratio: 1 / 1;
  isolation: isolate;
}

.oscyl-artista-card__link {
  display: block;
  width: 100%;
  height: 100%;
  text-decoration: none;
  color: inherit;
}

.oscyl-artista-card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 20%;
  display: block;
  transition: transform 0.55s ease, filter 0.55s ease;
  filter: grayscale(0.15);
}

.oscyl-artista-card__img--placeholder {
  background: linear-gradient(135deg, #2a2a2a 0%, #555 100%);
}

/* Gradiente inferior siempre visible */
.oscyl-artista-card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--oscyl-artista-overlay);
  z-index: 1;
  pointer-events: none;
  transition: background 0.35s ease;
}

.oscyl-artista-card__contenido {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 18px 20px 20px;
  color: var(--oscyl-artista-nombre);
}

.oscyl-artista-card__nombre {
  font-family: var(--oscyl-font-serif);
  font-size: 20px;
  font-weight: 500;
  line-height: 1.2;
  margin: 0 0 4px;
  color: var(--oscyl-artista-nombre);
  letter-spacing: 0.2px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

.oscyl-artista-card__cargo {
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.3px;
  margin: 0;
  color: var(--oscyl-artista-cargo);
}

/* Hover: zoom sutil + oscurecido para realzar texto */
.oscyl-artista-card:hover .oscyl-artista-card__img {
  transform: scale(1.04);
  filter: grayscale(0) brightness(0.92);
}

.oscyl-artista-card:hover .oscyl-artista-card__link::after {
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.1) 0%,
    rgba(0, 0, 0, 0.75) 100%);
}

/* Focus accesible (teclado) */
.oscyl-artista-card__link:focus-visible {
  outline: 2px solid #1a1a1a;
  outline-offset: 2px;
}

/* Estado vacío */
.oscyl-artistas__vacio {
  text-align: center;
  padding: 60px 20px;
  font-family: 'Inter', -apple-system, sans-serif;
  color: #666;
  font-size: 1rem;
}

/* v2.97.0 — `grupo_titulo_tam`, `_tablet` y `_movil`: tamaño de los títulos
   de sección por dispositivo, con los cortes de Divi (980 / 767).
   La cadena de `var()` reproduce la herencia de Divi: móvil → tablet →
   escritorio → valor del tema. Con los tres vacíos el resultado es el de
   antes de la v2.97.0, ancho a ancho: el clamp hasta 600px y 26px por debajo.
   Por eso hay DOS escalones de móvil: 767 cambia solo cuando hay atributo;
   600 conserva el 26px de la v2.33.0 como último recurso. */
@media (max-width: 980px) {
  .oscyl-artistas__grupo-titulo {
    font-size: var(--oscyl-artistas-grupo-titulo-tam-tablet,
               var(--oscyl-artistas-grupo-titulo-tam,
               clamp(2rem, 4.4vw, 3.5rem)));
  }
}

@media (max-width: 767px) {
  .oscyl-artistas__grupo-titulo {
    font-size: var(--oscyl-artistas-grupo-titulo-tam-movil,
               var(--oscyl-artistas-grupo-titulo-tam-tablet,
               var(--oscyl-artistas-grupo-titulo-tam,
               clamp(2rem, 4.4vw, 3.5rem))));
  }
}

@media (max-width: 600px) {
  .oscyl-artistas__grupo-titulo {
    /* v2.33.0 — el `clamp` de la regla base ya se encarga del escalado (su
       mínimo son 32px). Se deja este valor porque en móvil estrecho interesa
       bajar por debajo de ese mínimo.
       v2.97.0 — el 26px queda como último eslabón de la cadena. */
    font-size: var(--oscyl-artistas-grupo-titulo-tam-movil,
               var(--oscyl-artistas-grupo-titulo-tam-tablet,
               var(--oscyl-artistas-grupo-titulo-tam,
               26px)));
  }

  /* v2.34.0 — aquí había un escalón de nombre (17px) y cargo (11px). Se retira:
     el tamaño ya no depende del ancho del viewport sino del de la TARJETA, con
     `cqw` (ver el bloque «FICHA DE ARTISTA» más abajo). Dejarlo habría sido
     código muerto — pierde por especificidad contra el bloque nuevo. */
}


/* ==========================================================================
   FICHA DE ARTISTA — CAJA DE IDENTIDAD UNIFICADA (v2.34.0)
   ==========================================================================
   Un solo sistema visual para el nombre y el cargo sobre la foto, compartido
   por la rejilla de [oscyl_artistas] y por el carrusel de
   [oscyl_artistas_temporada]. Antes eran dos diseños distintos que se habían
   ido separando; ahora los números viven aquí y los dos sitios los consumen.

   NO afecta a [oscyl_mas_artistas], que mantiene su badge gris sólido: es un
   listado secundario dentro de la ficha de artista, no un elenco.

   ---------------------------------------------------------------------------
   POR QUÉ EL TAMAÑO VA EN `cqw` Y NO EN `vw` NI EN MEDIA QUERIES

   La misma tarjeta se pinta a 1, 2, 3 y 4 columnas, así que su ancho NO es una
   función del ancho de la ventana: a 1440px con 4 columnas mide 255px, y a
   420px con 1 columna mide 336px — la tarjeta del móvil es MÁS ANCHA que la
   del escritorio. Cualquier regla basada en el viewport se equivoca en la
   mitad de los casos, y de ahí venían los nombres partidos en tablet.

   Con `container-type: inline-size` en la tarjeta, `cqw` es el 1% de SU ancho,
   así que una sola declaración cubre todas las combinaciones sin un solo
   breakpoint. Medido en el elenco real de profesores (76 fichas): la palabra
   más larga es «DELBOUSQUETS.» y a Inter 700 mide 145px a 17px y 221px a 26px.
   Contra el ancho útil de la caja en cada escenario:

     tarjeta 367px (temporada)   → caja 335 máx, 303 útiles, nombre 26px → 221 ✓
     tarjeta 347px (3 col, 1440) → caja 315 máx, 287 útiles, nombre 25px → 213 ✓
     tarjeta 255px (4 col, 1440) → caja 223 máx, 195 útiles, nombre 18px → 157 ✓
     tarjeta 223px (3 col, 900)  → caja 191 máx, 163 útiles, nombre 17px → 145 ✓

   Caben todos con margen. El mínimo de 17px del clamp está puesto justo por
   ese último caso: es el escenario más apretado del sitio.

   Que un nombre pase a dos líneas es CORRECTO y así está en el mockup
   («THIERRY / FISCHER»). Lo que había que evitar es que se parta una palabra
   por la mitad, y eso es lo que garantizan los números de arriba.
   ---------------------------------------------------------------------------

   POR QUÉ LA CAJA ES `fit-content` Y NO UN PORCENTAJE FIJO

   v2.29.3 le puso ancho fijo al 50% en temporada, para que todas las cajas
   midieran igual como en el mockup. Ese 50% no se puede portar a la rejilla:
   sobre una tarjeta de 223px deja 84px útiles y ahí no cabe ningún nombre a
   ningún tamaño. Se sustituye por «crecer con el texto, con tope»:

     width: fit-content            → la caja mide lo que mide el nombre
     max-width: calc(100% - 2×16)  → nunca toca los bordes de la foto

   Lo que en v2.29.3 se descartó fue `min-width: min-content`, que es otra cosa:
   aquello crecía SIN TOPE (llegó al 84% de la tarjeta) porque por especificación
   `min-width` gana a `max-width`. `fit-content` sí respeta el tope. */

:root {
  /* Caja */
  --oscyl-ficha-caja-bg:      rgba(46, 50, 58, 0.70);
  --oscyl-ficha-caja-blur:    6px;
  --oscyl-ficha-caja-margen:  16px;
  --oscyl-ficha-caja-radius:  8px;
  --oscyl-ficha-caja-pad:     14px 18px 12px;

  /* Tipografía, relativa al ancho de la TARJETA (ver nota arriba) */
  --oscyl-ficha-nombre-size:  clamp(17px, 7.2cqw, 26px);
  --oscyl-ficha-cargo-size:   clamp(10px, 3.3cqw, 12px);
  --oscyl-ficha-nombre-color: #ffffff;
  --oscyl-ficha-cargo-color:  rgba(255, 255, 255, 0.72);
}

/* ---------- Rejilla de [oscyl_artistas] ----------
   Se acota con `.oscyl-artistas__grid` (0,2,0) para ganar a las reglas base de
   una sola clase sin recurrir a !important. */

.oscyl-artistas__grid .oscyl-artista-card {
  container-type: inline-size;
}

/* El degradado inferior sobraba en cuanto el texto tiene caja propia: sumaba
   una segunda capa oscura sobre la foto. Temporada ya lo quitaba; se unifica. */
.oscyl-artistas__grid .oscyl-artista-card__link::after {
  content: none;
}

.oscyl-artistas__grid .oscyl-artista-card__contenido {
  left: var(--oscyl-ficha-caja-margen);
  right: auto;
  bottom: var(--oscyl-ficha-caja-margen);
  z-index: 3;

  width: fit-content;
  max-width: calc(100% - var(--oscyl-ficha-caja-margen) * 2);
  box-sizing: border-box;
  padding: var(--oscyl-ficha-caja-pad);

  background-color: var(--oscyl-ficha-caja-bg);
  -webkit-backdrop-filter: blur(var(--oscyl-ficha-caja-blur));
  backdrop-filter: blur(var(--oscyl-ficha-caja-blur));
  border-radius: var(--oscyl-ficha-caja-radius);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);

  /* Último recurso: si algún día entra un apellido que no quepa ni a 17px,
     preferimos partirlo a que desborde la caja o se coma la foto. */
  overflow-wrap: break-word;
}

.oscyl-artistas__grid .oscyl-artista-card__nombre {
  /* Inter 700 en lugar de Kepler Std. Es una excepción consciente al sistema
     tipográfico —que reserva Kepler para nombres propios y titulares— heredada
     del mockup de temporada. Se documenta para que no parezca un despiste. */
  font-family: 'Inter', -apple-system, sans-serif;
  font-weight: 700;
  font-size: var(--oscyl-ficha-nombre-size);
  line-height: 1.1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-shadow: none;
  color: var(--oscyl-ficha-nombre-color);
  margin: 0 0 6px;
}

.oscyl-artistas__grid .oscyl-artista-card__cargo {
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: var(--oscyl-ficha-cargo-size);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.3px;
  text-transform: none;
  color: var(--oscyl-ficha-cargo-color);
  margin: 0;
}


/* ==========================================================================
   SLIDER REUTILIZABLE (v2.9.0)
   Usado por [oscyl_conciertos_artista] y [oscyl_mas_artistas] — también
   disponible para cualquier futuro shortcode con carrusel horizontal.
   Estrategia: CSS scroll-snap nativo + 2 botones de flecha JS.
   Cero dependencias, accesible, SEO-friendly.
   ========================================================================== */

:root {
  --oscyl-slider-gap: 1.25rem;

  /* v2.58.0 — Este es el radio de TODAS las tarjetas de artista y concierto
     del sitio, no solo las del slider, pese al nombre.
     ---------------------------------------------------------------------
     Lo consumen `.oscyl-concierto-card` y, desde v2.58.0, `.oscyl-artista-card`
     (rejilla y los dos carruseles). Antes la de artista usaba
     `--oscyl-artista-radius`, declarada en `.oscyl-artistas`, que envuelve SOLO
     a la rejilla: las tarjetas de los carruseles cuelgan de
     `.oscyl-slider__track`, la variable no las alcanzaba, el `var()` se quedaba
     sin valor y el radio caía a **0px**. Rejilla 4, carruseles 0, conciertos 6:
     tres radios para el mismo objeto.

     🔑 Una variable declarada en el contenedor de UNO de los usos no sirve para
     un componente que se usa en varios sitios. Si el valor debe ser común, la
     declaración va en `:root`.

     ⚠️ El comentario del bloque `--slider` decía que «border-radius se hereda
     del base», y era verdad a medias: la REGLA se heredaba, la VARIABLE no. Por
     eso nadie lo miró en meses.

     ⚠️ NO renombrar esto a `--oscyl-card-radius`: ese nombre YA EXISTE, con
     valor 12px, declarado en `.oscyl-conciertos` para las tarjetas de
     `[oscyl_conciertos]`. Son dos radios distintos a propósito. */
  --oscyl-slider-card-radius: 6px;
  --oscyl-slider-nav-size: 44px;
  --oscyl-slider-nav-color: #1d1d1b;
  --oscyl-slider-nav-bg: transparent;
  --oscyl-slider-nav-border: #1d1d1b;
}

.oscyl-slider {
  position: relative;
  margin: 3rem 0;
  box-sizing: border-box;
}

.oscyl-slider *,
.oscyl-slider *::before,
.oscyl-slider *::after {
  box-sizing: border-box;
}

.oscyl-slider__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  margin: 0 0 1.75rem;

  /* v2.63.0 — las flechas bajan solas cuando el titular no cabe. Ver abajo. */
  flex-wrap: wrap;
}

/* ---------- v2.63.0 — el titular no compite con las flechas por el ancho ----
   EL PROBLEMA: las flechas ocupan 120px FIJOS de la fila (96 + el hueco), y
   ese ancho no encoge. Al estrechar la ventana, el sitio que le queda al
   titular mengua MÁS DEPRISA de lo que el `clamp()` le baja el tamaño, así que
   se parte en dos líneas dejando un hueco vacío a su derecha. Medido en el
   abono de temporada: a 885px el titular tenía 588px de los 708 del header y
   necesitaba 659 para una línea.

   🔑 Ninguna curva basada en el ancho de VENTANA puede arreglar esto, porque
   lo que resta es una cantidad FIJA en píxeles. Por eso no se toca el clamp.

   LA SOLUCIÓN, SIN NINGÚN BREAKPOINT:
   · `flex-wrap: wrap` en el header permite una segunda línea de flex.
   · `flex: 1 1 max-content` en el titular fija su base al ancho que ocuparía
     EN UNA LÍNEA. Si eso más las flechas no cabe, flex rompe la fila y el
     titular se queda con el ancho completo. El `1` de shrink evita que
     desborde cuando ni a fila completa cabe: entonces sí se parte, pero con
     todo el ancho disponible.
   · `margin-left: auto` en las flechas: al quedarse solas en su fila,
     `space-between` las mandaría a la izquierda.

   📌 Se prefiere esto a una media query porque **el punto de ruptura depende
   del TEXTO del titular**, que se escribe desde Divi y cambia por página. Un
   breakpoint fijo acertaría con un título y fallaría con el siguiente.

   ✅ Medido antes de aplicarlo, en el abono de temporada y en /temporada-26-27/:
   a 1440 nada cambia (siguen en la misma fila); a 885 y 1009 el titular pasa de
   2 líneas a 1; a 375 «Artistas de la Temporada» pasa de 2 líneas a 1 y
   «Conciertos de la Temporada» de 3 a 2. Sin desbordamiento en ningún ancho.
   -------------------------------------------------------------------------- */

.oscyl-slider__header > .oscyl-slider__titulo {
  flex: 1 1 max-content;
}

.oscyl-slider__header > .oscyl-slider__nav {
  margin-left: auto;
}

/* ---------- v2.87.0 — EN TELÉFONO, EL TITULAR SE QUEDA AL LADO DE LAS FLECHAS
   La solución de la v2.63.0 es la correcta de 768px para arriba, pero en
   teléfono las flechas bajan SIEMPRE, con cualquier título. Medido en
   /temporada-26-27/: hacen falta 354px de cabecera para «Artistas de la
   Temporada» y 472px para «Conciertos de la Temporada de abono», y el ancho
   disponible es de 342px a 428 y de 256px a 320. O sea que la segunda fila no
   es un caso excepcional ahí: es el único caso.

   📌 El cliente lo pidió explícitamente el 25-09-2026: titular más pequeño y a
   la IZQUIERDA de las flechas. (El diseño aprobado de móvil no lleva flechas
   en estos bloques, pero está desactualizado.)

   Tres piezas, y las tres hacen falta:
   · `flex-wrap: nowrap` — desactiva la segunda fila, solo en teléfono.
   · `min-width: 0` en el titular — sin esto un item flex no encoge por debajo
     de su contenido y el titular seguiría empujando a las flechas fuera.
   · `flex: 0 0 auto` en las flechas — que no las encoja el `nowrap`.

   ✅ Medido con el titular ya al lado de las flechas. Líneas que ocupa el más
   largo, «Conciertos de la Temporada de abono»:

      ancho 428 → 234px para el texto → 22px: UNA línea
      ancho 375 → 192px →  2 líneas a cualquier tamaño entre 18 y 24
      ancho 320 → 148px →  2 líneas ídem

   «Artistas de la Temporada» entra en una línea en los tres. Se elige 22px
   porque es el mayor que deja el título largo en una sola línea en el móvil
   de referencia (428). En los estrechos son dos, que es inevitable sin bajar
   a tamaños ilegibles — y ahí lo que importaba era que no bajaran las flechas.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .oscyl-slider__header {
    flex-wrap: nowrap;
    gap: 12px;
  }

  .oscyl-slider__header > .oscyl-slider__titulo {
    flex: 1 1 auto;
    min-width: 0;

    /* v2.88.0 — TOPE, no tamaño fijo. Corrige la v2.87.0.
       Aquel `font-size: 22px` tenía dos problemas, y el segundo explica el
       primero:

       · Achicaba titulares CORTOS sin necesidad. «Más conciertos» se quedaba
         en 22px pidiendo 85px con 149px libres a su derecha.
       · Y **no llegaba a aplicarse donde hacía falta**: los carruseles de
         /temporada-26-27/ tienen su propia regla, más específica, así que
         conservaban sus 36px. O sea que encogía justo los que cabían y dejaba
         intactos los que no.

       Con `min(<la fórmula de siempre>, 36px)` el tamaño lo sigue decidiendo
       `titulo_tam` desde el shortcode —que es el mando que ya existe— y aquí
       solo se le pone un techo para teléfono. Medido con «Más conciertos»
       (`titulo_tam="80"`, que en teléfono daba 56px): pasa a 36px y entra en
       UNA línea a 428, 375 y 320. */
    font-size: min(
      clamp(
        calc(var(--oscyl-slider-titulo-tam, 2.5rem) * 0.7),
        2.6vw,
        var(--oscyl-slider-titulo-tam, 2.5rem)
      ),
      36px
    );
  }

  .oscyl-slider__header > .oscyl-slider__nav {
    flex: 0 0 auto;
    margin-left: 0;
  }
}

.oscyl-slider__titulo {
  margin: 0;
  font-family: var(--oscyl-font-serif);
  font-weight: 400;
  /* v2.62.0 — el tope del clamp sale de `--oscyl-slider-titulo-tam`, que el
     shortcode escribe EN LÍNEA con el atributo `titulo_tam`. Sin atributo, el
     `var()` cae a su valor por defecto y el tamaño es EXACTAMENTE el de
     siempre.

     🚨 v2.62.1 — EL SUELO TAMBIÉN ESCALA, y esto costó un desbordamiento.
     La v2.62.0 hacía configurable solo el TECHO y dejaba el suelo clavado en
     el valor de siempre. Resultado: en móvil el atributo no hacía nada. Con
     `titulo_fuente="sans"` el titular se quedaba en 36px —un valor calibrado
     para Kepler CONDENSADA— y en Inter la palabra «CONCIERTOS» ya no dejaba
     encoger la fila del header, que empujaba las flechas 9px FUERA de la
     pantalla a 375px.

     Ahora el suelo es una fracción del techo, así que el atributo manda en
     todos los anchos. La proporción es la del diseño original y sale exacta:
     2.25 / 5.25 = 3/7  (y 1.75 / 2.5 = 0.7 en la regla base). Escribirla como
     división y no como decimal redondeado deja el valor por defecto idéntico
     al de antes, sin arrastrar un error de 4ª cifra.

     📌 Y ya no hace falta el `min()` que llevaba la v2.62.0 para el caso
     «tope más pequeño que el suelo»: con el suelo proporcional, el suelo
     siempre es menor que el techo. El problema desaparece en vez de taparse. */
  font-size: clamp(calc(var(--oscyl-slider-titulo-tam, 2.5rem) * 0.7), 2.6vw, var(--oscyl-slider-titulo-tam, 2.5rem));
  line-height: 1.15;
  color: #1d1d1b;
  letter-spacing: -0.01em;

  /* 🚨 v2.69.0 — LA CAUSA DEL TITULAR DESALINEADO CON LAS FLECHAS.
     La hoja base de Divi trae `h1, h2, h3, h4, h5, h6 { padding-bottom: 10px }`
     —pensado para separar un título del párrafo que va debajo— y este titular
     es un <h2>. En un header flex con `align-items: center` lo que se centra
     son las CAJAS, así que esos 10px que sobran por abajo empujan el TEXTO
     5px hacia arriba: justo la mitad del padding.

     Medido antes de tocarlo: 5,2px a 56px de tamaño y 5,1px a 28px. **El
     desfase NO depende del tamaño de fuente ni de la familia** —también salía
     5,5px con Inter en el abono—, porque los 10px de Divi son fijos.

     El padding no hace ninguna falta aquí —la separación con las tarjetas la
     da el `margin-bottom: 28px` del header, verificado idéntico antes y
     después—, así que se quita en el origen en vez de compensarlo. */
  padding-bottom: 0;

  /* ---- Corrección óptica de Kepler (v2.69.1) ----
     Quitar el padding dejó las CAJAS centradas, y aun así el titular seguía
     viéndose alto. Son dos desajustes distintos que se sumaban, y en la
     v2.69.0 solo se arregló uno.

     El segundo sí es de la fuente: Kepler reserva mucho más hueco abajo que
     arriba. Medido a 56px: ascenso de caja 39px contra descenso 17px. Como el
     navegador centra la CAJA, ese hueco vacío inferior sube la tinta.

     🚨 Y NO SE PUEDE MEDIR CON EL RECTÁNGULO DEL TEXTO. Ese rectángulo incluye
     el sitio de las descendentes aunque el texto no tenga ninguna —«Más
     conciertos» no tiene—, así que da el bloque por centrado cuando el ojo lo
     ve alto. Lo que hay que alinear es la BANDA DE MAYÚSCULAS: de la altura de
     la «H» a la línea base.

     El valor sale de las métricas, no del ojo:
         ajuste = altura de mayúscula / 2 − (ascenso − descenso) / 2
                = 35,1/2 − (39 − 17)/2 = 6,53px sobre 56px = 0,117em

     Va en `em` porque esta parte SÍ es proporcional al tamaño. Verificado a
     tres tamaños distintos —37px, 56px y 74px—, con desfase final ≤0,6px en
     los cuatro carruseles.

     📌 Esto rehabilita el `translateY(0.135em)` de la v2.29.2, que la v2.69.0
     había retirado por completo. Aquel valor apuntaba bien y erraba en dos
     cosas: se quedaba solo en los carruseles de temporada, y compensaba de
     más porque incluía a ojo los 5px del padding. Con el padding fuera y el
     valor sacado de la fuente, la corrección vale para los cuatro.

     ⚠️ Es de Kepler y solo de Kepler: en Inter la misma cuenta da 0,001em, o
     sea nada. Por eso `.oscyl-slider__titulo--sans` lo anula. */
  transform: translateY(0.117em);
}

.oscyl-slider__nav {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

.oscyl-slider__btn {
  width: var(--oscyl-slider-nav-size);
  height: var(--oscyl-slider-nav-size);
  display: inline-grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--oscyl-slider-nav-border);
  background: var(--oscyl-slider-nav-bg);
  color: var(--oscyl-slider-nav-color);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}

.oscyl-slider__btn:hover:not(:disabled) {
  background: var(--oscyl-slider-nav-color);
  color: #fff;
}

.oscyl-slider__btn:focus-visible {
  outline: 2px solid var(--oscyl-slider-nav-color);
  outline-offset: 3px;
}

.oscyl-slider__btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.oscyl-slider__btn svg {
  width: 18px;
  height: 18px;
  display: block;
}

/* TRACK — contenedor horizontal con scroll-snap */
.oscyl-slider__track {
  display: flex;
  gap: var(--oscyl-slider-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 4px 0 1rem;
  margin: 0;
  list-style: none;
}

.oscyl-slider__track::-webkit-scrollbar {
  display: none;
}

/* SLIDE — tarjeta individual. Ancho basado en --columnas */
.oscyl-slider__slide {
  flex: 0 0 calc((100% - (var(--cols, 4) - 1) * var(--oscyl-slider-gap)) / var(--cols, 4));
  scroll-snap-align: start;
  min-width: 0;
}

/* Aplica el nº de columnas pasado por data-columnas */
.oscyl-slider[data-columnas="1"] .oscyl-slider__track { --cols: 1; }
.oscyl-slider[data-columnas="2"] .oscyl-slider__track { --cols: 2; }
.oscyl-slider[data-columnas="3"] .oscyl-slider__track { --cols: 3; }
.oscyl-slider[data-columnas="4"] .oscyl-slider__track { --cols: 4; }
.oscyl-slider[data-columnas="5"] .oscyl-slider__track { --cols: 5; }

/* Responsive: colapsar columnas progresivamente */
@media (max-width: 1100px) {
  .oscyl-slider[data-columnas="5"] .oscyl-slider__track,
  .oscyl-slider[data-columnas="4"] .oscyl-slider__track {
    --cols: 3;
  }
}

@media (max-width: 820px) {
  .oscyl-slider[data-columnas="5"] .oscyl-slider__track,
  .oscyl-slider[data-columnas="4"] .oscyl-slider__track,
  .oscyl-slider[data-columnas="3"] .oscyl-slider__track {
    --cols: 2;
  }
}

/* 🚨 v2.96.0 — ESTA REGLA NO SE APLICA A NINGÚN CARRUSEL REAL, y no es nuevo.
   Su selector pesa 0,2,0 y las de arriba 0,3,0 (llevan el `[data-columnas]`),
   así que pierde contra todas aunque venga después: con 3, 4 y 5 gana la de
   820px (→ 2 tarjetas) y con 1 o 2 gana la base. Medido en vivo a 375px
   recorriendo las hojas de estilo: las tres reglas aplican, sus media queries
   están activas, y `--cols` sale 2. El «1.15» no se ha visto nunca.
   Se deja como está a propósito: arreglarla cambiaría TODOS los carruseles del
   sitio en teléfono de golpe. Para elegirlo bloque a bloque está el atributo
   `columnas_movil` (abajo). Si algún día se quiere para todos por defecto,
   basta con subirle el peso a `.oscyl-slider[data-columnas] .oscyl-slider__track`. */
@media (max-width: 540px) {
  .oscyl-slider .oscyl-slider__track {
    --cols: 1.15; /* deja asomar la siguiente tarjeta */
  }
}

/* v2.96.0 — `columnas_movil`: cuántas tarjetas en TELÉFONO, bloque a bloque.
   Atributo OPCIONAL de los cinco carruseles ([oscyl_artistas_temporada],
   [oscyl_conciertos_temporada], [oscyl_mas_conciertos],
   [oscyl_conciertos_artista] y [oscyl_mas_artistas]). Si no se escribe, el
   shortcode no emite `data-columnas-movil` y NINGUNA de estas reglas aplica:
   el carrusel se comporta exactamente como antes.

   POR QUÉ UN ATRIBUTO Y NO UNA REGLA POR CLASE. Se escribió primero atado a
   `.oscyl-slider--conciertos-temporada`, y al barrer las 54 páginas salió que
   ese carrusel está también en las CUATRO páginas de abono: habrían cambiado
   sin que nadie lo pidiera. Con el atributo cambia solo el bloque que lo lleva.

   ⚠️ EL PESO DEL SELECTOR ES LO IMPORTANTE. Con uno de 0,2,0 perdería igual
   que el 1,15 de arriba. Estos pesan 0,4,0 —`.oscyl-slider` + `[data-columnas]`
   + `[data-columnas-movil]` + el track— y ganan a la regla de 820px (0,3,0)
   sin depender del orden ni de `!important`.

   540 y no 767: es el corte que el propio carrusel usa para pasar a una sola
   tarjeta. Por encima, entre 541 y 820, siguen las dos de siempre. */
@media (max-width: 540px) {
  .oscyl-slider[data-columnas][data-columnas-movil="1"] .oscyl-slider__track { --cols: 1; }
  .oscyl-slider[data-columnas][data-columnas-movil="2"] .oscyl-slider__track { --cols: 2; }
}


/* ==========================================================================
   TARJETA DE CONCIERTO (dentro del slider)
   "Lo puedes encontrar en:" — card con imagen full-bleed, fecha + tipo
   arriba, título sobre gradiente inferior.
   ========================================================================== */

/* v2.21.0 — ratio 1/1 (antes 3/4) para uniformidad con el size 900×900. */
.oscyl-concierto-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--oscyl-slider-card-radius);
  background: #2a2a2a;
  aspect-ratio: 1 / 1;
  isolation: isolate;
  transform: translateZ(0); /* promoción a capa para hover suave */
}

.oscyl-concierto-card__link {
  display: block;
  width: 100%;
  height: 100%;
  position: relative;
  color: #fff;
  text-decoration: none;
}

.oscyl-concierto-card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 0.6s ease;
}

.oscyl-concierto-card__img--placeholder {
  background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
}

.oscyl-concierto-card:hover .oscyl-concierto-card__img {
  transform: scale(1.04);
}

/* Gradiente inferior para legibilidad del título */
.oscyl-concierto-card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 30%,
    rgba(0, 0, 0, 0.3) 55%,
    rgba(0, 0, 0, 0.85) 100%
  );
  z-index: 1;
  pointer-events: none;
}

/* META superior: fecha + tipo */
.oscyl-concierto-card__meta {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem;
  color: #fff;
}

.oscyl-concierto-card__fecha {
  font-family: 'Inter', -apple-system, sans-serif;
  font-weight: 500;
  font-size: 0.875rem;
  letter-spacing: 0.02em;
}

.oscyl-concierto-card__tipo {
  font-family: 'Inter', -apple-system, sans-serif;
  font-weight: 500;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  text-align: right;
  line-height: 1.3;
}

/* CONTENIDO inferior: título del concierto */
.oscyl-concierto-card__contenido {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 2;
  padding: 1.25rem;
  color: #fff;
}

.oscyl-concierto-card__titulo {
  margin: 0;
  font-family: var(--oscyl-font-serif);
  font-weight: 400;
  font-size: clamp(1.25rem, 1.8vw, 1.75rem);
  line-height: 1.1;
  color: #fff;
  letter-spacing: -0.01em;
}

.oscyl-concierto-card__excerpt {
  margin: 0.5rem 0 0;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.85);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.3s ease, opacity 0.3s ease, margin 0.3s ease;
}

.oscyl-concierto-card:hover .oscyl-concierto-card__excerpt,
.oscyl-concierto-card:focus-within .oscyl-concierto-card__excerpt {
  max-height: 5rem;
  opacity: 1;
}


/* ==========================================================================
   TARJETA DE ARTISTA DENTRO DEL SLIDER
   ==========================================================================
   Variante de .oscyl-artista-card para los carruseles de artistas:
   [oscyl_mas_artistas] y [oscyl_artistas_temporada].

   v2.39.0 — AHORA USA EL MISMO SISTEMA QUE LA REJILLA.
   Hasta v2.38.0 esto era un badge gris sólido (#2e323a) con el nombre en
   Kepler a 18px, y solo el carrusel de temporada recibía el tratamiento
   unificado de v2.34.0 mediante el modificador `--artistas-temporada`.
   Resultado: en la misma web convivían dos estéticas de tarjeta de artista
   según en qué página estuvieras.

   Al pedir el cliente que [oscyl_mas_artistas] se viera «igual que el resto»,
   lo que procedía no era añadir un tercer bloque de excepciones sino MOVER
   el sistema unificado a esta clase base, que es la que comparten los dos
   carruseles. Con eso el bloque específico de temporada se queda casi vacío
   —solo el tamaño del título del slider, que no es cosa de la tarjeta— y no
   hay tres sitios donde tocar el mismo diseño.

   Los valores no se repiten aquí: salen de las variables `--oscyl-ficha-*`
   declaradas en el bloque «FICHA DE ARTISTA» de más arriba, las mismas que
   consume la rejilla. Si hay que retocar el aspecto, se toca allí y cambia
   en los tres sitios a la vez.
   ========================================================================== */

.oscyl-artista-card--slider {
  width: 100%;
  margin: 0;
  /* aspect-ratio, overflow, border-radius y background se heredan del base */

  /* Contenedor para que el `cqw` del nombre y del cargo se mida contra el
     ancho de ESTA tarjeta. Ver la nota larga del bloque «FICHA DE ARTISTA»:
     el ancho de una tarjeta no es función del ancho de la ventana. */
  container-type: inline-size;
}

/* Anular el gradiente inferior del base — el contraste lo da la caja */
.oscyl-artista-card--slider .oscyl-artista-card__link::after {
  content: none;
}

/* Caja de texto anclada abajo a la izquierda, que crece con el nombre */
.oscyl-artista-card--slider .oscyl-artista-card__contenido {
  position: absolute;
  left: var(--oscyl-ficha-caja-margen);
  right: auto;
  bottom: var(--oscyl-ficha-caja-margen);
  z-index: 3;

  width: fit-content;
  max-width: calc(100% - var(--oscyl-ficha-caja-margen) * 2);
  box-sizing: border-box;
  padding: var(--oscyl-ficha-caja-pad);
  overflow-wrap: break-word;

  background-color: var(--oscyl-ficha-caja-bg);
  -webkit-backdrop-filter: blur(var(--oscyl-ficha-caja-blur));
  backdrop-filter: blur(var(--oscyl-ficha-caja-blur));
  border-radius: var(--oscyl-ficha-caja-radius);
  color: #ffffff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}

.oscyl-artista-card--slider .oscyl-artista-card__contenido .oscyl-artista-card__nombre {
  font-family: 'Inter', -apple-system, sans-serif;
  font-weight: 700;
  font-size: var(--oscyl-ficha-nombre-size);
  line-height: 1.1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-shadow: none;
  color: var(--oscyl-ficha-nombre-color) !important;
  margin: 0 0 6px;
}

.oscyl-artista-card--slider .oscyl-artista-card__contenido .oscyl-artista-card__cargo {
  display: block;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: var(--oscyl-ficha-cargo-size);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.3px;
  text-transform: none;
  color: var(--oscyl-ficha-cargo-color) !important;
  margin: 0;
}

/* Móvil: solo se compacta la CAJA. Los tamaños de texto NO se tocan aquí —
   ya los baja el `cqw` al estrecharse la tarjeta. Un valor fijo en una media
   query se pelearía con el cálculo automático. */
@media (max-width: 540px) {
  .oscyl-artista-card--slider .oscyl-artista-card__contenido {
    left: 12px;
    bottom: 12px;
    padding: 10px 14px;
    max-width: calc(100% - 24px);
  }
}


/* ==========================================================================
   TIPOGRAFÍAS OSCYL — Manual Courtiers (v2.13.0)
   ==========================================================================
   Sistema tipográfico oficial. Usa Kepler Std Light Condensed Display
   (auto-hosteada en /fonts/) e Inter (Google Fonts, ya enqueueada).

   Escala basada en el manual de Courtiers, adaptada con clamp() para que
   los tamaños escalen entre móvil (~375px) y desktop (~1920px) sin media
   queries — el primer valor es el mínimo en móvil, el segundo es la
   función de escalado por viewport, el tercero es el máximo en desktop.

   Cómo aplicar:
     1. Las etiquetas semánticas (h1-h4, p) ya tienen el estilo por defecto
        del manual. Para usarlas en Divi: módulo de texto + selecciona el
        nivel de heading correspondiente.
     2. Para variantes específicas (H2-Std en sans, H4-Cards bold, etc.)
        usa las clases utility .h2-std, .h4-cards, etc. desde el campo
        "CSS Class" del módulo Divi o como class en HTML directo.
     3. Para body intermedio entre p y small usa .body-subhead.
   ========================================================================== */

/* ---------- Auto-host de Kepler Std Light Condensed Display ---------- */
@font-face {
  font-family: 'Kepler Std';
  font-style: normal;
  font-weight: 300; /* Light */
  font-display: swap;
  src: url('fonts/KeplerStd-LightCondensedDisplay.woff2') format('woff2'),
       url('fonts/KeplerStd-LightCondensedDisplay.woff')  format('woff');
  /* Light + Condensed + Display variant — única que el manual Courtiers
     usa para H1, H2-Serif y H4-Conciertos. Si más adelante necesitamos
     Regular o Bold, se añaden con su propio @font-face. */
}

/* ---------- Variables: stack tipográfico + escala ---------- */
:root {
  /* Familias */
  --oscyl-font-serif: 'Kepler Std', 'Playfair Display', Georgia, serif;
  --oscyl-font-sans:  'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  /* Letter-spacing común del manual */
  --oscyl-tracking-tight: -0.023em;  /* equivalente a -23px del manual a 1000px */
}

/* ---------- Defaults para etiquetas semánticas (H1-H4, p) ---------- */
/* Cualquier h1, h2, h3, h4, p del frontend hereda el estilo del manual.
   Divi puede sobrescribirlo desde su Theme Customizer si hace falta. */

h1,
.h1 {
  font-family: var(--oscyl-font-serif);
  font-weight: 300;
  font-size: clamp(48px, 6vw + 12px, 115px);
  line-height: 0.73;            /* 84/115 */
  letter-spacing: var(--oscyl-tracking-tight);
}

h2,
.h2-serif {
  font-family: var(--oscyl-font-serif);
  font-weight: 300;
  font-size: clamp(38px, 4.5vw + 10px, 90px);
  line-height: 0.83;            /* 75/90 */
  letter-spacing: var(--oscyl-tracking-tight);
}

.h2-std {
  /* Variante sans-serif del H2 — para subtítulos modernos */
  font-family: var(--oscyl-font-sans);
  font-weight: 400;
  font-size: clamp(28px, 2.5vw + 14px, 53px);
  line-height: 1.19;            /* 63/53 */
  letter-spacing: var(--oscyl-tracking-tight);
}

h3,
.h3 {
  font-family: var(--oscyl-font-sans);
  font-weight: 700;
  font-size: clamp(22px, 1.8vw + 12px, 37px);
  line-height: 0.89;            /* 33/37 */
  letter-spacing: var(--oscyl-tracking-tight);
  text-transform: uppercase;
}

h4,
.h4 {
  /* H4 default = Cards (sans, bold) */
  font-family: var(--oscyl-font-sans);
  font-weight: 700;
  font-size: clamp(18px, 1.4vw + 10px, 29px);
  line-height: 1.14;            /* 33/29 */
  letter-spacing: var(--oscyl-tracking-tight);
}

.h4-cards {
  /* Alias explícito de H4 */
  font-family: var(--oscyl-font-sans);
  font-weight: 700;
  font-size: clamp(18px, 1.4vw + 10px, 29px);
  line-height: 1.14;
  letter-spacing: var(--oscyl-tracking-tight);
}

.h4-conciertos {
  /* Variante serif del H4 — para títulos de concierto en single */
  font-family: var(--oscyl-font-serif);
  font-weight: 300;
  font-size: clamp(26px, 2.2vw + 14px, 46px);
  line-height: 0.72;            /* 33/46 */
  letter-spacing: var(--oscyl-tracking-tight);
}

/* ---------- Body + variantes intermedias ---------- */
body,
.body-regular {
  font-family: var(--oscyl-font-sans);
  font-weight: 300;
  font-size: clamp(15px, 0.4vw + 13px, 16px);
  line-height: 1.25;            /* 20/16 */
  letter-spacing: var(--oscyl-tracking-tight);
}

.body-subhead {
  /* Body más grande para introducciones cortas (ej. lead de un single) */
  font-family: var(--oscyl-font-sans);
  font-weight: 400;
  font-size: clamp(18px, 0.8vw + 14px, 24px);
  line-height: 1.375;           /* 33/24 */
  letter-spacing: var(--oscyl-tracking-tight);
}

.body-small,
small {
  font-family: var(--oscyl-font-sans);
  font-weight: 300;
  font-size: clamp(11px, 0.2vw + 10px, 12px);
  line-height: 1.33;            /* 16/12 */
  letter-spacing: var(--oscyl-tracking-tight);
}

/* ---------- Util: Info para tarjetas de concierto ---------- */
.info-conciertos {
  /* "JUE 12 FEB 19:30 · SALA SINFÓNICA" en cards de programación */
  font-family: var(--oscyl-font-sans);
  font-weight: 300;
  font-size: clamp(14px, 0.4vw + 12px, 18px);
  line-height: 1.11;            /* 20/18 */
  letter-spacing: var(--oscyl-tracking-tight);
}

/* ---------- Util: categoría / etiqueta destacada en mayúsculas ---------- */
.categoria-conciertos {
  /* "CATEGORIA CONCIERTOS" del manual — uppercase tracking ligero */
  font-family: var(--oscyl-font-sans);
  font-weight: 700;
  font-size: clamp(12px, 0.3vw + 11px, 14px);
  line-height: 1.2;
  letter-spacing: 0.06em;       /* tracking abierto en mayúsculas, no -23 */
  text-transform: uppercase;
}


/* ==========================================================================
   NOTICIAS — Módulo Blog de Divi
   v2.21.0

   Las noticias se gestionan como entradas nativas de WordPress y se listan
   con el módulo Blog del Theme Builder de Divi. No tenemos un shortcode
   propio (el render lo hace Divi). Forzamos aspect-ratio 1/1 sobre la
   imagen destacada del listado para que case con conciertos y artistas.

   Selectores: .et_pb_post_main_image y .et_pb_image_container son los
   wrappers nativos del módulo Blog. .et_pb_post_main_image envuelve la
   <img> de la featured image en cada artículo del grid/listado. La regla
   actúa solo cuando la página NO es el single (en single-post la imagen
   se renderiza a tamaño completo, sin recortar).
   ========================================================================== */
.et_pb_blog_grid .et_pb_post_main_image,
.et_pb_posts .et_pb_post_main_image,
.et_pb_post.et_pb_post_main_image,
.et_pb_blog_grid article.et_pb_post .et_pb_image_container,
.et_pb_posts article.et_pb_post .et_pb_image_container {
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

.et_pb_blog_grid .et_pb_post_main_image a,
.et_pb_posts .et_pb_post_main_image a,
.et_pb_blog_grid .et_pb_post_main_image img,
.et_pb_posts .et_pb_post_main_image img,
.et_pb_blog_grid article.et_pb_post .et_pb_image_container img,
.et_pb_posts article.et_pb_post .et_pb_image_container img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center;
}


/* ==========================================================================
   SLIDER DE NOTICIAS (módulo Divi Post Slider) — home
   v2.22.0

   El módulo Divi Post Slider que renderiza "Últimas noticias" sobre el hero
   lleva la clase CSS personalizada `oscyl-slider-noticias` (añadida desde
   el editor de Divi → Avanzado → Atributos → class).

   Cambios visuales aplicados aquí:
     - Se ocultan los dots nativos de Divi (.et-pb-controllers).
     - Las flechas nativas .et-pb-arrow-prev / .et-pb-arrow-next pasan de
       gigantes pegadas a los laterales en posición vertical centrada, a
       dos botones circulares blancos pequeños abajo a la izquierda del
       slide, replicando el mockup de diseño.

   Pre-requisito en Divi (no es CSS): el módulo Post Slider tiene que tener
   activada la opción "Mostrar flechas" y desactivada la opción "Mostrar
   barra de control / puntos". Si los dots siguen visibles, este CSS los
   tapa de todas formas con display: none.
   ========================================================================== */

/* Ocultar dots de paginación */
.oscyl-slider-noticias .et-pb-controllers {
  display: none !important;
}

/* v2.23.19 — Quitar el overlay negro semitransparente (rgba(0,0,0,0.3)) que Divi
   pone sobre la imagen del slide. No está en el diseño; el slider va sin oscurecer. */
.oscyl-slider-noticias .et_pb_slide_overlay_container {
  display: none !important;
}

/* --------------------------------------------------------------------------
   v2.53.0 — ALINEACIÓN DE LAS FLECHAS, EL BOTÓN Y EL TEXTO
   --------------------------------------------------------------------------
   Dos medidas gobiernan la barra inferior del slider, y las comparten las
   flechas y el botón "Leer más" para que NO puedan descuadrarse: si mañana se
   cambia el tamaño o la separación, los dos se mueven juntos.

     --oscyl-nav-bottom : distancia al fondo del módulo
     --oscyl-nav-size   : lado del círculo de la flecha (y alto del botón)
     --oscyl-nav-gap    : hueco entre las dos flechas

   Antes de v2.53.0 el botón vivía en el flujo del texto, y ese bloque lo
   centra Divi verticalmente (`display: table-cell; vertical-align: middle`).
   Como el bloque cambia de alto con la longitud del titular, la base del
   botón subía y bajaba: medido, 19px de desfase a 1440 y 20px en móvil,
   variando además entre un slide y otro. Las flechas, en `position:absolute`,
   no se movían nunca. De ahí que el botón pareciera "subirse" con los textos
   cortos.
   -------------------------------------------------------------------------- */
.oscyl-slider-noticias {
  --oscyl-nav-bottom: 28px;
  --oscyl-nav-size: 33px;
  --oscyl-nav-gap: 12px;
  --oscyl-nav-sep: 24px;   /* separación mínima entre el texto y la barra */
}

/* El contenido del slide llena la celda, así que su base deja de depender del
   largo del texto; `margin-top: auto` empuja el botón al fondo y el texto se
   queda arriba, donde ya estaba (verificado: el titular no se mueve ni 1px).

   ⚠️ Sustituye al `padding-bottom: 40px` de v2.22.2, que reservaba hueco para
   que el extracto no pisara las flechas. Ya no hace falta: el botón ancla el
   fondo y el texto queda por encima de él. */
.oscyl-slider-noticias .et_pb_slide_description {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding-bottom: 0 !important;
}

/* v2.54.0 — Titular a DOS líneas como máximo, con puntos suspensivos.
   El alto del slide es fijo, así que un titular largo se comía el hueco hasta
   la barra de flechas y el botón. Medido antes del recorte:

     2484px .......... 3 líneas, 42px de hueco
     1112px .......... 3 y 4 líneas según la noticia, 45px y 24px
     375px ........... 6 líneas y 0px — el texto tocaba la barra

   Con el tope en dos líneas el hueco queda entre 59 y 67px en todos los casos.

   ⚠️ Recorta de verdad: en móvil un titular de 156 caracteres deja ver unos 80.
   Si algún día se prefiere ver más en pantallas pequeñas, la salida es subir el
   tope SOLO en el bloque de móvil de más abajo, no aquí. */
.oscyl-slider-noticias .et_pb_slide_title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;

  /* v2.54.1 — Separación GARANTIZADA con la barra de abajo.
     El `margin-top: auto` del botón solo separa cuando SOBRA espacio, y al
     recortar el titular a dos líneas dejó de sobrar: el slide se encogió con
     él —la descripción pasó de 166px a 106px— y el contenido la llenaba
     exacto, así que el `auto` se quedaba en 0 y el texto volvía a tocar las
     flechas. Este margen no depende de que sobre nada.

     No descuadra la barra: el bloque crece, el módulo crece con él, y como las
     flechas se anclan a su fondo y el botón al final del flujo, los dos bajan
     lo mismo. Verificado: siguen a 0px en 2484, 1440 y 375. */
  margin-bottom: var(--oscyl-nav-sep);
}

/* La CAJA del botón toma el alto de la flecha y centra el botón dentro. Con el
   mismo `bottom` y el mismo alto, los centros coinciden por construcción, sin
   números mágicos que recalcular si cambia el tamaño de las flechas.

   ⚠️ v2.53.1 — El alto se le pone al WRAPPER, no al botón, y eso no es un
   capricho: `.et_pb_more_button` es un `<a>` que Divi gobierna con sus propias
   reglas y **se come el `height`** (declarado 33px, computaba 30px). Se veía
   solo en monitores anchos, donde el desfase de 1,5px —media diferencia de
   altura— se hacía perceptible. El wrapper es un `<div>` sin estilos de Divi
   compitiendo, así que ahí el alto sí manda; el botón conserva su altura
   natural y queda centrado dentro. */
.oscyl-slider-noticias .et_pb_button_wrapper {
  margin-top: auto;
  margin-bottom: var(--oscyl-nav-bottom);
  height: var(--oscyl-nav-size);
  display: flex;
  align-items: center;
}

/* --------------------------------------------------------------------------
   v2.53.0 — ALINEACIÓN HORIZONTAL CON EL RESTO DE LA COLUMNA
   --------------------------------------------------------------------------
   Divi mete el contenido del slide DOS veces hacia dentro: un `padding` del
   6% en `.et_pb_slide` y un `width: 88%` centrado en `.et_pb_container`. Los
   dos son PORCENTUALES, así que crecen con el ancho de la pantalla.

   En el módulo había un `margin-left: -35px` puesto desde Divi para
   compensarlos. Un valor fijo no puede compensar un porcentaje: solo cuadra a
   un ancho concreto. Medido antes del arreglo, el texto de la noticia quedaba
   5px a la izquierda de la columna a 1440px y 12px a 1100px, mientras el
   rótulo "Últimas noticias" y el titular del hero iban al borde.

   🚨 REQUISITO EN DIVI: hay que QUITAR el `margin-left: -35px` del módulo
   (ajustes del módulo → Diseño → Espaciado → Margen). Sin eso, este bloque
   deja el texto 35px a la izquierda. No se puede forzar desde aquí sin
   duplicar el valor en dos sitios.
   -------------------------------------------------------------------------- */
.oscyl-slider-noticias .et_pb_slide {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

.oscyl-slider-noticias .et_pb_container {
  width: 100% !important;
  max-width: 100% !important;
}

/* Flechas: v2.23.19 — iconos SVG oficiales (círculo con borde blanco + flecha,
   uploads/arrow-left.svg / arrow-right.svg). El SVG YA incluye el círculo, así que
   el botón no lleva border ni glifo de icon-font: solo el SVG como background. */
.oscyl-slider-noticias .et-pb-arrow-prev,
.oscyl-slider-noticias .et-pb-arrow-next {
  top: auto !important;
  bottom: var(--oscyl-nav-bottom) !important;
  transform: none !important;
  margin: 0 !important;

  width: var(--oscyl-nav-size) !important;
  height: var(--oscyl-nav-size) !important;
  border: none !important;
  background-color: transparent !important;
  background-repeat: no-repeat !important;
  background-position: center !important;
  background-size: contain !important;
  opacity: 1 !important;
  padding: 0 !important;
  transition: opacity 0.2s ease;
}

.oscyl-slider-noticias .et-pb-arrow-prev {
  background-image: url('img/oscyl-arrow-left.svg') !important;
}

.oscyl-slider-noticias .et-pb-arrow-next {
  background-image: url('img/oscyl-arrow-right.svg') !important;
}

/* Posición horizontal: las dos flechas pegadas a la izquierda del bloque,
   con la "next" inmediatamente al lado de la "prev".

   v2.53.0 — `left: 0` en vez de 32px. Los 32px compensaban a ojo el padding
   porcentual del slide; ahora ese padding está anulado arriba, así que el 0
   deja las flechas en el borde de la columna, con el texto y el titular.
   La separación entre ambas se deriva del tamaño y del hueco, para que siga
   siendo la misma de siempre si algún día cambia el tamaño del círculo. */
.oscyl-slider-noticias .et-pb-arrow-prev {
  left: 0 !important;
  right: auto !important;
}

.oscyl-slider-noticias .et-pb-arrow-next {
  left: calc(var(--oscyl-nav-size) + var(--oscyl-nav-gap)) !important;
  right: auto !important;
}

/* v2.23.19 — Ocultar el glifo de icon-font de Divi: ahora la flecha es el SVG de
   background (el glifo se solapaba con la flecha del SVG). */
.oscyl-slider-noticias .et-pb-arrow-prev:before,
.oscyl-slider-noticias .et-pb-arrow-next:before {
  content: "" !important;
  display: none !important;
}

/* Hover discreto: leve atenuación (antes background+border, que ahora pisarían el SVG). */
.oscyl-slider-noticias .et-pb-arrow-prev:hover,
.oscyl-slider-noticias .et-pb-arrow-next:hover {
  opacity: 0.7 !important;
}

/* En móvil estrecho compactar margen y bajar un pelín.
   v2.23.19 — flechas a 30px (SVG) y reposicionadas con el gap correcto.
   v2.53.0 — pasa a redefinir SOLO las tres variables. Las reglas de arriba
   (flechas, botón y su margen inferior) las leen todas, así que el botón
   "Leer más" sigue al tamaño y a la altura de las flechas también aquí, sin
   repetir ni un valor. El gap de 8px conserva la separación de v2.23.19. */
@media (max-width: 600px) {
  .oscyl-slider-noticias {
    --oscyl-nav-bottom: 20px;
    --oscyl-nav-size: 30px;
    --oscyl-nav-gap: 8px;
  }
}


/* ==========================================================================
   CARRUSEL DE DESTACADOS DE LA HOME (mobile/tablet)
   v2.23.2

   El bloque de "PROGRAMACIÓN internacional / UNA ORQUESTA impacto / PARA TODA
   LA comunidad" es una Divi row con 3 columnas. En desktop se ve como grid
   3 columnas tradicional. En tablet y móvil (≤980px) lo convertimos en un
   carrusel horizontal con scroll-snap nativo (swipe táctil), sin scrollbar
   visible y dejando asomar la siguiente tarjeta para que el usuario sepa
   que hay más contenido a la derecha.

   Pre-requisito Divi (NO CSS): al row hay que asignarle la clase CSS
   personalizada `oscyl-home-destacados` desde:
     Editor Divi → row settings → Avanzado → Atributos → Añadir atributo →
       selecciona `class` → valor: oscyl-home-destacados

   El número de columnas dentro del row es libre (3, 4, 5...) — el CSS no
   asume una cantidad concreta, las tarjetas siempre ocupan 85% del row
   y el scroll-snap-align: start hace que se encajen una a una al swipear.
   ========================================================================== */

/* v2.23.18 — Efecto ZOOM en hover sobre la imagen de fondo de cada columna.
   La imagen es un background-image de la columna Divi (background-size: cover).
   Para hacer zoom SOLO de la imagen (sin escalar el texto ni la caja), se usa un
   pseudo-elemento ::before que HEREDA el background de la columna (background-image:
   inherit) y se le aplica transform: scale en hover. El overflow:hidden de la columna
   recorta el desbordamiento, dando el efecto de zoom limpio.
   - El texto/caja (hijos directos) se elevan con z-index:1 para quedar por encima.
   - pointer-events:none en el ::before para no interferir con clics ni con el scroll
     del carrusel en móvil/tablet.
   - Funciona en desktop (hover de ratón) y al tocar la tarjeta en táctil (carrusel). */
.oscyl-home-destacados > .et_pb_column {
  position: relative;
  overflow: hidden !important;
}

.oscyl-home-destacados > .et_pb_column::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: inherit;       /* hereda la imagen de fondo de la columna */
  background-size: cover;
  background-position: center;
  z-index: 0;
  transition: transform 0.6s ease;
  pointer-events: none;
}

.oscyl-home-destacados > .et_pb_column:hover::before {
  transform: scale(1.08);
}

/* El contenido (título, texto, caja) por encima de la imagen del ::before */
.oscyl-home-destacados > .et_pb_column > * {
  position: relative;
  z-index: 1;
}

/* ---------- Titulares que se adaptan al ancho de la caja (v2.42.0) ----------
   En escritorio las tres columnas se reparten el ancho de la fila, así que al
   estrechar la ventana la caja de texto se queda muy angosta y «PROGRAMACIÓN»
   —una sola palabra de 12 letras— se partía por la mitad: «PROGRAMACI / ÓN».

   Medido en la home:

     viewport 1600 → caja 280px → 28px entra en 1 línea
     viewport 1280 → caja 223px → 28px necesita 224px y NO entra
     viewport 1000 → caja 174px → 28px necesita 224px, se parte
     viewport  981 → caja 170px → ídem (es el escritorio más estrecho)

   Se usa `cqw` y NO `vw` porque lo que aprieta es el ancho de la CAJA, no el
   de la ventana: a ≤980px este mismo bloque se convierte en carrusel y cada
   columna pasa al 85-90% del ancho, o sea que la caja de móvil es MUCHO más
   ancha que la de un escritorio estrecho. Una regla en `vw` tendría que
   invertirse a mitad de camino para acertar en los dos sitios.

   El tope del `clamp` son los 28px / 50px de diseño, así que por encima de
   ~233px de caja no cambia absolutamente nada: verificado a 1600px, donde el
   resultado es idéntico con y sin esta regla.

   Va dentro de `min-width: 981px` porque tablet y móvil tienen AHORA su propio
   bloque justo debajo, con un coeficiente distinto. Hasta la v2.72.0 no existía:
   el cliente había pedido no tocarlos, y cambió de criterio el 02-09-2026 al ver
   que «PROGRAMACIÓN» partía la última letra en su móvil.

   ⚠️ ESPECIFICIDAD — no simplificar el selector. La regla que compite es la
   que compila Divi para los módulos, `.et_pb_text_6 .et_pb_text_inner h3`
   (0,2,1), y su hoja carga DESPUÉS que esta. Un selector de dos clases
   empataría y perdería por orden. Con `.et_pb_text` en medio son (0,3,1) y
   gana sin recurrir a `!important` — misma decisión que en v2.29.2.
   Además se ancla a `.oscyl-home-destacados` y no a `.et_pb_text_6`, que es
   un número que Divi reasigna al reordenar módulos. */
@media (min-width: 981px) {
  .oscyl-home-destacados .et_pb_text_inner {
    container-type: inline-size;
  }

  /* v2.43.0 — el coeficiente baja de 12cqw a 9.6cqw.
     Lo manda el titular MÁS LARGO, «UNA ORQUESTA CON», porque las tres cajas
     son gemelas y con tamaños distintos parecerían un error. Medido: para que
     entre en una línea hace falta como mucho `28 × ancho / 285`, o sea 9.82cqw;
     se deja en 9.6 por margen.

     Dato que apareció al medirlo: ese titular **nunca ha cabido en una línea**,
     ni siquiera a 1600px, donde necesita 285px y la caja da 280. No era un
     problema de estrechar la ventana; llevaba partido desde el principio.

     Coste asumido: los tres titulares bajan ~20% en todo el escritorio
     (28 → 26.8 a 1600px, 26.8 → 21.4 a 1280). La alternativa sin coste sería
     acortar el texto del centro a «UNA ORQUESTA» y bajar el «con» a la línea
     en script: con eso el más largo pasa a ser «PROGRAMACIÓN» y el coeficiente
     podría volver a 12cqw. Es cambio de contenido, no de código. */
  .oscyl-home-destacados .et_pb_text .et_pb_text_inner h3 {
    font-size: clamp(15px, 9.6cqw, 28px);
  }

  /* El h4 en script («internacional», «impacto», «comunidad») nunca llegaba a
     partirse, pero se escala en la misma proporción para que la pareja
     conserve su relación de tamaños. Sin esto, con el h3 reducido un 25% y el
     h4 intacto, el contraste entre ambos se disparaba. */
  .oscyl-home-destacados .et_pb_text .et_pb_text_inner h4 {
    font-size: clamp(26px, 22cqw, 50px);
  }
}

/* v2.72.0 — LOS TRES TITULARES TAMBIÉN SE AJUSTAN EN TABLET Y MÓVIL
   ------------------------------------------------------------------
   Por debajo de 981px no aplicaba NADA de lo de arriba y mandaba el 28px fijo
   que compila Divi. Medido a 390px: la caja del texto son 211px y
   «PROGRAMACIÓN» a 28px pide 224px. Se queda a 13px — un 6%— y por eso saltaba
   solo la «N» a la segunda línea. Y «UNA ORQUESTA CON» iba a TRES líneas.

   ⚠️ COEFICIENTE PROPIO, distinto al 9.6cqw del escritorio. Con el mismo 9.6
   el titular caería a 20,2px en un móvil de 390px; el cliente prefirió quedarse
   cerca de los 28px de partida (eligió la «opción B» el 02-09-2026).
   El techo real lo marca «PROGRAMACIÓN», que pide `8,0 × tamaño`: cabe hasta
   12.5cqw, así que 11.5 deja un 8% de margen.

   Medido con esta regla, ancho de ventana → caja → tamaño:
      320px → 173px → 19,87px · pide 158,9px · UNA LÍNEA
      390px → 211px → 24,22px · pide 193,7px · UNA LÍNEA
      767px → 391px → 28px (tope) · UNA LÍNEA
      980px → 443px → 28px (tope) · UNA LÍNEA
   El tope de 28px se alcanza a partir de ~449px de ventana.

   📌 «UNA ORQUESTA CON» sigue en DOS líneas en móvil, pero partiendo entre
   palabras y no por la mitad de una; antes eran tres. Para que cayera en una
   sola harían falta 20,9px, o sea volver al 9.6cqw. Es el mismo tira y afloja
   que ya obligó a bajar de 12 a 9.6 en escritorio: manda el titular más largo.

   🔄 v2.86.0 (25-09-2026) — EL CLIENTE CAMBIA DE CRITERIO Y PIDE UNA LÍNEA.
   Se revierte aquella elección: el coeficiente baja de 11.5 a 9.6cqw, el mismo
   que escritorio. Medido a 428px, caja de 231px:

      con 11.5cqw → 26,58px → «UNA ORQUESTA CON» pide 268px → NO entra
      con  9.6cqw → 22,19px → pide 223px → ENTRA, con 8px de margen

   Y no se puede tocar solo la caja del medio: las tres son gemelas y con
   tamaños distintos parecerían un error. Así que **el coste es que los tres
   titulares bajan un 16%** en tablet y móvil, de 26,6 a 22,2px a 428px.

   Se descartó la alternativa sin coste que proponía el comentario de abajo
   —pasar «CON» al h4 en script— porque **no se puede tocar el texto**: el
   reparto en mayúsculas/script es del diseño aprobado.

   📌 Con este cambio los dos bloques, escritorio y móvil, llevan YA LOS MISMOS
   coeficientes (9.6 y 22). Se dejan separados a propósito, porque documentan
   decisiones distintas y el día que uno vuelva a divergir el sitio está hecho.
   ⚠️ Pero eso significa que **un cambio aquí hay que mirarlo también arriba**.

   El h4 va con el MISMO factor de proporción que arriba (22/9.6 = 2,29), o sea
   11.5 × 2,29 = 26.4cqw. Sin esto el h3 encogería y la palabra en script se
   quedaría clavada en 50px, descompensando la pareja — exactamente lo que avisa
   el comentario del bloque de escritorio.

   ⚠️ El `container-type` hay que REPETIRLO. El de arriba también está encerrado
   en `min-width: 981px`, y sin contenedor de consulta las unidades `cqw` no dan
   error: se resuelven contra la VENTANA, que aquí es 2,5 veces la caja. */
@media (max-width: 980px) {
  .oscyl-home-destacados .et_pb_text_inner {
    container-type: inline-size;
  }

  .oscyl-home-destacados .et_pb_text .et_pb_text_inner h3 {
    /* v2.86.0 — de 11.5 a 9.6cqw para que «UNA ORQUESTA CON» entre en una línea. */
    font-size: clamp(15px, 9.6cqw, 28px);
  }

  .oscyl-home-destacados .et_pb_text .et_pb_text_inner h4 {
    /* v2.86.0 — el h4 acompaña al h3 con el mismo factor de siempre (2,29):
       9.6 × 2,29 = 22cqw. Si se deja en 26.4 mientras el h3 baja, la palabra en
       script se queda clavada en su tope de 50px y la pareja se descompensa —
       que es justo lo que avisa el comentario del bloque de escritorio. */
    font-size: clamp(26px, 22cqw, 50px);
  }
}

@media (max-width: 980px) {
  .oscyl-home-destacados {
    /* La row pasa de "fila de columnas" estática a contenedor con scroll
       horizontal. Mantenemos flex-direction row + nowrap para que las
       columnas hijas se queden en una sola fila virtual de ancho amplio. */
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 16px;
    padding-left: 5%;
    padding-right: 5%;
    box-sizing: border-box;

    /* Ocultar scrollbar */
    scrollbar-width: none;        /* Firefox */
    -ms-overflow-style: none;     /* IE/Edge legacy */
  }

  .oscyl-home-destacados::-webkit-scrollbar {
    display: none;                /* Chrome / Safari / nuevos Edge */
  }

  /* Cada columna ocupa el 85% del row; el 15% restante asoma la siguiente */
  .oscyl-home-destacados > .et_pb_column {
    flex: 0 0 85% !important;
    width: 85% !important;
    max-width: 85% !important;
    margin: 0 !important;
    scroll-snap-align: start;
  }
}

/* En móvil estrecho cada tarjeta ocupa más espacio para no quedar diminuta. */
@media (max-width: 600px) {
  .oscyl-home-destacados {
    gap: 12px;
    padding-left: 4%;
    padding-right: 4%;
  }
  .oscyl-home-destacados > .et_pb_column {
    flex: 0 0 90% !important;
    width: 90% !important;
    max-width: 90% !important;
  }
}

/* ==========================================================================
   HEADER DE DIVI: NO CAPTURAR CLICS EN SU ZONA VACÍA (v2.26.9)
   --------------------------------------------------------------------------
   `.et-l--header` es `position: fixed` con `z-index: 100001` y mide unos
   200px de alto a lo ancho de toda la página, con el fondo TRANSPARENTE
   mientras no se hace scroll. Resultado: se tragaba los clics de cualquier
   elemento del contenido que cayera en esa franja, aunque el header no se
   viera. No era un problema de un elemento concreto — afectaba a los 200px
   superiores de CUALQUIER página del sitio.

   Lo destapó el breadcrumb «Atrás» de las fichas (y=114..131, con 86px de
   solape): se veía perfectamente y no había forma de pulsarlo. Verificado con
   `document.elementsFromPoint()`, que devolvía la sección del header por
   encima del enlace.

   Fix: los contenedores del header dejan pasar el puntero y solo lo capturan
   sus elementos interactivos.

   OJO — acotado a `body:not(.oscyl-scrolled)` A PROPÓSITO. Sin scroll el
   header es transparente y no debe capturar nada; pero al hacer scroll SÍ
   tiene fondo (el translúcido con blur de la sección scrolled), y entonces
   debe volver a tragarse los clics para que no se pulse un enlace que está
   visualmente detrás de la barra.

   Verificado tras aplicarlo: los 7 elementos interactivos del header
   (hamburguesa, EN, ES, los dos logos y los dos botones CTA) siguen
   respondiendo. Los dos «enlaces sin texto» son los logos superpuestos del
   cross-fade y apuntan los dos a la home, así que da igual cuál gane el
   hit test.
   ========================================================================== */
body:not(.oscyl-scrolled) .et-l--header,
body:not(.oscyl-scrolled) .et-l--header .et_builder_inner_content,
body:not(.oscyl-scrolled) .et-l--header .et_pb_section,
body:not(.oscyl-scrolled) .et-l--header .et_pb_row,
body:not(.oscyl-scrolled) .et-l--header .et_pb_column {
  pointer-events: none;
}

body:not(.oscyl-scrolled) .et-l--header a,
body:not(.oscyl-scrolled) .et-l--header button,
body:not(.oscyl-scrolled) .et-l--header input,
body:not(.oscyl-scrolled) .et-l--header select,
body:not(.oscyl-scrolled) .et-l--header [role="button"] {
  pointer-events: auto;
}

/* ==========================================================================
   BREADCRUMB «ATRÁS» (v2.26.9)
   --------------------------------------------------------------------------
   Enlace de vuelta de las fichas interiores, según el mockup
   `diseño/1conciertos/1.3.1.Plantilla Abono.png`. Va sobre el hero terracota,
   así que es SIEMPRE blanco.

   El icono NO puede ser un carácter Unicode: la flecha del diseño tiene la
   punta en ÁNGULO RECTO (un brazo horizontal y otro vertical formando esquina
   arriba-izquierda, más una diagonal saliendo de esa esquina), y ningún glifo
   la reproduce — `↖` U+2196 lleva punta en V. Va como SVG inline en el HTML
   del enlace, con `aria-hidden="true"` para que el lector de pantalla lea
   solo «Atrás».

   Medidas tomadas del mockup: flecha 9×9 px, hueco de 10 px, texto 38×13 px
   → subrayado de 57 px. El ancho renderizado coincide exactamente.

   Dos decisiones a respetar:
   · El subrayado es `border-bottom`, NO `text-decoration`: en el diseño la
     línea pasa por debajo de la flecha además del texto, y `text-decoration`
     solo subrayaría el texto.
   · `line-height: 1` y `padding-bottom: 0` NO son arbitrarios. El diseño pone
     la línea a 2px de la línea base del texto y a 3px del pie de la flecha.
     Con `line-height: 1.2` el semi-interlineado metía ~3,6px por debajo de la
     base antes de llegar al borde y la línea quedaba lejos. Si algún día el
     breadcrumb tuviera que ocupar DOS líneas, habría que volver a 1.2 y mover
     el subrayado a un pseudo-elemento, porque no existe el padding negativo.

   Uso (módulo Texto o Código de Divi):
   <a class="oscyl-atras" href="/miradas/"><svg viewBox="0 0 10 10"
      aria-hidden="true"><path d="M.5 8.5V.5h8"/><path d="M.5.5 9.5 9.5"/>
      </svg>Atrás</a>
   ========================================================================== */
.oscyl-atras {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: #fff;
  font-family: var(--oscyl-font-sans, 'Inter', sans-serif);
  font-size: 16px;
  font-weight: 300;
  line-height: 1;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 0;
  transition: opacity 0.2s ease;
}

.oscyl-atras:hover,
.oscyl-atras:focus {
  color: #fff;
  opacity: 0.7;
}

.oscyl-atras svg {
  width: 10px;
  height: 10px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
}

/* ==========================================================================
   SELECTOR DE SUB-ABONOS / «RUTAS» (v2.28.0)
   --------------------------------------------------------------------------
   Aspecto del selector de la página de Proximidad, según el mockup del
   cliente: pastilla terracota de esquinas suaves, texto blanco y flecha
   blanca. Distinto de los selects normales del módulo, que son blancos con
   borde gris y radio de 50px.

   Se aplica SOLO al modificador `--rutas`, que pinta el shortcode cuando
   lleva `filtro_abono="hijos"`. Los selects del resto de listados no se tocan.

   Hereda del bloque base `.oscyl-conciertos__select`: el `appearance: none`,
   el `text-overflow: ellipsis` y el `max-width: 100%`. Ese truncado importa
   aquí más que en ningún sitio, porque una de las rutas se llama «Villafranca
   del Bierzo - Ponferrada - Astorga - La Bañeza - Benavente» (v2.24.4).

   La lista desplegada la pinta el sistema operativo y NO se puede estilar
   desde CSS: sale con el fondo claro nativo, que es justo lo que muestra el
   mockup.
   ========================================================================== */
.oscyl-conciertos__campo--rutas {
  /* Ancho fijo como en el mockup, pero sin pasarse del contenedor en móvil. */
  flex: 0 1 280px;
  max-width: 100%;
  min-width: 0;
}

.oscyl-conciertos__select--rutas {
  color: #ffffff;
  background-color: var(--oscyl-single-terracota, #b5533c);
  border: 1px solid var(--oscyl-single-terracota, #b5533c);
  border-radius: 4px;
  font-weight: 500;
  /* Flecha blanca: el caret heredado es #1a1a1a y sobre el terracota apenas
     se distingue. Mismo trazado que el base, cambiando solo el stroke. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='none' stroke='%23ffffff' stroke-width='1.6' d='M1 1l5 5 5-5'/></svg>");
}

/* El texto de las <option> lo pinta el SO sobre fondo claro, así que hay que
   devolverlo a oscuro: si se hereda el blanco del select, el desplegable sale
   blanco sobre blanco en varios navegadores de escritorio. */
.oscyl-conciertos__select--rutas option {
  color: #1a1a1a;
  background-color: #ffffff;
}

.oscyl-conciertos__select--rutas:hover {
  background-color: var(--oscyl-single-terracota-dark, #9a4530);
  border-color: var(--oscyl-single-terracota-dark, #9a4530);
}

.oscyl-conciertos__select--rutas:focus {
  border-color: var(--oscyl-single-terracota-dark, #9a4530);
  box-shadow: 0 0 0 3px rgba(181, 83, 60, 0.25);
}

/* ==========================================================================
   SLIDER DE LA PÁGINA DE TEMPORADA — [oscyl_artistas_temporada] (v2.29.0)
   --------------------------------------------------------------------------
   TODO este bloque va acotado a `.oscyl-slider--artistas-temporada`, el
   modificador que solo pinta ese shortcode. Es deliberado: `.oscyl-slider__titulo`
   lo comparten TRES shortcodes ([oscyl_artistas_temporada], [oscyl_mas_artistas]
   y [oscyl_conciertos_artista]) y la tarjeta la comparten DOS, así que tocar las
   clases base habría cambiado también la ficha de artista. Decisión del cliente:
   aplicar los cambios solo en la página de temporada.
   ========================================================================== */

/* ---------- Título grande ----------
   De 37px a ~75px a 1440 (decisión del cliente). Medido contra el mockup: allí
   la altura de mayúscula del título es casi igual al diámetro de los botones
   (ratio ~0.95), mientras que con los 37px anteriores el ratio era 0.57.
   5.21vw da 75px justos a 1440; el clamp lo deja entre 36px y 84px. */
/* v2.30.1 — el mismo tratamiento se extiende al carrusel de conciertos de la
   página de temporada, que comparte maqueta y debe verse igual. Se añade el
   modificador a la lista en vez de duplicar el bloque: si mañana se afina el
   tamaño, se afina una sola vez. Los otros dos sliders del tema
   ([oscyl_mas_artistas] y [oscyl_conciertos_artista]) siguen sin tocarse. */
.oscyl-slider--artistas-temporada .oscyl-slider__titulo,
.oscyl-slider--conciertos-temporada .oscyl-slider__titulo {
  /* v2.62.0 — el tope del clamp sale de `--oscyl-slider-titulo-tam`, que el
     shortcode escribe EN LÍNEA con el atributo `titulo_tam`. Sin atributo, el
     `var()` cae a su valor por defecto y el tamaño es EXACTAMENTE el de
     siempre.

     🚨 v2.62.1 — EL SUELO TAMBIÉN ESCALA, y esto costó un desbordamiento.
     La v2.62.0 hacía configurable solo el TECHO y dejaba el suelo clavado en
     el valor de siempre. Resultado: en móvil el atributo no hacía nada. Con
     `titulo_fuente="sans"` el titular se quedaba en 36px —un valor calibrado
     para Kepler CONDENSADA— y en Inter la palabra «CONCIERTOS» ya no dejaba
     encoger la fila del header, que empujaba las flechas 9px FUERA de la
     pantalla a 375px.

     Ahora el suelo es una fracción del techo, así que el atributo manda en
     todos los anchos. La proporción es la del diseño original y sale exacta:
     2.25 / 5.25 = 3/7  (y 1.75 / 2.5 = 0.7 en la regla base). Escribirla como
     división y no como decimal redondeado deja el valor por defecto idéntico
     al de antes, sin arrastrar un error de 4ª cifra.

     📌 Y ya no hace falta el `min()` que llevaba la v2.62.0 para el caso
     «tope más pequeño que el suelo»: con el suelo proporcional, el suelo
     siempre es menor que el techo. El problema desaparece en vez de taparse. */
  font-size: clamp(calc(var(--oscyl-slider-titulo-tam, 5.25rem) * 3 / 7), 5.21vw, var(--oscyl-slider-titulo-tam, 5.25rem));
  line-height: 1.05;
}

/* ---------- Alineación óptica con los botones — SUBIDA A LA REGLA BASE ----------
   Aquí vivía `transform: translateY(0.135em)`, de la v2.29.2, acotado a los
   dos carruseles de temporada. Ya no está en este bloque: desde la v2.69.1 la
   corrección vive en `.oscyl-slider__titulo`, o sea en los CUATRO carruseles,
   con el valor sacado de las métricas de la fuente (0,117em). El razonamiento
   completo está allí.

   Por qué se movió, en corto: el descuadre nunca fue exclusivo de esta página.
   Lo que lo hacía visible aquí antes que en los demás era el tamaño —74px
   frente a 37px—, porque esta parte del desfase crece con la tipografía. Los
   otros dos carruseles llevaban el mismo error desde siempre, más pequeño.

   ⚠️ Lo que NO era de la fuente: los 5px del `padding-bottom` que Divi pone a
   todo `h1`–`h6`, retirados en la v2.69.0. El 0,135em de la v2.29.2 los
   absorbía sin saberlo, y por eso salía algo alto. */

/* ---------- Título de la tarjeta de concierto ----------
   v2.30.1 — de `clamp(1.25rem, 1.8vw, 1.75rem)` (20–28px) a
   `clamp(1.5rem, 2.1vw, 2rem)` (24–32px), para que acompañe al título grande
   del carrusel. Acotado al modificador: la tarjeta es la misma que usa
   «Lo puedes encontrar en:» en la ficha de artista, y allí sigue igual.

   No hace falta subir especificidad como en v2.29.2: aquí la regla base es
   `.oscyl-concierto-card__titulo`, una sola clase (0,1,0), así que el
   modificador + la clase (0,2,0) gana de sobra. Verificado enumerando las
   reglas que compiten por el `font-size`. */
.oscyl-slider--conciertos-temporada .oscyl-concierto-card__titulo {
  font-size: clamp(1.5rem, 2.1vw, 2rem);
}

/* ---------- Tarjeta ----------
   v2.39.0 — AQUÍ YA NO HAY NADA, Y ESO ES EL ARREGLO.

   Este bloque contenía toda la tipografía y la caja de la tarjeta de temporada
   (nombre en Inter 700, caja semitransparente con desenfoque, `fit-content`),
   acotadas con una cadena de CUATRO clases para ganarle al bloque base, que
   pintaba un badge gris sólido con el nombre en Kepler a 18px.

   Al pedir el cliente que [oscyl_mas_artistas] se viera igual, todo eso pasó a
   la clase base `.oscyl-artista-card--slider`, que es la que comparten los dos
   carruseles. Replicarlo aquí sería ahora una copia del mismo diseño en un
   tercer sitio.

   ⚠️ LA NOTA DE ESPECIFICIDAD DE v2.29.1 SIGUE VIGENTE si algún día hay que
   volver a diferenciar este carrusel del otro: la cadena del bloque base
   `.oscyl-artista-card--slider .oscyl-artista-card__contenido
   .oscyl-artista-card__nombre` tiene TRES clases (0,3,0), así que un selector
   de dos como `.oscyl-slider--artistas-temporada .oscyl-artista-card__nombre`
   (0,2,0) PIERDE por mucho que vaya después en el archivo. Hay que replicar la
   cadena completa y anteponer el modificador → (0,4,0). Fue exactamente el
   fallo de v2.29.1: la caja se aplicó y el tamaño del nombre no.

   Lo único propio que le queda a este carrusel es el TAMAÑO DEL TÍTULO del
   slider, arriba en este mismo bloque, que no es cosa de la tarjeta. */

/* ==========================================================================
   ARCHIVO DE NOTICIAS — [oscyl_noticias] (v2.31.0)
   --------------------------------------------------------------------------
   Listado histórico con los periodos (año / mes) en una columna a la izquierda
   y las noticias del periodo a la derecha.

   La rejilla es de DOS columnas por grupo, no una tabla ni un flex: así la
   celda del periodo ocupa toda la altura de su grupo sin saber cuántas
   noticias lleva, y el año queda arriba alineado con la primera. En móvil se
   apila a una sola columna.
   ========================================================================== */
.oscyl-noticias {
  --oscyl-noticias-linea: rgba(29, 29, 27, 0.25);
  max-width: 1140px;
  margin: 0 auto;
}

.oscyl-noticias__grupo {
  display: grid;
  grid-template-columns: minmax(140px, 20%) 1fr;
  gap: 0 4rem;
  align-items: start;
  margin-bottom: 3.5rem;
}

.oscyl-noticias__periodo {
  display: flex;
  flex-direction: column;
  font-family: var(--oscyl-font-serif);
  font-weight: 400;
  line-height: 1.05;
  color: #1d1d1b;
}

/* v2.55.0 — Año y mes un 25% más grandes, a petición del cliente.
   Antes: clamp(1.75rem, 2.6vw, 2.5rem) → 28px mínimo, 40px de tope.
   Los tres valores se escalan por igual, así que los anchos en los que el
   clamp topa arriba y abajo NO se mueven: sigue en el mínimo por debajo de
   ~1077px y en el tope por encima de ~1538px. Solo cambia el tamaño. */
.oscyl-noticias__anio,
.oscyl-noticias__mes {
  font-size: clamp(2.1875rem, 3.25vw, 3.125rem);   /* 35px → 50px */
}

/* ⚠️ ESPECIFICIDAD — no simplificar a `.oscyl-noticias__items`.
   Divi trae `#left-area ul, .entry-content ul, .et-l--body ul, … { list-style-type: disc }`.
   El selector que casa aquí es `.et-l--body ul` → (0,1,1), que GANA a
   `.oscyl-noticias__items` → (0,1,0). Con el selector corto seguía saliendo la
   viñeta junto a la fecha. Con el padre delante son (0,2,0) y gana.
   Se pone también en el `li` y se anula la sangría que Divi da al `ul`. */
.oscyl-noticias .oscyl-noticias__items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.oscyl-noticias .oscyl-noticias__item {
  list-style: none;
}

/* La línea va en el item y no en el enlace: así llega de borde a borde de la
   columna aunque el enlace lleve padding. */
.oscyl-noticias__item {
  border-bottom: 1px solid var(--oscyl-noticias-linea);
}

/* Un solo enlace envuelve toda la fila (ver el comentario del PHP). Es grid
   para poder colocar el ⊕ en su propia columna, centrado verticalmente
   respecto al bloque de texto completo. */
/* Un solo enlace envuelve toda la fila (ver el comentario del PHP). La rejilla
   tiene UNA fila y DOS celdas: el bloque de texto y el ⊕.

   ⚠️ v2.31.1 — antes los tres elementos de texto colgaban sueltos del enlace y
   el ⊕ se colocaba con `grid-row: 1 / -1` para que ocupara toda la altura.
   NO FUNCIONA: con filas implícitas, el `-1` apunta al final de la rejilla
   EXPLÍCITA, y como no hay `grid-template-rows` se resuelve a la fila 1. El ⊕
   quedaba confinado en la celda de la fecha (28px de alto), así que `align-self`
   no ten��a recorrido y el icono aparecía arriba en vez de abajo.
   La solución es el envoltorio `__texto`: con dos celdas en una sola fila,
   `align-items: end` alinea el ⊕ con el pie del texto. Verificado: la diferencia
   entre el pie del ⊕ y el del bloque de texto es de 0px. */
.oscyl-noticias__link {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 0 1.5rem;
  padding: 1.1rem 0;
  text-decoration: none;
  color: inherit;
}

.oscyl-noticias__texto {
  grid-column: 1;
  min-width: 0;   /* que un titular largo no ensanche la celda */
}

.oscyl-noticias__mas {
  grid-column: 2;
  align-self: end;
  display: inline-flex;
  color: #1d1d1b;
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.oscyl-noticias__link:hover .oscyl-noticias__mas {
  transform: scale(1.12);
  opacity: 0.7;
}

.oscyl-noticias__fecha {
  display: block;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: #6b6b68;
  margin-bottom: 0.35rem;
}

.oscyl-noticias__titulo {
  margin: 0 0 0.4rem;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.3;
  color: #1d1d1b;
}

.oscyl-noticias__link:hover .oscyl-noticias__titulo {
  text-decoration: underline;
}

.oscyl-noticias__extracto {
  margin: 0;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 300;
  line-height: 1.5;
  color: #4a4a48;
  max-width: 62ch;   /* longitud de línea legible aunque la columna sea ancha */
}

/* ---------- Paginación ---------- */
.oscyl-noticias__paginacion {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 2.5rem;
}

.oscyl-noticias__paginacion .page-numbers {
  display: inline-grid;
  place-items: center;
  min-width: 40px;
  height: 40px;
  padding: 0 0.75rem;
  border: 1px solid var(--oscyl-noticias-linea);
  border-radius: 50px;
  font-family: 'Inter', -apple-system, sans-serif;
  font-size: 14px;
  color: #1d1d1b;
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.oscyl-noticias__paginacion .page-numbers:hover,
.oscyl-noticias__paginacion .page-numbers.current {
  background: #1d1d1b;
  border-color: #1d1d1b;
  color: #fff;
}

.oscyl-noticias__paginacion .page-numbers.dots {
  border-color: transparent;
}

/* ---------- Móvil ---------- */
@media (max-width: 780px) {
  .oscyl-noticias__grupo {
    grid-template-columns: 1fr;
    gap: 0.75rem;
    margin-bottom: 2.5rem;
  }
  /* En una sola columna el periodo pasa a leerse como una cabecera de sección,
     así que el año y el mes van en línea en vez de apilados. */
  .oscyl-noticias__periodo {
    flex-direction: row;
    align-items: baseline;
    gap: 0.5rem;
  }
  .oscyl-noticias__anio,
  .oscyl-noticias__mes {
    font-size: 1.875rem;   /* v2.55.0 — 30px (antes 1.5rem = 24px) */
  }
  .oscyl-noticias__link {
    gap: 0 1rem;
  }
}

/* ==========================================================================
   ENLACE CON FLECHA — .oscyl-enlace-flecha (v2.32.0)
   --------------------------------------------------------------------------
   Enlace subrayado con flecha diagonal, para los pies de sección del tipo
   «Sede ↗ · Directores y artistas residentes ↗ · Profesores ↗».

   HERMANO DE `.oscyl-atras` (v2.26.9). Misma anatomía y mismas dos decisiones,
   que allí ya se razonaron:
     · El subrayado va con `border-bottom` y NO con `text-decoration`, para que
       la línea pase también por debajo de la flecha.
     · La flecha es SVG inline y NO un carácter Unicode: el glifo depende de la
       fuente instalada y cambia de grosor y tamaño entre sistemas.

   LA DIFERENCIA IMPORTANTE: aquí NO se declara `color`.
   `.oscyl-atras` lo fija a blanco porque siempre va sobre el hero terracota.
   Este se usa en secciones de colores distintos (verde en La Orquesta,
   terracota en otras), así que el color debe poder cambiarse sin tocar CSS.
   Al no declararlo:
     · manda el «Color del enlace» del módulo Texto de Divi, que es lo que el
       cliente puede cambiar por sí mismo;
     · y si no se toca, hereda el color del texto que lo rodea. Por defecto sale
       oscuro, porque el tema tiene un color de enlace global de #1c1c1c.

   CÓMO SE CAMBIA EL COLOR (confirmado funcionando el 11-08-2026):
     Módulo Texto → pestaña Diseño → apartado «Enlace» (según versión, «Texto
     del enlace») → Color del texto del enlace.
     OJO: NO vale el apartado «Texto» a secas, que afecta al párrafo y no al <a>.
   El subrayado y la flecha lo siguen solos gracias a `currentColor`.
   El subrayado y la flecha usan `currentColor`, así que **siguen al color del
   enlace automáticamente**: se cambia en un sitio y cambia todo.

   Se descartó hacer modificadores por color (`--verde`, `--terracota`): habría
   que editar el CSS del tema cada vez que aparezca un color nuevo, y eso no lo
   puede hacer quien maqueta la página.

   USO, en un módulo Texto de Divi:
     <a class="oscyl-enlace-flecha" href="/la-orquesta/sede/">Sede<svg …></svg></a>
   ========================================================================== */
.oscyl-enlace-flecha {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--oscyl-font-sans, 'Inter', sans-serif);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 3px;
  transition: opacity 0.2s ease;
}

.oscyl-enlace-flecha:hover,
.oscyl-enlace-flecha:focus {
  opacity: 0.65;
}

/* `stroke: currentColor` es lo que hace que la flecha herede el color. */
.oscyl-enlace-flecha svg {
  width: 9px;
  height: 9px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
}

/* Separación entre varios enlaces seguidos dentro del mismo módulo Texto.
   Se aplica al contenedor, no al enlace, para no meter margen al último. */
.oscyl-enlaces-fila {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 44px;
  align-items: center;
}


/* ==========================================================================
   PORTADA — UN BLOQUE DE NOTICIAS SIN CONTENIDO DESAPARECE  (v2.59.1)
   ==========================================================================

   EL PROBLEMA
   -----------
   Cuando un módulo Blog o Post Slider de Divi no encuentra entradas, pinta su
   cartel de serie:

       «No Se Encontraron Resultados»
       «No se pudo encontrar la página que solicitaste. Prueba a ajustar tu
        búsqueda o usa la navegación superior para localizar la entrada.»

   En una página interior de un blog puede tener sentido. En la portada de la
   web de una orquesta es un error a ojos del visitante — y encima le habla de
   una búsqueda que nadie ha hecho. Pasó el 27-08-2026, al asignar las
   categorías de portada a los módulos ANTES que a las noticias: los bloques se
   quedaron sin nada y la home mostró el cartel dos veces, uno de ellos a
   tamaño de titular sobre el fondo rojo.

   ⚠️ NO ES UN CASO RARO. Vuelve a pasar cada vez que una categoría de portada
   se quede sin ninguna noticia: al arrancar una temporada, al despublicar la
   última que quedaba, o si alguien desmarca la casilla sin darse cuenta.

   DIVI EMITE DOS MARCADOS DISTINTOS, y por eso el selector va por
   `.not-found-title`, que es lo único común a los dos:

       Post Slider →  .et_pb_no_results > .entry > h1.not-found-title
       Blog        →  .entry > h1.not-found-title      (sin el envoltorio)

   `.not-found-title` solo existe cuando el bloque está vacío, así que no hay
   riesgo de que estas reglas se activen con contenido.

   📌 ESCONDERLO NO ES TODO. Un bloque que desaparece sin decir nada es el tipo
   de fallo silencioso del que este proyecto ya se ha quemado. El tema deja un
   COMENTARIO HTML al pie diciendo qué bloque está vacío y por qué — ver la §7
   de inc/portada-noticias.php. Al visitante no le sale nada; a quien mire el
   código fuente, sí.
   ========================================================================== */

/* El bloque entero desaparece: sin cartel y sin el hueco que dejaba. */
.oscyl-slider-noticias:has(.not-found-title),
.slider-noticias-oscyl:has(.not-found-title),
.noticias-home-oscyl:has(.not-found-title) {
  display: none;
}

/* Red de seguridad por si `:has()` no estuviera disponible. Entonces el bloque
   sigue ocupando su hueco, pero al menos el cartel no se lee. Se listan el
   titular y sus hermanos porque sin `:has()` tampoco se puede seleccionar el
   `.entry` que los contiene. */
.oscyl-slider-noticias .not-found-title,
.oscyl-slider-noticias .not-found-title ~ p,
.slider-noticias-oscyl .not-found-title,
.slider-noticias-oscyl .not-found-title ~ p,
.noticias-home-oscyl .not-found-title,
.noticias-home-oscyl .not-found-title ~ p {
  display: none;
}


/* ==========================================================================
   NEGRITA EN LÍNEA — peso por defecto de <strong>   (v2.60.0)
   ==========================================================================

   Divi da `strong { font-weight: 700 }` desde su hoja base (inline, en
   `divi-style-parent-inline`). No hay ningún ajuste de Divi para esto: el
   constructor deja poner el peso de un módulo, no el de la negrita en línea
   dentro de un texto. Por eso va en CSS y no en Divi — no aplica la regla de
   la §9.3 «si el ajuste existe en Divi, va en Divi», porque aquí no existe.

   El texto de párrafo del sitio computa Inter 300, así que un 700 saltaba 400
   unidades y la negrita pesaba demasiado. A 500 el salto es de 200 y sigue
   leyéndose como resaltado.

   Inter se sirve como fuente variable (100..900), así que el 500 es un peso
   real dibujado, no una negrita sintética.

   ⚠️ NO se toca <b>, Y ES DELIBERADO.
   -----------------------------------
   <b> no tiene regla de Divi: usa el `font-weight: bolder` de la hoja del
   navegador, que es RELATIVO, no 700. Sobre el texto a 300 de este sitio,
   `bolder` computa **400**. Medido: los 32 <b> del sitio están a 400.

   Meter `b` aquí lo subiría de 400 a 500 — más gordo, lo contrario de lo que
   se busca. Y 22 de esos 32 son los NOMBRES DE COMPOSITOR del bloque PROGRAMA
   de las fichas de concierto, que la v2.24.11 dejó a propósito con la negrita
   viniendo solo de las etiquetas del contenido.

   📌 Efecto secundario bueno: con `strong` a 500 y `<b>` a 400, las dos
   etiquetas quedan casi iguales. Antes eran 700 y 400 — dos cosas que el
   editor usa indistintamente y se veían muy distintas.

   ✅ ALCANCE VERIFICADO (27-08-2026, 61 URLs barridas, 24 con negrita).
   152 casos: 120 <strong> y 32 <b>. **Ningún <strong> está en línea junto a
   texto a 500**, así que en ningún sitio se confunde con el texto que lo
   rodea. Los 9 de /la-orquesta/equipo-tecnico/ ocupan un <h2> entero cuyo
   peso propio es 500 — ese 500 nunca se ve porque lo pisa el propio <strong>,
   y el cargo de debajo es un <p> aparte a 300/14px.

   NO afecta a los componentes del tema que declaran su propio 700 (titulares
   de tarjeta, nombres de artista…): esos llevan su peso a propósito.
   ========================================================================== */

strong {
  font-weight: 500;
}


/* ==========================================================================
   TITULAR DE CARRUSEL EN SANS — `titulo_fuente="sans"`   (v2.61.0)
   ==========================================================================

   Los cuatro carruseles del tema comparten `.oscyl-slider__titulo`, que va en
   la serif del tema (Kepler). En algunas páginas el titular debe ir en Inter
   —caso del abono, «¿Qué conciertos incluye?»—, así que la fuente pasa a
   elegirse POR BLOQUE con el atributo `titulo_fuente`.

   Es el mismo criterio que el `titulo_color` de la v2.48.0: la clase la
   comparten todos los carruseles, así que la variante no puede vivir en la
   regla base.

   POR QUÉ UNA CLASE Y NO UN `style` EN LÍNEA (que es lo que hace el color)
   ----------------------------------------------------------------------
   Porque cambiar de familia obliga a cambiar MÁS DE UNA propiedad, y una de
   ellas no es tipográfica:

   la familia, el peso y el tracking, que son tres. Un `style` en línea con las
   tres sería ilegible en el atributo del shortcode y habría que repetirlo en
   cada bloque.

   ⚠️ Y una cuarta que no es tipográfica: el `transform` de corrección óptica.
   La regla base baja el titular 0,117em porque Kepler reserva mucho más hueco
   bajo la línea base que sobre las mayúsculas. **Inter no lo necesita**: la
   misma cuenta sobre sus métricas da 0,001em, y medido en el abono el titular
   en Inter ya cae a 0,6px del centro de las flechas sin ajuste ninguno. Un
   `style="font-family:…"` en línea no llegaría al `transform`, y ese es el
   motivo de fondo de que la fuente vaya como clase.

   📌 v2.69.1 — este párrafo estuvo mal escrito una versión: la v2.69.0 dio por
   hecho que el desfase era SOLO el `padding-bottom` de Divi y retiró el
   transform de todo el tema. Eran dos cosas sumadas, una fija y otra de la
   fuente. Al quitar solo la fija, el titular seguía viéndose alto.

   ESPECIFICIDAD
   -------------
   Se escriben las dos clases juntas para sumar (0,2,0) y empatar con
   `.oscyl-slider--conciertos-temporada .oscyl-slider__titulo`, que es quien
   pone el tamaño grande. Al ir más abajo en la hoja, gana el empate — sin
   necesidad de `!important`. Mismo criterio que en v2.49.2 con
   `.oscyl-interpretes__enlace`.

   📌 El TAMAÑO no se toca: lo decide el modificador del bloque, que es una
   decisión aparte y ya tomada. Aquí solo se cambia la familia y lo que
   depende de ella.

   Los valores salen de `.h2-std`, que la escala tipográfica del tema define
   literalmente como «variante sans-serif del H2»: Inter 400 con el tracking
   común del manual. No se inventa nada nuevo.
   ========================================================================== */

.oscyl-slider__titulo.oscyl-slider__titulo--sans {
  font-family: var(--oscyl-font-sans);
  font-weight: 400;
  letter-spacing: var(--oscyl-tracking-tight);

  /* La corrección óptica de la regla base es de Kepler. Con Inter sobra:
     0,001em según sus métricas, o sea nada. Medido en el abono. */
  transform: none;
}


/* ==========================================================================
   TARJETAS DE NOTICIAS DE LA HOME — el titular en la MISMA familia que su enlace
   ==========================================================================
   v2.72.0 — el interlineado del módulo Blog no daba lo que decía.

   EL SÍNTOMA
   ----------
   Se puso «Altura de línea = 1.2em» en el panel de Divi para igualar el titular
   de las tarjetas con el del slider de al lado. El valor SE APLICABA —los dos
   computaban 20,16px— pero las líneas de las tarjetas quedaban a **23,2px**
   unas de otras, un 15% más que las del slider. Bajar el número no arreglaba
   nada: mantenía la misma desproporción.

   LA CAUSA: DOS FUENTES EN LA MISMA LÍNEA
   ---------------------------------------
   El `<h2>` es **Kepler Std**, heredado de la regla `h2` del tema. El `<a>` que
   lleva dentro —que es TODO el contenido visible— es **Inter**, puesto por el
   panel de Divi. Divi solo emite la familia sobre el enlace, no sobre el h2.

   Las dos cajas tienen la misma altura de línea, pero su línea base NO cae a la
   misma altura dentro de ella: Kepler reserva mucho más hueco bajo la base. Al
   alinear ambas por la línea base, la caja de línea resultante crece.
   Es el mismo desajuste de métricas que obligó a la corrección óptica de los
   carruseles en la v2.69.1.

   Medido dejando la interlínea FIJA en 20,16px:
      h2 en Kepler Std  →  paso real entre líneas 23,2px
      h2 en Inter       →  paso real entre líneas 20,1px  ← igual que el slider

   POR QUÉ VA EN EL TEMA Y NO EN DIVI
   ----------------------------------
   El campo *Fuente De Título* del módulo Blog solo escribe sobre `.entry-title a`.
   No hay ningún ajuste del panel que alcance al `h2`, así que es de los casos
   que sí tocan al `style.css` — ver §9.3.1 del Flujo operativo.

   ✅ No cambia NADA visible por sí misma: comprobado que el enlace ocupa el
   titular entero y no queda ni un nodo de texto suelto fuera de él. Lo único
   que hace es que la caja de línea deje de inflarse.

   ⚠️ Se ancla a `.noticias-home-oscyl`, la clase que puso el editor, y NO a
   `.et_pb_blog_0`: ese número es posicional y Divi lo reasigna al reordenar
   módulos. De hecho en esta página hay DOS módulos con esa clase.

   📌 La fuga es más ancha que este bloque: `h2 { line-height: 0.83 }` del tema
   afecta a CUALQUIER h2 al que Divi le pise el tamaño. Queda pendiente un
   barrido para ver dónde más está pasando.
   ========================================================================== */

.noticias-home-oscyl .et_pb_post .entry-title {
  font-family: var(--oscyl-font-sans);
}


/* ==========================================================================
   v2.92.0 — «abonos» EN MÓVIL: UNA REGLA PARA LAS NUEVE PÁGINAS
   ==========================================================================
   QUÉ SE VEÍA MAL
   ---------------
   En el pie de `/conciertos/entradas-y-abonos/` el rótulo grande partía la
   palabra «abonos» en dos líneas en teléfono. En el Theme Builder se veía
   bien, porque allí el lienzo es ancho.

   DE DÓNDE SALE
   -------------
   El marcado es `<p class="linea-desplazada">abonos</p>` dentro de un módulo
   de texto, y la regla NO estaba en el tema: vive en el campo *CSS de formato
   libre* del propio módulo (Divi → Avanzado → CSS), así:

      .linea-desplazada{ display:block; margin-left:8rem;
                         font-family:'Kepler Std',serif;
                         font-size:1.75em; line-height:0.71; }

   Los dos valores que rompen son fijos y no tienen variante de teléfono:
      · `1.75em` cuelga del módulo, que está a 60px → **105px clavados**
        (el `h2` hermano sí baja a 30px en móvil; este `p` no baja nunca).
      · `8rem` = **128px** de sangría: el 37% del ancho a 428 y la mitad a 320.

   Medido en vivo, caja disponible / tinta que pide / resultado:
      428 → 214 / 203  cabe por 11px      393 → 186 / 203  PARTE
      375 → 172 / 203  PARTE              320 → 128 / 203  PARTE

   El tamaño del diseño aprobado, medido sobre el PNG, es ~77px: la palabra
   ocupa 148px arrancando en x=160 (esa sangría son los 8rem). De ahí el
   `1.28em` → 1,28 × 60 = **76,8px**, y la sangría en % para que encoja con la
   pantalla en lugar de comerse un ancho fijo.

   POR QUÉ LA REGLA ESTÁ AQUÍ Y NO EN CADA MÓDULO
   ----------------------------------------------
   El mismo CSS pegado a mano aparece en **9 páginas** — comprobadas las 202
   URLs del sitio, una aparición por página y siempre la palabra «abonos»:

      /conciertos/                             /conciertos-anteriores/
      /contacto/                               /conciertos/entradas-y-abonos/
      /conciertos/entradas-y-abonos/abono-temporada-26-27/
      /conciertos/entradas-y-abonos/abono-sabado/
      /conciertos/entradas-y-abonos/abono-de-bienvenida/
      /conciertos/entradas-y-abonos/abonos-de-proximidad/
      /conciertos/entradas-y-abonos/historias-musicales/

   Las nueve copias son idénticas byte a byte, y los nueve módulos están a
   60px, así que un único `1.28em` sirve para todas. Arreglarlo módulo a módulo
   serían nueve ediciones a mano y, sobre todo, nueve sitios donde olvidarse la
   próxima vez que se duplique la sección.

   ⚠️ LA ESPECIFICIDAD NO ES DECORATIVA
   La hoja de Divi (`et-core-unified-…-deferred-N.min.css`) es *deferred*: carga
   DESPUÉS de este `style.css`. Con el selector pelado `.linea-desplazada` los
   dos pesarían igual (0,1,0) y ganaría Divi por orden. Por eso se ancla a
   `.et_pb_text_inner` (0,2,0), que gana sin necesidad de `!important`.

   ✅ Comprobado en vivo inyectando esta misma regla sobre `/conciertos/`:
        320 → 76,8px, sangría 95, caja 161, tinta 148 → 1 línea
        375 → 76,8px, sangría 111, caja 189, tinta 148 → 1 línea
        428 → 76,8px, sangría 127, caja 216, tinta 148 → 1 línea
        768 → 105px, sangría 128 → SIN TOCAR (escritorio intacto)

   📌 767 y no 980: este es el corte de *teléfono* de Divi, el mismo que ya
   obligó a rehacer el degradado del hero. Ver §9.3 del Flujo operativo.

   📌 Queda una copia del parche pegada a mano en el módulo de
   `/conciertos/entradas-y-abonos/`. Es inofensiva —mismos valores— pero hay
   que borrarla para que la fuente de verdad sea solo esta.
   ========================================================================== */

@media (max-width: 767px) {

  .et_pb_text_inner .linea-desplazada {
    font-size: 1.28em;   /* 1,28 × 60px = 76,8px, el tamaño del diseño */
    margin-left: 37%;    /* en vez de 8rem fijos: encoge con la pantalla */
  }

}
