/* Estructura base de anuncios (modal, editor de lienzo por capas). El
   fondo/tamaño/proporción/posición de cada anuncio se genera inline por
   anuncio en views/partials/announcements.template.php; cada capa
   (contenedor de texto / imagen / botón) trae su propio left/top/width en
   % inline también — ver Announcement::imageAlignCss() y el resto de los
   métodos de models/announcement.class.php. */

.ann-modal {
  position: fixed;
  inset: 0;
  z-index: 1060;
  display: none;
  align-items: center;
  justify-content: center;
}

.ann-modal.is-visible {
  display: flex;
}

.ann-modal-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .55);
}

.ann-modal-box {
  position: relative;
  /* Fijo explícito (no heredado): el admin usa Poppins como fuente del
     panel y el sitio público usa Segoe UI — sin esto, el modal se veía
     con tipografía distinta en la vista previa que en el sitio real. */
  font-family: 'Segoe UI', system-ui, sans-serif;
  color: #fff;
  max-width: 480px;
  width: calc(100% - 32px);
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  scrollbar-width: none; /* Firefox — el contenido sigue siendo desplazable, solo se oculta la barra */
  border-radius: 12px;
  padding: 32px 40px 28px 24px;
  box-shadow: 0 16px 48px rgba(0, 0, 0, .35);
  transform: scale(.94);
  opacity: 0;
  transition: transform 220ms cubic-bezier(0.23, 1, 0.32, 1), opacity 220ms ease-out;
  /* .ann-modal-box es un flex item de .ann-modal (min-height:auto por
     default en flexbox) y, con proporción fija, también pasa a ser flex
     container de su propio contenido — sin min-height:0 el contenido
     puede forzar la caja a crecer más alta que la proporción configurada
     en vez de recortar con el scroll interno. */
  min-height: 0;
}

/* Chrome/Safari/Edge — mismo objetivo que scrollbar-width:none arriba */
.ann-modal-box::-webkit-scrollbar {
  display: none;
}

.ann-modal.is-visible .ann-modal-box {
  transform: scale(1);
  opacity: 1;
}

.ann-close {
  position: absolute;
  top: 8px;
  right: 12px;
  z-index: 5;
  background: transparent;
  border: 0;
  color: inherit;
  font-size: 1.6rem;
  line-height: 1;
  opacity: .85;
  cursor: pointer;
  transition: transform 120ms ease-out;
}

.ann-close:active {
  transform: scale(.9);
}

/* ── Banner (segundo tipo de anuncio, convive con el modal — tema
   "Anuncios3") ───────────────────────────────────────────────────────────
   Un solo div (sin overlay: un banner no bloquea el resto de la página).
   Posición fija (pedido explícito: siempre abajo, ancho completo, cierre
   en la esquina superior derecha — .ann-close ya usa top:8px;right:12px
   por defecto, no necesita nada propio). Solo el alto (px) y el estado
   oculto/visible de la animación llegan inline por anuncio y por
   breakpoint — ver bannerBoxCss()/bannerHiddenCss()/bannerVisibleCss() en
   announcements.template.php. */
.ann-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  z-index: 1060;
  display: none;
  overflow: hidden; /* barra angosta de alto fijo — recorta en vez de mostrar scroll (una capa de imagen sin restricción de alto propio es la causa más común de contenido más alto que el banner) */
  font-family: 'Segoe UI', system-ui, sans-serif;
  color: #fff;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .35);
  padding: 20px 44px 20px 24px;
  transition: transform 260ms cubic-bezier(0.23, 1, 0.32, 1), opacity 260ms ease-out;
}

.ann-banner.is-visible {
  display: block;
}

/* Contenedor de contenido — el fondo del banner ocupa todo el ancho
   (.ann-banner), pero el texto/imágenes/botones se centran y no se
   extienden a todo lo ancho en pantallas muy anchas (mismo criterio que
   el resto del sitio, .container de Bootstrap, pero con un max-width fijo
   propio en vez de la escalera de breakpoints de Bootstrap — esta misma
   clase se usa tal cual en el editor y en el sitio real, ver
   announcement-layer-editor.function.js/announcements.template.php, así
   que las capas se posicionan contra el mismo ancho de referencia en los
   dos lugares). Solo limita el ANCHO (max-width + margin:auto) — el alto
   siempre es el 100% real del banner: inset:0 (position:absolute contra
   .ann-banner, que ya es position:fixed) lo estira top-a-bottom sin
   depender de un height:100% en cascada por flexbox, que en algunos
   navegadores no resuelve igual de confiable. */
.ann-banner-inner {
  position: absolute;
  inset: 0;
  max-width: 1140px;
  margin: 0 auto;
}

/* ── Capas (lienzo) ──────────────────────────────────────────────────────
   .ann-layers-desktop/.ann-layers-mobile cubren toda la caja (position:
   relative, alto real = el más alto de sus capas posicionadas) — el CSS
   por-anuncio decide cuál de las dos se ve según el ancho real, igual
   mecanismo que ya usaba el bloque de contenido único anterior. */
.ann-layers-desktop,
.ann-layers-mobile {
  position: relative;
  width: 100%;
  /* left/top de cada capa son % de ESTA caja — necesita una altura real
     para poder moverse libre en Y. Con proporción fija, height:100% la
     hace ocupar exactamente la caja (que sí tiene alto definido por
     aspect-ratio). Con proporción "Automática" no hay alto definido del
     padre, así que height:100% no aplica y cae al min-height de abajo —
     por eso ese mínimo es generoso (antes 40px dejaba casi sin rango
     vertical para mover una capa). */
  min-height: 200px; /* bajo el alto de la combinación más chica real (tamaño Pequeño + horizontal 16:9 ≈ 210px de alto útil), para no forzar scroll por defecto en esa combinación */
  height: 100%;
}

/* El banner SIEMPRE tiene alto real definido (px, ver bannerBoxCss()) — a
   diferencia del modal en proporción "Automática", nunca depende del
   min-height de arriba para tener rango de movimiento en Y. Sin este
   reset, cualquier banner más bajo que 200px (el default son 90px)
   forzaba scroll aunque el contenido cupiera perfecto. */
.ann-banner .ann-layers-desktop,
.ann-banner .ann-layers-mobile {
  min-height: 0;
}

.ann-layer {
  position: absolute;
}

.ann-layer-text {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ann-layer-text p {
  margin: 0;
}

.ann-layer-subtitle {
  font-size: 1.05em;
  opacity: .85;
}

.ann-layer-image {
  display: block;
}

.ann-layer-image img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
}

/* ── Botones ─────────────────────────────────────────────────────────────
   Colores por variables --btn-* (ver Announcement::buttonAttrs()) para no
   generar un <style> nuevo por botón solo por la regla :hover. Portado de
   /home/sysadmin/www/dental/public/css/home.style.css (sistema de botones
   de "Vitrinas") — 10 presets, cada uno con su propia transición de hover. */
.ann-layer-text .ann-btn {
  margin-top: .25rem;
  align-self: flex-start;
}

.ann-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 26px;
  font-weight: 600;
  font-size: 15px;
  text-decoration: none;
  line-height: 1.2;
  white-space: nowrap;
  border-radius: .375rem;
  border: 2px solid transparent;
  background: var(--btn-bg);
  color: var(--btn-text);
  transition: background-color .2s ease, color .2s ease, border-color .2s ease,
              transform .2s ease, box-shadow .2s ease, background-position .4s ease;
}

/* background-color, no el shorthand background — el shorthand resetea
   background-image/-position a su valor inicial si no se repiten en la
   misma declaración, lo que apagaría el degradado de .is-gradient en cada
   hover. Esta regla se aplica a TODOS los presets por especificidad más
   baja, incluido gradient. */
.ann-btn:hover { background-color: var(--btn-hover-bg); color: var(--btn-hover-text); }
.ann-btn.is-pill { border-radius: 999px; }
.ann-btn.is-outline { background: transparent; color: var(--btn-bg); border-color: var(--btn-bg); }
.ann-btn.is-outline:hover { background: var(--btn-hover-bg); color: var(--btn-hover-text); border-color: var(--btn-hover-bg); }
.ann-btn.is-ghost { background: transparent; color: var(--btn-bg); border-color: transparent; }
.ann-btn.is-ghost:hover { background: var(--btn-hover-bg); color: var(--btn-hover-text); }

/* Degradado — tile al doble de ancho (background-size:200%), listo para
   que el efecto "shift" deslice la posición. Sin color acá — .ann-btn ya
   lo pone (línea de base) y redeclararlo acá con la misma especificidad
   que .ann-btn:hover anularía el cambio de color al pasar el mouse. */
.ann-btn.is-gradient {
  background: var(--btn-gradient); background-size: 200% auto; background-position: 0% 50%;
  border-color: transparent;
}

/* Efecto de hover — desacoplado del color/forma. Solo aplica a los presets
   "rellenos" (solid/pill-solid/gradient/pill-gradient) — 'swap' no
   necesita regla propia, ya es el comportamiento base de .ann-btn:hover. */
.ann-btn.is-hover-shift:hover { background-position: 100% 50%; }
.ann-btn.is-hover-scale:hover { transform: scale(1.06); }
.ann-btn.is-hover-lift:hover { transform: translateY(-3px); box-shadow: 0 8px 20px rgba(0, 0, 0, .25); }
.ann-btn.is-hover-glow:hover { box-shadow: 0 0 22px rgba(var(--btn-bg-rgb), .65); }
.ann-btn.is-hover-sweep { position: relative; overflow: hidden; }
.ann-btn.is-hover-sweep::before {
  content: ''; position: absolute; top: 0; left: -60%; width: 40%; height: 100%;
  background: rgba(255, 255, 255, .35); transform: skewX(-20deg); transition: left .5s ease;
}
.ann-btn.is-hover-sweep:hover::before { left: 120%; }

/* Suave — fondo del mismo color a baja opacidad (rgba real vía --btn-bg-rgb),
   se levanta con sombra al pasar el mouse. */
.ann-btn.is-soft {
  background: rgba(var(--btn-bg-rgb), .14); color: var(--btn-bg); border-color: transparent;
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease, color .15s ease;
}
.ann-btn.is-soft:hover {
  background: var(--btn-hover-bg); color: var(--btn-hover-text);
  transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, .18);
}

/* Vidrio — translúcido con blur, se aclara al pasar el mouse. */
.ann-btn.is-glass {
  background: rgba(255, 255, 255, .12); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-color: rgba(255, 255, 255, .35);
  transition: background-color .2s ease, border-color .2s ease;
}
.ann-btn.is-glass:hover { background: rgba(255, 255, 255, .22); border-color: rgba(255, 255, 255, .6); }

/* Subrayado — solo texto, una línea crece desde el centro al pasar el
   mouse (::after en vez de border-bottom, para animar el ancho sin mover
   el layout del texto). */
.ann-btn.is-underline {
  background: transparent; border-color: transparent; color: var(--btn-bg);
  padding-left: .25rem; padding-right: .25rem; position: relative;
}
.ann-btn.is-underline::after {
  content: ''; position: absolute; left: 50%; bottom: 2px; width: 0; height: 2px;
  background: var(--btn-hover-bg); transition: width .25s ease, left .25s ease;
}
.ann-btn.is-underline:hover { color: var(--btn-hover-bg); background: transparent; }
.ann-btn.is-underline:hover::after { width: calc(100% - .5rem); left: .25rem; }

@media (prefers-reduced-motion: reduce) {
  .ann-btn.is-soft:hover { transform: none; }
  .ann-btn.is-hover-scale:hover,
  .ann-btn.is-hover-lift:hover { transform: none; }
  .ann-btn.is-hover-sweep::before { transition: none; display: none; }
}

/* ── Subrayado decorativo (plugins/svg_marker_announcements) ───────────── */
.animated-marker { position: relative; display: inline; z-index: 0; }
.animated-marker .svg-marker { position: absolute; left: 0; bottom: -5px; width: 100%; height: 14px; overflow: visible; pointer-events: none; z-index: -1; }
.animated-marker .svg-marker--style5,
.animated-marker .svg-marker--style6 { top: -22%; bottom: auto; left: -20%; width: 140%; height: 148%; }

@media (max-width: 768px) {
  .ann-modal-box {
    padding: 28px 32px 24px 20px;
  }
}
