/* ═══════════════════════════════════════════════════════════════════
   CodeHub — VIEWPORT GUARD  (última capa CSS, se carga SIEMPRE al final)
   Wilson.E 2026

   PROPÓSITO
   ─────────
   Red de seguridad para que NINGUNA modificación de componentes rompa
   la visualización en pantallas de distintos tamaños. Este archivo se
   carga después de index.css, components.css, index-responsive.css y
   site-tour.css, por lo que sus reglas ganan la cascada y actúan como
   "última palabra" para evitar desbordes horizontales y roturas de layout.

   BREAKPOINTS CANÓNICOS DEL PROYECTO (no usar otros)
   ───────────────────────────────────────────────────
   Usar SIEMPRE estos rangos al escribir @media nuevas. No inventar
   anchos nuevos: la fragmentación de breakpoints es lo que rompe
   pantallas pequeñas (380–720px).

     ≤ 360px   teléfonos muy antiguos (iPhone SE 1ª gen, Galaxy pequeños)
     ≤ 380px   teléfonos compactos   — rango mínimo soportado
     ≤ 420px   teléfonos medianos (p.ej. ciertos Android)
     ≤ 480px   teléfonos grandes (iPhone 12/13 mini en vertical)
     ≤ 550px   phablets / teléfonos grandes
     ≤ 640px   teléfonos XXL y tablets pequeñas en vertical
     ≤ 720px   tablets compactas / landscape de teléfonos
     ≤ 768px   tablets verticales  — breakpoint principal mobile/desktop
     ≤ 860px   tablets grandes vertical / desktop compacto
     ≤ 1080px  desktop medio

   REGLA DE ORO
   ────────────
   - Toda nueva regla de layout DEBE comprobarse en 380, 480, 640, 720
     y 768 px (al menos), además de escritorio.
   - Los contenedores de grid/flex deben usar `min-width: 0` en sus
     hijos cuando puedan desbordar (texto largo, tablas, pre, code).
   - Todo medio (img/video/canvas/iframe/table) debe tener max-width:100%.
   - Cualquier corrección de un componente debe añadirse AL FINAL de
     este archivo o dentro de su @media canónica, nunca inventando
     breakpoints intermedios arbitrarios.
   ═══════════════════════════════════════════════════════════════════ */

/* ── 1. SANIDAD GLOBAL — impedir desbordes horizontales ───────────── */
img, svg, video, canvas, iframe, embed, object, audio {
  max-width: 100%;
}
img, video { height: auto; }
picture, figure { max-width: 100%; }

/* Morphicons (<morph-icon>) — el svg generado hereda el color del botón
   y no debe empujar el layout ni salirse del contenedor. */
morph-icon { display: inline-flex; align-items: center; justify-content: center; }
morph-icon svg { max-width: 100%; }
/* En cuanto el custom element está definido, ocultar el icono Font Awesome
   de respaldo para que no se vean los dos a la vez. */
[data-theme-toggle]:has(morph-icon:defined) [data-fa-theme-icon],
.wx-alerts-toggle:has(morph-icon:defined) [data-fa-wx-icon] { display: none; }

/* Refuerzo absoluto: el documento nunca debe ser más ancho que la
   pantalla, ni generar scroll horizontal ni forzar el zoom-out que hace
   que el móvil muestre el sitio "en miniatura de escritorio". */
html { overflow-x: hidden; overflow-x: clip; }
html, body { max-width: 100%; }
body { overflow-x: hidden; overflow-x: clip; width: 100%; }

/* Cualquier elemento fijo/absoluto debe caber dentro del viewport */
[class*="dock"], .side-nav, .mobile-nav, #ai-panel, #config-panel,
#command-palette, #auth-panel, #experimental-menu, .menu-toggle-btn,
#sw-update-banner, .ai-fab-wrap, .ai-bottom-bar, .ai-circle-btn,
#egg-overlay, #devtools-warning, #ch-splash, #command-overlay,
#ios-notif-overlay, #ch-app-perms-overlay {
  max-width: 100vw;
}


/* Texto largo / palabras sin espacios no pueden empujar el layout */
p, h1, h2, h3, h4, h5, h6, li, a, span, strong, em, small,
button, label, legend, caption, blockquote, figcaption {
  overflow-wrap: break-word;
  word-wrap: break-word;
}
code, pre, kbd, samp {
  overflow-wrap: break-word;
  word-wrap: break-word;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Inputs/selects/textareas: no crecen más que su contenedor */
input, select, textarea, button {
  max-width: 100%;
  min-width: 0;
}

/* ── 2. PROTECCIÓN DE CONTENEDORES — grids/flex no desbordan ───────── */
/* Hijos de contenedores flexibles necesitan min-width:0 para poder
   encogerse con el texto largo. Solo en contenedores con ancho fluido. */
.grid > *, .grid-2 > *, .grid-3 > *, .grid-4 > *,
.flex-row > *, .flex-col > *, .services-grid > *, .stats-section > *,
.wx-grid > *, .blogger-grid > *, .skills-grid > *, .hero-inner > *,
.otw-content > *, .otw-left > *, .otw-right > *,
.hero-stack > *, .hero-ctas > *, .blogger-card > *, .game-grid > * {
  min-width: 0;
}

/* ── 3. FIXES DE RANGO MÓVIL — 380px a 720px ───────────────────────── */
/* Estas reglas solo aplican en pantallas pequeñas. Su objetivo es
   absorber errores de layout y garantizar el soporte del rango móvil
   completo, aunque la corrección original solo se haya pensado en
   un ancho concreto. */

/* 380px — el ancho mínimo soportado */
@media (max-width: 380px) {
  /* Cualquier fila/barra del header debe caber en 380px sin desbordar */
  .header-inner { gap: 0.5rem; }
  .header-actions { gap: 0.35rem; }
  .burger-btn { min-width: 38px; min-height: 38px; }

  /* Drawer Windows Enhance: las 3 pestañas caben en 380px sin apretar */
  .we-tabs { gap: 0.3rem; padding-left: 0.6rem; padding-right: 0.6rem; }
  .we-tab { font-size: 0.66rem !important; padding: 0.4rem 0.3rem !important; }

  /* Header: en el mínimo, el logo no puede empujar el layout */
  .header-logo { flex-shrink: 1; min-width: 0; }
  .header-logo-copy { min-width: 0; overflow: hidden; }
  .header-logo-text { font-size: 0.95rem !important; }
  .header-logo-badge { font-size: 0.6rem !important; padding: 2px 7px !important; }

  /* El hero y sus botones no pueden desbordar en el mínimo */
  .hero-card { min-width: 0; }

  /* Paneles flotantes (config, ai, command) nunca más anchos que el viewport */
  #config-panel, #ai-panel, #command-palette {
    max-width: calc(100vw - 16px);
    width: auto;
  }
}

/* 420px — teléfonos medianos: reforzar header y grids */
@media (max-width: 420px) {
  .header-logo-text { font-size: 1rem !important; }
  .header-logo-meta { flex-wrap: nowrap; min-width: 0; }
  .hero-inner { grid-template-columns: 1fr !important; }
  .hero-visual { display: none !important; }
  .blogger-card { flex-direction: column !important; }
  .blogger-card-thumb { width: 100% !important; height: auto !important; max-height: 170px; }
  .blogger-card-desc { display: none !important; }
}

/* 480px — teléfonos grandes en vertical */
@media (max-width: 480px) {
  /* Textos de cabecera no desbordan */
  .header-logo-text { font-size: 0.9rem !important; }
  .header-logo-desc { max-width: 100%; }

  /* Hero: ocultar visual y forzar una columna limpia */
  .hero-visual { display: none !important; }
  .hero-inner { grid-template-columns: 1fr !important; }
  .hero-title { font-size: clamp(1.6rem, 8vw, 2.4rem) !important; }
  .hero-ctas { flex-wrap: wrap; }
  .hero-stack { flex-wrap: wrap; }

  /* Skills en cuadrícula compacta (2 col) y otw en una columna */
  .skills-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 0.6rem !important; }
  .otw-content { grid-template-columns: 1fr !important; }

  /* Office download bar: botones más grandes para touch */
  .office-dl-bar { gap: .35rem; padding: .45rem .5rem; flex-wrap: wrap; }
  .office-dl-btn { padding: .45rem .7rem; font-size: .72rem; min-height: 38px; }
  .office-dl-btn i { font-size: .8rem; }
  .office-dl-label { font-size: .58rem; }

  /* Tablas/wx-grid no desbordan */
  .wx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

/* 720px — tablets compactas / landscape de teléfonos */
@media (max-width: 720px) {
  /* Red de seguridad: ningún elemento posicionado o flotante se sale */
  .side-nav, .mobile-nav, [class*="dock"], .ai-circle-btn, .ai-bottom-bar {
    max-width: 100vw;
  }
  /* Grids principales no desbordan: otw/hero en 1 col, skills en 2 */
  .otw-content, .hero-inner {
    grid-template-columns: 1fr !important;
  }
  .skills-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 0.6rem !important; }
  /* Roadmap en cuadrícula compacta en tablets/móvil */
  .roadmap-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 0.6rem !important; }
  .roadmap-card { padding: 0.9rem; }
  /* Juegos: forzar cuadrícula de 2 columnas en todo el rango móvil
     (el auto-fit con minmax(210px) de base degenera a una sola columna
     en pantallas <420px y en 551-720px, viéndose como lista) */
  .game-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

/* ── 4. GUARDAS DE COMPONENTES CRÍTICOS ────────────────────────────── */
/* Si un componente nuevo se rompe en móvil, corrige AQUÍ abajo con el
   breakpoint canónico que corresponda. Nunca inventes anchos nuevos. */

/* Secciones: nunca más anchas que la pantalla */
section, main, .container, .wrap, .inner, .section-wrap {
  max-width: 100%;
  min-width: 0;
}

/* Noticias: tarjetas en una columna, texto limitado */
.blogger-grid { grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); }
.blogger-card { min-width: 0; overflow: hidden; }
.blogger-card-title { overflow-wrap: break-word; }
.blogger-card-body { min-width: 0; }

/* Pueblo: paneles y video no desbordan */
.pueblo-panels, .pueblo-video-wrap, .pueblo-iframe-wrap {
  max-width: 100%;
}
.pueblo-iframe-wrap iframe { max-width: 100%; }

/* Roadmap y stats: cards no desbordan */
.roadmap-grid, .stats-grid { grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr)); }

/* Hero: código/visual nunca desborda */
.hc-code pre { white-space: pre-wrap; overflow-wrap: break-word; }
.hero-card { max-width: 100%; }

/* Refuerzo mobile-first universal para rangos críticos: los hijos de
   cualquier fila se encogen y el texto envuelve (regla de oro del proyecto). */
@media (max-width: 768px) {
  .hero-inner { grid-template-columns: 1fr !important; }
  .hero-visual { display: none !important; }
  .hero-text, .hero-visual-shell, .otw-inner, .otw-content {
    min-width: 0;
  }
  /* Contacto unificado dentro de otw: se apila en móvil */
  .contact-wrap { grid-template-columns: 1fr; }
}

/* Fin del guard. Todo lo nuevo va antes de esta línea. */

/* ── 5. CENTRO DE NOTIFICACIONES — seguridad responsiva ────────── */
/* El panel flotante nunca más ancho que el viewport y bien anclado */
#notif-panel {
  max-width: calc(100vw - 20px);
  right: 10px;
}
#notif-panel.open {
  transform: translateY(0) scale(1);
}

/* 380px — mínimo soportado */
@media (max-width: 380px) {
  #notif-panel {
    width: calc(100vw - 16px);
    right: 8px;
    left: 8px;
    top: 4.2rem;
    max-height: 60vh;
  }
  #notif-btn { min-width: 34px; min-height: 34px; }
  #notif-badge { min-width: 14px; height: 14px; font-size: .45rem; }
}

/* 480px — panel casi a lo ancho, sin pegarse al borde */
@media (max-width: 480px) {
  #notif-panel {
    width: calc(100vw - 24px);
    right: 12px;
    left: 12px;
  }
  .notif-item { padding: .55rem .7rem; }
}

/* 720px — en tablets/landscape el panel queda a la derecha y tope superior ajustado */
@media (max-width: 720px) {
  #notif-panel { top: 4.4rem; }
  .header-inner { gap: 0.5rem; }
  .header-actions { gap: 0.4rem; }
}

/* ═══ 6. PWA INSTALADA — comportamiento de app nativa ═══════════════ */
/* Cuando CodeHub se ejecuta como app instalada (standalone), se activan
   ajustes para que se comporte como una app compilada, no como un sitio web. */

/* General: cuando está instalada, el header se adapta al status bar */
@media (display-mode: standalone) {
  /* Status bar transparente — el header se extiende detrás */
  header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    padding-top: env(safe-area-inset-top);
  }

  /* Body: contenido debajo del header + status bar */
  body {
    padding-top: calc(env(safe-area-inset-top) + 60px);
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
  }

  /* Ocultar barra de direcciones del navegador */
  html {
    overflow: hidden;
    overscroll-behavior: none;
  }

  /* Desactivar zoom en inputs */
  input, textarea, select {
    font-size: 16px !important;
  }

  /* Scroll suave sin rebote */
  body, html {
    overscroll-behavior: none;
    -webkit-overflow-scrolling: touch;
  }

  /* Links no abren en nueva pestaña */
  a[href^="http"]:not([href*="wilson360-labs.vercel.app"]) {
    target: _self;
  }

  /* Ocultar elementos de "navegador" */
  .browser-only {
    display: none !important;
  }

  /* Swipe back gesture hint */
  body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 4px;
    height: 100%;
    background: transparent;
    z-index: 99999;
    pointer-events: none;
  }

  /* Pull-to-refresh indicator */
  .ptr-indicator {
    display: none;
  }
}

/* Android standalone */
@media (display-mode: standalone) and (platform: android) {
  body {
    padding-bottom: env(safe-area-inset-bottom);
  }
}

/* iOS standalone */
@supports (-webkit-touch-callout: none) {
  @media (display-mode: standalone) {
    body {
      padding-top: calc(env(safe-area-inset-top) + 50px);
    }
    header {
      padding-top: env(safe-area-inset-top);
      height: calc(50px + env(safe-area-inset-top));
    }
  }
}

/* ═══ 7. VIEW TRANSITIONS — transiciones tipo app nativa ═══════════ */
/* Transiciones suaves entre páginas como una app compilada */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.3s;
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

::view-transition-old(root) {
  animation-name: slide-out-left;
}

::view-transition-new(root) {
  animation-name: slide-in-right;
}

@keyframes slide-out-left {
  from { transform: translateX(0); opacity: 1; }
  to { transform: translateX(-30px); opacity: 0; }
}

@keyframes slide-in-right {
  from { transform: translateX(30px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

/* Navegación activa — indicador animado */
.native-app #mobile-nav-bar a.active::after {
  content: '';
  position: absolute;
  bottom: 2px;
  left: 50%;
  transform: translateX(-50%);
  width: 20px;
  height: 3px;
  background: linear-gradient(135deg, #7c4dff, #2f80ed);
  border-radius: 2px;
  animation: navIndicator 0.3s ease;
}

@keyframes navIndicator {
  from { width: 0; opacity: 0; }
  to { width: 20px; opacity: 1; }
}

/* ── Diálogo de actualización ── */
@keyframes ch-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
#ch-update-overlay {
  animation: ch-fade-in .25s ease;
}
#ch-update-dialog {
  animation: ch-slide-up .3s cubic-bezier(.22,1,.36,1);
}
@keyframes ch-slide-up {
  from { opacity: 0; transform: translateY(20px) scale(.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  #ch-update-overlay, #ch-update-dialog { animation: none; }
}

/* ── Weather live indicator ─────────────────────────── */
.wx-live-dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #22c55e;
  margin-left: 4px;
  vertical-align: middle;
  animation: wx-pulse 2s ease-in-out infinite;
}
@keyframes wx-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(34,197,94,.6); }
  50% { opacity: .6; box-shadow: 0 0 0 4px rgba(34,197,94,0); }
}
@media (prefers-reduced-motion: reduce) {
  .wx-live-dot { animation: none; }
}
[data-theme="light"] .wx-live-dot { background: #16a34a; }

/* ── Minimapa del clima (Leaflet) ─────────────────────── */
.wx-map-box { display: block; margin-top: .5rem; }
.wx-map-togglebtn {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  width: 100%; padding: .8rem 1rem; border-radius: 14px; cursor: pointer;
  background: rgba(34,197,94,.1); border: 1px solid rgba(34,197,94,.28);
  color: #22c55e; font-weight: 700; font-size: .82rem; font-family: var(--font);
  transition: all .18s;
}
.wx-map-togglebtn:hover { background: rgba(34,197,94,.18); }
.wx-map-togglebtn > span { text-align: left; }
.wx-map-togglebtn .wx-map-caret { font-size: .75rem; opacity: .8; transition: transform .2s; }
.wx-map-inner { margin-top: .7rem; }
.wx-map-box.closed .wx-map-inner { display: none; }
.wx-map-search { display: flex; gap: .4rem; margin-bottom: .6rem; position: relative; }
/* Panel de búsqueda (input + sugerencias) con tema MATERIAL gris oscuro:
   bueno para ver el texto en claro y oscuro; el modo Google/Leaflet no
   cambia. El dropdown reemplaza al <datalist> nativo (no estilable). */
.wx-map-search .wx-input {
  flex: 1; min-width: 0; padding: .65rem .9rem;
  border-radius: 12px; border: 1px solid rgba(255,255,255,.14);
  background: linear-gradient(180deg, #2c3542, #232b36); /* material dark */
  color: #f2f5f9; caret-color: #22c55e; font-size: .88rem;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 2px 10px rgba(0,0,0,.35);
  transition: border-color .2s, box-shadow .2s;
}
.wx-map-search .wx-input::placeholder { color: rgba(242,245,249,.6); }
.wx-map-search .wx-input:focus {
  border-color: rgba(34,197,94,.65); outline: none;
  box-shadow: 0 0 0 3px rgba(34,197,94,.22), 0 2px 12px rgba(0,0,0,.4);
}
.wx-map-search .wx-input:focus::placeholder { color: rgba(242,245,249,.45); }

.wx-map-suggest-list {
  position: absolute; z-index: 1200; top: 100%; left: 0; right: 0;
  margin-top: 6px; overflow: hidden; text-align: left;
  background: #1e2630; color: #eef2f7;   /* material dark surface */
  border: 1px solid rgba(255,255,255,.12); border-radius: 12px;
  box-shadow: 0 14px 40px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.35);
}
.wx-map-suggest-list .wx-sug-item {
  display: flex; align-items: center; gap: .65rem; width: 100%;
  padding: .6rem .85rem; min-height: 48px; font-size: .85rem;
  text-align: left; background: transparent; border: none;
  border-bottom: 1px solid rgba(255,255,255,.07);
  color: inherit; cursor: pointer;
}
.wx-map-suggest-list .wx-sug-item:last-child { border-bottom: none; }
.wx-sug-emoji { font-size: 1.05rem; flex: 0 0 auto; line-height: 1; }
.wx-sug-text { display: flex; flex-direction: column; min-width: 0; }
.wx-sug-name {
  font-weight: 600; color: #ffffff; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.wx-sug-sub {
  font-size: .72rem; color: rgba(238,242,247,.62); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.wx-map-suggest-list .wx-sug-item:hover,
.wx-map-suggest-list .wx-sug-item:focus-visible,
.wx-map-suggest-list .wx-sug-item.active {
  background: rgba(34,197,94,.18);
  box-shadow: inset 3px 0 0 #22c55e;
}
.wx-map-suggest-list .wx-sug-empty {
  padding: .85rem 1rem; font-size: .8rem; color: rgba(238,242,247,.6);
  text-align: center;
}
@media (max-width: 480px) {
  .wx-map-suggest-list .wx-sug-item { font-size: .9rem; }
  .wx-sug-name { font-size: .9rem; }
  .wx-sug-sub { font-size: .76rem; }
}
.wx-map-search .wx-search-btn {
  border: none; width: 44px; min-width: 44px; border-radius: 12px;
  background: linear-gradient(135deg,#2f80ed,#22c55e); color: #fff; cursor: pointer;
}
.wx-minimap {
  width: 100%; height: 260px; border-radius: 14px;
  overflow: hidden; position: relative;
  border: 1px solid rgba(128,128,128,.25); z-index: 1;
  background: #a6cad4; /* color de respaldo tipo agua/cielo OSM */
}
/* En móvil: el contenedor del mapa debe capturar el gesto táctil (pan/zoom)
   y NO dejar que se haga scroll de toda la página al arrastrar. Leaflet ya
   aplica `touch-action: none` internamente; refuerza aquí por si el CSS
   externo u otro estilo lo sobreescribe en el móvil/WebView. */
.wx-minimap { touch-action: none; }
.wx-map-loading {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; gap: .5rem; font-size: .8rem; color: var(--muted, #666);
  flex-direction: column;
}
.wx-spinner-map {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid rgba(34,197,94,.2); border-top-color: #22c55e;
  animation: spin .8s linear infinite;
}
.wx-map-fail {
  padding: 1.4rem; text-align: center; font-size: .8rem;
  color: #b45309; line-height: 1.5;
}
/* Aviso cuando TODAS las capas de teselas fallaron (calles y
   satélite): se superpone al mapa (que puede seguir ahí, arrastrable,
   solo sin imágenes) en vez de reemplazar el contenedor entero, para
   poder reintentar sin perder el zoom/posición elegidos. */
.wx-map-fail-overlay {
  position: absolute; inset: 0; z-index: 650;
  display: flex; align-items: center; justify-content: center;
  background: rgba(10, 14, 20, .82);
  color: #fde68a;
}
.wx-map-retry-btn {
  display: block; margin: .7rem auto 0; padding: .5rem 1.1rem;
  border: none; border-radius: 10px; cursor: pointer;
  background: linear-gradient(135deg,#22c55e,#16a34a); color: #fff;
  font-weight: 700; font-size: .78rem;
}
.wx-map-retry-btn:active { transform: scale(.96); }
.wx-map-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; margin-top: .6rem; font-size: .75rem; color: var(--muted, #888);
  text-overflow: ellipsis; overflow: hidden; white-space: nowrap;
}
.wx-map-select-btn {
  flex-shrink: 0; padding: .55rem .9rem; border: none; border-radius: 10px;
  background: linear-gradient(135deg,#22c55e,#16a34a); color: #fff;
  font-weight: 700; font-size: .75rem; cursor: pointer; white-space: nowrap;
}
.wx-map-select-btn:active { transform: scale(.96); }
.wx-map-marker svg { filter: drop-shadow(0 2px 4px rgba(0,0,0,.4)); }
.wx-minimap.leaflet-container { font: inherit; }
.wx-minimap .leaflet-control-attribution { font-size: 9px !important; background: rgba(255,255,255,.7) !important; }
.wx-minimap .leaflet-bar a { color: #333 !important; }

/* Selector de capas (Calles/Satélite): en escritorio queda expandido,
   pero en móvil un panel fijo de ~150px de ancho puede tapar la mitad
   del mapa (312px de ancho típico). Se compacta para que no invada el
   mapa; weather-map.js además lo inicia colapsado (ícono de capas) en
   pantallas angostas. */
.wx-minimap .leaflet-control-layers {
  font-size: 12px; background: rgba(255,255,255,.92);
}
.wx-minimap .leaflet-control-layers-expanded {
  padding: 6px 10px; max-width: 128px; line-height: 1.5;
}
.wx-minimap .leaflet-control-layers-toggle {
  width: 32px !important; height: 32px !important;
}

/* Continuidad de breakpoints en todo el rango móvil canónico
   (380–730px): antes solo existían reglas en 720 y 380px, dejando un
   salto brusco de tamaño en 420/480/550/640 donde el mapa/controles
   podían quedar desproporcionados según el ancho exacto del teléfono. */
@media (max-width: 720px) {
  .wx-minimap { height: 220px; }
  .wx-map-retry-btn { font-size: .74rem; padding: .45rem 1rem; }
}
@media (max-width: 640px) {
  .wx-minimap { height: 212px; }
}
@media (max-width: 550px) {
  .wx-minimap { height: 204px; }
  .wx-map-fail-overlay { font-size: .78rem; padding: 0 1rem; }
}
@media (max-width: 480px) {
  .wx-minimap { height: 196px; }
  .wx-minimap .leaflet-control-layers-expanded { max-width: 104px; font-size: 11px; padding: 5px 8px; }
}
@media (max-width: 420px) {
  .wx-minimap { height: 190px; }
  .wx-map-foot { flex-direction: column; align-items: stretch; white-space: normal; }
  .wx-map-select-btn { width: 100%; }
}
@media (max-width: 380px) {
  .wx-minimap { height: 176px; }
  .wx-map-fail-overlay { font-size: .72rem; }
  .wx-map-retry-btn { font-size: .7rem; padding: .4rem .85rem; }
}

/* ── Panel de clima mejorado ─────────────────────────── */
.wx-card {
  position: relative; overflow: hidden;
  background: linear-gradient(160deg, rgba(13,13,26,.96), rgba(17,24,39,.92));
}
.wx-main { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.2rem; }
.wx-big {
  font-size: 3.4rem; line-height: 1; flex-shrink: 0;
  filter: drop-shadow(0 3px 8px rgba(0,0,0,.35));
}
.wx-hdr { flex: 1; min-width: 0; }
/* Evita que Chrome móvil "infle" el texto (font boosting) cuando esta
   columna queda muy angosta entre el ícono y la temperatura, y evita
   que el nombre de la ciudad se parta en una palabra por línea. */
.wx-city {
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  overflow-wrap: break-word; word-break: normal; hyphens: auto;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.wx-feels { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
.wx-temp-row { display: flex; align-items: flex-end; gap: .7rem; flex-wrap: wrap; }
.wx-temp { margin-top: .2rem; flex-shrink: 0; }
.wx-desc { font-size: 1rem; font-weight: 600; margin: 0 0 .25rem; padding-bottom: .35rem; }
.wx-feels { margin-top: .1rem; }
.wx-stat i { font-size: 1.05rem; }

/* Breakpoint canónico (720): cubre todo el rango móvil 380–720px. En
   la mayoría de móviles en vertical (360–430px reales) Y en teléfonos
   grandes/landscape (hasta 720px) el layout en fila (ícono + ciudad +
   temperatura) deja la columna de la ciudad casi sin espacio, forzando
   el "font boosting" de Chrome que se ve en el reporte. Se apila en
   columna en todo ese rango. */
@media (max-width: 720px) {
  .wx-main { flex-direction: column; align-items: flex-start; gap: .5rem; }
  .wx-big { font-size: 2.6rem; }
  .wx-city { -webkit-line-clamp: 2; max-width: 100%; }
  .wx-temp-row { width: 100%; }
}

@media (max-width: 480px) {
  .wx-big { font-size: 2.45rem; }
}

@media (max-width: 380px) {
  .wx-big { font-size: 2.3rem; }
}

/* ── Selector de frecuencia de notificaciones ────────── */
.wx-interval {
  margin-top: .7rem; padding: .7rem .8rem;
  border: 1px solid rgba(128,128,128,.25); border-radius: 14px;
  background: rgba(128,128,128,.06);
}
.wx-interval-label {
  display: flex; align-items: center; gap: .4rem;
  font-size: .8rem; font-weight: 700; margin-bottom: .6rem;
  color: var(--text, currentColor);
}
.wx-interval-label i { color: #22c55e; }
.wx-interval-options {
  display: flex; flex-wrap: wrap; gap: .4rem;
}
.wx-int-btn {
  border: 1px solid rgba(128,128,128,.3); background: transparent;
  color: var(--text, currentColor); padding: .45rem .7rem;
  border-radius: 999px; font-size: .75rem; cursor: pointer;
  transition: all .15s;
}
.wx-int-btn.active {
  background: linear-gradient(135deg,#2f80ed,#22c55e);
  color: #fff; border-color: transparent; font-weight: 700;
}
.wx-interval-hint {
  margin-top: .55rem; font-size: .7rem; color: var(--muted, #888);
  line-height: 1.4;
}
@media (max-width: 380px) {
  .wx-int-btn { flex: 1 1 40%; text-align: center; }
  .wx-map-foot { flex-direction: column; align-items: stretch; white-space: normal; }
  .wx-map-select-btn { width: 100%; }
}

/* ── EMI: barra de modos ───────────────────────────────────── */
.ai-modes-bar {
  display: flex; gap: .4rem; padding: .5rem .75rem;
  background: var(--ai-s1, #1c1c26);
  border-bottom: 1px solid var(--ai-border2, rgba(255,255,255,.07));
  flex-shrink: 0; overflow-x: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; position: relative; z-index: 1;
}
.ai-modes-bar::-webkit-scrollbar { display: none; }
.ai-mode-chip {
  flex-shrink: 0; white-space: nowrap;
  padding: .3rem .65rem; border-radius: var(--radius-full, 50px);
  border: 1px solid var(--ai-border, rgba(255,255,255,.09));
  background: transparent; color: var(--ai-muted, rgba(210,210,225,.5));
  font-size: .72rem; font-weight: 600; cursor: pointer;
  transition: all .15s;
}
.ai-mode-chip:hover { border-color: rgba(124,77,255,.45); color: var(--ai-text, #ECECF3); }
.ai-mode-chip.active {
  background: linear-gradient(135deg, #7C4DFF, #00B0FF);
  color: #fff; border-color: transparent; box-shadow: 0 2px 8px rgba(124,77,255,.35);
}

/* ── EMI: pantalla completa ────────────────────────────────── */
#ai-panel.ai-fullscreen {
  right: 0; bottom: 0; width: 100vw; height: 100dvh; max-height: 100dvh;
  min-height: 100dvh; border-radius: 0; border: none;
}
@media (max-width: 768px) {
  .ai-head-actions { gap: 4px; }
  .ai-modes-bar { padding: .45rem .65rem; }
}

/* ── EMI: cuerpo del chat (sin sidebar fijo) ──────────────── */
#ai-panel { display: flex; flex-direction: column; }
.ai-body {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  overflow: hidden;
}
#ai-msgs { flex: 1; min-height: 0; }

/* ── EMI: menú hamburguesa deslizante (drawer) ────────────── */
.emi-drawer {
  position: fixed; inset: 0; z-index: 9700;
  display: flex; justify-content: flex-start;
  pointer-events: none;
}
.emi-drawer-scrim {
  position: absolute; inset: 0; background: rgba(0,0,0,.5);
  opacity: 0; transition: opacity .28s;
  backdrop-filter: blur(2px);
}
.emi-drawer-panel {
  position: relative; width: min(300px, 82vw); height: 100%;
  background: var(--ai-bg, #17171f);
  border-right: 1px solid var(--ai-border, rgba(255,255,255,.09));
  box-shadow: 0 0 40px rgba(0,0,0,.5);
  display: flex; flex-direction: column;
  transform: translateX(-100%);
  transition: transform .3s cubic-bezier(.2,.9,.2,1);
  overflow: hidden;
}
.emi-drawer.is-open { pointer-events: all; }
.emi-drawer.is-open .emi-drawer-scrim { opacity: 1; }
.emi-drawer.is-open .emi-drawer-panel { transform: translateX(0); }

.emi-drawer-head {
  flex-shrink: 0; display: flex; align-items: center; justify-content: space-between;
  padding: 1rem 1rem .9rem; border-bottom: 1px solid var(--ai-border2, rgba(255,255,255,.07));
  background: linear-gradient(135deg, rgba(124,77,255,.16), rgba(0,176,255,.1));
}
.emi-drawer-title {
  font-size: .9rem; font-weight: 800; color: var(--ai-text, #ECECF3);
  display: flex; flex-direction: column; gap: .2rem;
}
.emi-drawer-status {
  font-size: .62rem; font-weight: 600; color: var(--ai-muted, rgba(210,210,225,.5));
  display: flex; align-items: center; gap: .35rem;
}
.emi-drawer-status .online-dot { font-size: .38rem; color: #3ecf8e; }
.emi-drawer-close {
  width: 30px; height: 30px; border-radius: 9px; border: 1px solid var(--ai-border, rgba(255,255,255,.09));
  background: transparent; color: var(--ai-muted, rgba(210,210,225,.5)); cursor: pointer; font-size: .9rem;
}
.emi-drawer-close:hover { color: #fff; background: rgba(255,255,255,.08); }
.emi-drawer-body {
  flex: 1; min-height: 0; overflow-y: auto; padding: .6rem .8rem 1.2rem;
  scrollbar-width: thin;
}

.emi-sec {
  font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ai-accent, #7C4DFF); margin: 1rem 0 .4rem;
}
.emi-sec:first-child { margin-top: .3rem; }

.emi-item {
  display: flex; align-items: center; gap: .75rem; width: 100%;
  background: none; border: none; color: var(--ai-text, #ECECF3);
  font-size: .8rem; text-align: left; padding: .62rem .7rem;
  border-radius: var(--radius-sm, 10px); cursor: pointer; transition: background .15s;
}
.emi-item i { width: 17px; text-align: center; color: var(--ai-accent, #7C4DFF); font-size: .9rem; }
.emi-item:hover { background: rgba(124,77,255,.14); }
.emi-item.danger i { color: #ff5c6c; }
.emi-item.danger:hover { background: rgba(255,92,108,.12); }

.emi-mode {
  display: flex; align-items: center; gap: .7rem; width: 100%;
  background: none; border: 1px solid transparent; color: var(--ai-text, #ECECF3);
  font-size: .78rem; text-align: left; padding: .55rem .7rem;
  border-radius: var(--radius-sm, 10px); cursor: pointer; transition: all .15s; margin-bottom: .25rem;
}
.emi-mode:hover { background: rgba(124,77,255,.1); }
.emi-mode.is-active { background: linear-gradient(135deg, rgba(124,77,255,.22), rgba(0,176,255,.16)); border-color: rgba(124,77,255,.35); }
.emi-mode-ico { font-size: 1rem; }
.emi-mode-lbl { flex: 1; }
.emi-mode-check { color: #7C4DFF; font-weight: 800; }

.emi-usage {
  background: rgba(255,255,255,.035); border: 1px solid var(--ai-border, rgba(255,255,255,.07));
  border-radius: var(--radius-sm, 10px); padding: .6rem .7rem; margin-bottom: .4rem;
}
.emi-usage-top { display: flex; justify-content: space-between; font-size: .74rem; color: var(--ai-muted, rgba(210,210,225,.5)); }
.emi-usage-top b { color: var(--ai-text, #ECECF3); }
.emi-usage-bar { height: 6px; border-radius: 50px; background: rgba(255,255,255,.08); overflow: hidden; margin: .45rem 0 .35rem; }
.emi-usage-bar > span { display: block; height: 100%; border-radius: 50px; background: linear-gradient(90deg,#7C4DFF,#00B0FF); }
.emi-usage-hint { font-size: .66rem; color: var(--ai-muted, rgba(210,210,225,.5)); }

.emi-opt-row { display: flex; gap: .4rem; padding: 0 .1rem; }
.emi-pill {
  flex: 1 1 auto; min-width: 42px; padding: .4rem .5rem; text-align: center;
  font-size: .72rem; font-weight: 600; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--ai-border, rgba(255,255,255,.09));
  background: transparent; color: var(--ai-muted, rgba(210,210,225,.5)); transition: all .15s;
}
.emi-pill:hover { border-color: rgba(124,77,255,.45); color: #fff; }
.emi-pill.is-active { background: linear-gradient(135deg,#7C4DFF,#00B0FF); color: #fff; border-color: transparent; box-shadow: 0 2px 8px rgba(124,77,255,.3); }
.emi-opt-hint { font-size: .64rem; color: var(--ai-muted, rgba(210,210,225,.4)); margin: .4rem 0 .3rem; }
.emi-check {
  display: flex; align-items: center; justify-content: space-between;
  padding: .5rem .1rem; font-size: .76rem; color: var(--ai-text, #ECECF3);
}
.emi-check input[type="checkbox"] { width: 15px; height: 15px; accent-color: #7C4DFF; cursor: pointer; }

/* Botón de menú en el header */
.ai-menu-trigger { background: rgba(124,77,255,.12); border-color: rgba(124,77,255,.3) !important; color: #fff; }
.ai-menu-trigger:hover { background: rgba(124,77,255,.25); }

/* ── Sección SISMOS ─────────────────────────────────────────────
   Mapa oscuro estilo centros meteorológicos (Carto dark). Respeto de
   breakpoints canónicos y variables del theme (--text/--muted/--card-bg)
   para que luzca bien en claro y oscuro. Guard en la última capa. */
.sismos-toolbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: .6rem;
  margin-bottom: .8rem;
}
.sismos-filter-label {
  font-size: .78rem; color: var(--muted, #888); display: flex; align-items: center; gap: .4rem;
}
.sismos-mag-options { display: flex; gap: .4rem; flex-wrap: wrap; }
.sismos-mag-btn {
  padding: .45rem .85rem; min-height: 40px; font-size: .8rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.12); border-radius: 10px;
  cursor: pointer; color: var(--text, #eee);
  white-space: nowrap;
}
.sismos-mag-btn.active, .sismos-mag-btn:hover {
  background: rgba(34,197,94,.2); border-color: rgba(34,197,94,.6); color: #22c55e;
}
.sismos-summary { margin-bottom: .7rem; }
#sismos-count-chip {
  display: inline-block; font-size: .78rem; padding: .35rem .8rem;
  background: rgba(255,69,0,.12); border: 1px solid rgba(255,69,0,.3);
  border-radius: 999px; color: #ff8a5c;
}
/* ── Lugares con sismos detectados (panel expansible por país) ── */
.sismos-places {
  position: relative; z-index: 1; margin: 0 0 .8rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.1); border-radius: 14px;
  overflow: hidden;
}
.sismos-places-header {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  padding: .7rem .9rem; background: transparent; border: 0;
  color: var(--text, #eee); cursor: pointer; text-align: left;
  font-size: .85rem; font-weight: 600; font-family: inherit;
}
.sismos-places-header:hover { background: rgba(34,197,94,.06); }
.sismos-places-title {
  flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: .5rem;
}
.sismos-places-title i { color: #22c55e; }
.sismos-places-count {
  font-size: .74rem; color: var(--muted, #888);
  background: rgba(34,197,94,.12); border: 1px solid rgba(34,197,94,.3);
  border-radius: 999px; padding: .15rem .55rem; white-space: nowrap;
}
.sismos-places-chev { transition: transform .25s ease; color: var(--muted, #888); }
.sismos-places.open .sismos-places-chev { transform: rotate(180deg); }
.sismos-places-body {
  display: none; padding: 0 .9rem .8rem;
}
.sismos-places.open .sismos-places-body { display: block; }
.sismos-places-chips {
  display: flex; flex-wrap: wrap; gap: .4rem;
}
.sismos-place-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .4rem .7rem; min-height: 36px; font-size: .76rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.12); border-radius: 999px;
  cursor: pointer; color: var(--text, #eee); white-space: nowrap;
}
.sismos-place-chip b { font-weight: 700; color: #ff8a5c; }
.sismos-place-chip.active, .sismos-place-chip:hover {
  background: rgba(34,197,94,.18); border-color: rgba(34,197,94,.6); color: #22c55e;
}
.sismos-place-chip.active b, .sismos-place-chip:hover b { color: #22c55e; }
.sismos-places-empty {
  font-size: .74rem; color: var(--muted, #888);
}
.sismos-places-note {
  margin-top: .5rem; font-size: .72rem; color: var(--muted, #888);
  line-height: 1.45;
}
@media (max-width: 480px) {
  .sismos-places-chips { max-height: 168px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .sismos-place-chip { flex: 1 1 auto; justify-content: center; }
}
.sismos-map {
  width: 100%; height: 340px; border-radius: 14px; overflow: hidden;
  border: 1px solid rgba(128,128,128,.25); position: relative; z-index: 1;
  background: #1c2430;
}
.sismos-map { touch-action: none; }
.sismos-stage {
  position: relative;
}
.sismos-carousel {
  position: absolute; left: 0; right: 0; bottom: 10px;
  z-index: 5;
  display: flex; gap: .6rem;
  overflow-x: auto; overflow-y: hidden;
  padding: 0 10px 2px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.sismos-carousel::-webkit-scrollbar { display: none; }
.sismos-car-card {
  scroll-snap-align: start;
  flex: 0 0 auto;
  width: min(240px, 54vw);
  display: flex; align-items: center; gap: .55rem;
  padding: .5rem .6rem;
  border-radius: 12px;
  background: rgba(10,14,20,.74);
  border: 1px solid rgba(255,255,255,.16);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  cursor: pointer;
  font-family: inherit;
  color: #fff;
  text-align: left;
  transition: transform .18s ease, border-color .18s ease, background .18s ease;
}
.sismos-car-card:hover, .sismos-car-card:focus-visible {
  border-color: rgba(34,197,94,.6);
  background: rgba(16,22,32,.88);
  transform: translateY(-2px);
  outline: none;
}
.sismos-car-badge {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 10px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-weight: 700; line-height: 1.05; color: #fff;
}
.sismos-car-badge b { font-size: .95rem; }
.sismos-car-badge span { font-size: .56rem; opacity: .8; }
.sismos-car-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sismos-car-place {
  font-weight: 600; font-size: .78rem; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sismos-car-meta { font-size: .7rem; color: rgba(255,255,255,.62); margin-top: .1rem; }
.sismos-car-arrow { flex: 0 0 auto; color: rgba(255,255,255,.45); font-size: .8rem; }
.sismos-car-empty {
  flex: 0 0 auto;
  color: rgba(255,255,255,.75); font-size: .78rem;
  padding: .6rem .8rem;
  background: rgba(10,14,20,.6);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 10px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.sismos-list {
  margin-top: 1rem; display: flex; flex-direction: column; gap: .5rem;
}
.sismos-item {
  display: flex; align-items: center; gap: .8rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.1); border-radius: 14px;
  padding: .7rem .9rem; cursor: pointer;
}
.sismos-item:hover { border-color: rgba(34,197,94,.5); background: rgba(34,197,94,.08); }
.sismos-badge {
  flex: 0 0 auto; width: 46px; height: 46px; border-radius: 12px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-weight: 700; line-height: 1.05; color: #fff;
}
.sismos-badge b { font-size: 1rem; }
.sismos-badge span { font-size: .6rem; opacity: .8; }
.sismos-item-main { flex: 1; min-width: 0; }
.sismos-item-place {
  font-weight: 600; font-size: .85rem; color: var(--text, #eee);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sismos-item-meta {
  font-size: .74rem; color: var(--muted, #888); margin-top: .15rem;
}
.sismos-none {
  text-align: center; padding: 1.4rem; color: var(--muted, #888); font-size: .85rem;
}
.sismos-legend {
  display: flex; flex-wrap: wrap; gap: .6rem; margin-top: .7rem;
  font-size: .72rem; color: #fff;
  background: rgba(10,14,20,.62); border: 1px solid rgba(255,255,255,.18);
  padding: .4rem .7rem; border-radius: 10px;
  backdrop-filter: blur(3px);
}
.sismos-legend span { display: inline-flex; align-items: center; gap: .35rem; }
.sismos-legend i { width: 12px; height: 12px; border-radius: 50%; display: inline-block; }
/* Colores de magnitud (clases compartidas con el JS) */
.sm-0 { background: #2f80ed; }
.sm-4 { background: #38bdf8; }
.sm-5 { background: #f59e0b; }
.sm-6 { background: #e11d48; }
@media (max-width: 768px) {
  .sismos-map { height: 300px; }
}
@media (max-width: 480px) {
  .sismos-map { height: 260px; }
  .sismos-toolbar { flex-direction: column; align-items: flex-start; gap: .45rem; }
  .sismos-mag-btn { flex: 1 1 auto; }
  .sismos-mag-options { width: 100%; justify-content: space-between; }
}

/* ── Lista de sismos en móvil: panel deslizante (no roba espacio) ──
   La lista vertical queda fuera del flujo en pantallas ≤ 768px; se abre
   desde un launcher con un panel fijo (bottom sheet) que se desliza sobre
   la web y no ocupa layout. Desktop conserva la lista inline. */
.sismos-sheet-open { display: none; }
body.ch-sismos-sheet-locked { overflow: hidden; }

@keyframes chSismosFadeUp {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes chSismosPulse {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(34,197,94,0)); }
  50% { transform: scale(1.14); filter: drop-shadow(0 0 8px rgba(34,197,94,.55)); }
}
@keyframes chSismosPop {
  0% { transform: scale(.4) rotate(-14deg); opacity: 0; }
  60% { transform: scale(1.18) rotate(4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}
@keyframes chSismosSpinUp {
  to { transform: rotate(180deg); }
}

@media (max-width: 768px) {
  .sismos-list { display: none; }
  .sismos-sheet-open {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    width: 100%; margin-top: .8rem; padding: .7rem;
    font-family: inherit; font-size: .85rem; font-weight: 600; color: #fff;
    background: rgba(34,197,94,.12); border: 1px solid rgba(34,197,94,.4);
    border-radius: 12px; cursor: pointer;
    animation: chSismosFadeUp .4s cubic-bezier(.2,.9,.3,1.15) both;
  }
  .sismos-sheet-open i {
    display: inline-block;
    animation: chSismosPulse 2.8s ease-in-out infinite;
  }
  .sismos-sheet-open:hover i { animation: chSismosSpinUp .3s ease forwards; }
  .sismos-sheet-open:active { background: rgba(34,197,94,.24); }
  .sismos-sheet-open b { color: #22c55e; font-weight: 800; }
  .sismos-sheet-backdrop {
    position: fixed; inset: 0; z-index: 9990;
    background: rgba(0,0,0,.55);
    opacity: 0; pointer-events: none;
    transition: opacity .22s ease;
  }
  .sismos-sheet-backdrop.open { opacity: 1; pointer-events: auto; }
  .sismos-sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 9991;
    max-height: 72vh; border-radius: 18px 18px 0 0;
    background: #101520;
    border: 1px solid rgba(255,255,255,.14); border-bottom: none;
    display: flex; flex-direction: column;
    transform: translateY(103%);
    transition: transform .26s cubic-bezier(.32,.72,.35,1);
    will-change: transform;
    box-shadow: 0 -8px 30px rgba(0,0,0,.5);
  }
  .sismos-sheet.open { transform: translateY(0); }
  .sismos-sheet-grab {
    flex: 0 0 auto; height: 22px;
    display: flex; align-items: center; justify-content: center;
    cursor: grab; touch-action: pan-y;
  }
  .sismos-sheet-grab::before {
    content: ''; width: 44px; height: 5px; border-radius: 3px;
    background: rgba(255,255,255,.32);
  }
  .sismos-sheet-head {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: space-between;
    padding: .2rem .9rem .6rem;
  }
  .sismos-sheet-head > span {
    display: inline-flex; align-items: center; gap: .45rem;
    font-weight: 700; font-size: .9rem; color: var(--text, #eee);
  }
  .sismos-sheet-head > span i {
    color: #22c55e; display: inline-block;
  }
  .sismos-sheet.open .sismos-sheet-head > span i {
    animation: chSismosPop .5s cubic-bezier(.2,.9,.3,1.4) .1s both;
  }
  #sismos-sheet-count { color: #22c55e; }
  .sismos-sheet-head button {
    width: 34px; height: 34px; border-radius: 10px;
    border: 1px solid rgba(255,255,255,.14);
    background: rgba(255,255,255,.06); color: #fff; font-size: 1rem; cursor: pointer;
    transition: background .18s ease, transform .18s ease;
  }
  .sismos-sheet-head button:hover { background: rgba(255,255,255,.14); }
  .sismos-sheet-head button:active {
    background: rgba(255,255,255,.2); transform: scale(.92);
  }
  .sismos-sheet-head button i { display: inline-block; transition: transform .25s ease; }
  .sismos-sheet-head button:hover i { transform: rotate(90deg); }
  .sismos-sheet-body {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 0 .9rem calc(.9rem + env(safe-area-inset-bottom));
    display: flex; flex-direction: column; gap: .5rem;
  }
}

@media (min-width: 768px) {
  .sismos-sheet, .sismos-sheet-backdrop, .sismos-sheet-open { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .sismos-sheet-open,
  .sismos-sheet-open i,
  .sismos-sheet.open .sismos-sheet-head > span i,
  .sismos-sheet-head button i {
    animation: none !important;
    transition: none !important;
  }
}

/* ── Alertas de sismos por push (toggle + umbral de magnitud) ── */
.sismos-alerts {
  margin: 0 0 .8rem; padding: .7rem .8rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.1); border-radius: 14px;
}
.sismos-alerts-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: .7rem;
}
.sismos-alerts-row .wx-alerts-toggle {
  flex: 1 1 220px; margin: 0;
}
.sismos-alert-mag {
  display: flex; align-items: center; gap: .35rem;
}
.sismos-alert-mag-label {
  font-size: .72rem; color: var(--muted, #888);
  display: inline-flex; align-items: center; gap: .35rem;
}
.sismos-alert-mag-btn {
  padding: .4rem .7rem; min-height: 38px; font-size: .78rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.12); border-radius: 10px;
  cursor: pointer; color: var(--text, #eee); white-space: nowrap;
}
.sismos-alert-mag-btn.active, .sismos-alert-mag-btn:hover {
  background: rgba(255,69,0,.16); border-color: rgba(255,110,40,.6); color: #ff8a5c;
}
.sismos-alerts-hint {
  margin-top: .45rem; font-size: .72rem; color: var(--muted, #888);
  line-height: 1.45; min-width: 0;
}
@media (max-width: 480px) {
  .sismos-alerts-row { flex-direction: column; align-items: stretch; gap: .5rem; }
  .sismos-alert-mag { justify-content: flex-start; flex-wrap: wrap; }
  .sismos-alert-mag-btn { flex: 1 1 auto; }
  .sismos-alert-mag-label { width: 100%; }
}

/* ═══════════════════════════════════════════════════════════
   MOTOR GEO UNIFICADO — CHGeo
   Panel de Sol (amanecer/atardecer) con cielo animado por fases,
   dock de navegación Clima ⇄ Sismos y reflejo día/noche en sismos.
   Todo con CSS puro + variables del tema (última capa).
   ═══════════════════════════════════════════════════════════ */

/* ── Geo dock: centro geográfico común ───────────────────── */
.geo-dock {
  display: flex; gap: .5rem; margin: .2rem 0 .9rem; padding: .3rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.1); border-radius: 14px;
  width: 100%;
}
.geo-dock-btn {
  flex: 1 1 auto; padding: .5rem .8rem; font-size: .82rem; font-weight: 600;
  color: var(--muted, #999); background: transparent; border: 1px solid transparent;
  border-radius: 10px; cursor: pointer; min-height: 42px;
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  transition: all .18s;
}
.geo-dock-btn:hover { color: var(--text, #eee); }
.geo-dock-btn.active {
  background: linear-gradient(135deg, rgba(47,128,237,.2), rgba(34,197,94,.18));
  border-color: rgba(47,128,237,.4); color: var(--text, #eee);
}

/* ── Cielo: gradiente por fase (amanecer → día → atardecer → noche) ── */
.wx-sun { margin: .8rem 0 .2rem; }
.wx-sun-sky {
  position: relative; height: 118px; border-radius: 16px; overflow: hidden;
  transition: background 2.5s ease;
}
.wx-sun-sky[data-sky="day"]   { background: linear-gradient(180deg, #2f9bea, #7cc7ff 55%, #e3f4ff); }
.wx-sun-sky[data-sky="dawn"]  { background: linear-gradient(180deg, #2b4a7c, #e88e5a 60%, #ffd98a); }
.wx-sun-sky[data-sky="dusk"]  { background: linear-gradient(180deg, #1d2150, #7b2b6f 50%, #e8874a 85%, #ffca7a); }
.wx-sun-sky[data-sky="night"] { background: linear-gradient(180deg, #070b1d, #152449 60%, #23375f); }

.wx-sun-arc { position: absolute; inset: 0; }

/* ── Sol / Luna (formas CSS puras, sin emojis) ───────────── */
.wx-sun-disc, .wx-moon-disc {
  position: absolute; transform: translate(-50%, -50%);
  transition: left 2s linear, top 2s linear;
}
.wx-sun-disc {
  left: var(--sun-x, 50%); top: var(--sun-y, 105%); z-index: 2;
  width: 46px; height: 46px;
}
.wx-sun-disc::before {
  content: ''; position: absolute; inset: -15px; border-radius: 50%;
  background: repeating-conic-gradient(rgba(255,200,60,.9) 0deg 14deg, transparent 14deg 36deg);
  -webkit-mask: radial-gradient(circle, transparent 0 40%, #000 46%);
  mask: radial-gradient(circle, transparent 0 40%, #000 46%);
  animation: wx-sun-spin 30s linear infinite;
}
.wx-sun-disc::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff7cc, #ffd34d 45%, #ff9d2e 100%);
  box-shadow: 0 0 24px 6px rgba(255,180,40,.55), 0 0 60px 18px rgba(255,160,40,.25);
  animation: wx-sun-breath 4s ease-in-out infinite;
}
.wx-moon-disc {
  left: var(--moon-x, 50%); top: var(--moon-y, 105%); z-index: 2;
  width: 38px; height: 38px; display: none;
}
.wx-moon-disc::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, #fcfdfd, #cfd8e6 55%, #93a3bd);
  box-shadow: 0 0 18px 5px rgba(200,215,255,.35);
}
.wx-moon-disc::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  transform: translate(7px, -5px);
  background: #000;
  -webkit-mask: radial-gradient(circle, transparent 0 58%, #000 62%);
  mask: radial-gradient(circle, transparent 0 58%, #000 62%);
  opacity: .6;
}
.wx-sun-sky[data-sky="night"] .wx-sun-disc { animation: none; opacity: 0; }
.wx-sun-sky[data-sky="night"] .wx-moon-disc,
.wx-sun-sky[data-sky="dawn"] .wx-moon-disc,
.wx-sun-sky[data-sky="dusk"] .wx-moon-disc { display: block; }
.wx-sun-sky[data-sky="dawn"] .wx-moon-disc,
.wx-sun-sky[data-sky="dusk"] .wx-moon-disc { opacity: .4; }

@keyframes wx-sun-spin { to { transform: rotate(360deg); } }
@keyframes wx-sun-breath {
  0%, 100% { box-shadow: 0 0 24px 6px rgba(255,180,40,.55), 0 0 60px 18px rgba(255,160,40,.25); }
  50%      { box-shadow: 0 0 30px 9px rgba(255,190,50,.75), 0 0 78px 26px rgba(255,170,45,.38); }
}

/* ── Estrellas (parpadeo de noche) ───────────────────────── */
.wx-star {
  position: absolute; display: block; width: 5px; height: 5px; border-radius: 50%;
  background: #fff; opacity: 0;
}
.wx-sun-sky[data-sky="night"] .wx-star,
.wx-sun-sky[data-sky="dawn"] .wx-star,
.wx-sun-sky[data-sky="dusk"] .wx-star {
  opacity: 1;
  animation: wx-star-tw 2.6s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}
@keyframes wx-star-tw { 0%, 100% { opacity: .9; } 50% { opacity: .15; } }

/* ── Nube a la deriva (día) ──────────────────────────────── */
.wx-cloud {
  position: absolute; left: -90px; top: 26px; width: 64px; height: 18px;
  opacity: 0;
}
.wx-sun-sky[data-sky="day"] .wx-cloud { opacity: .65; animation: wx-cloud-drift 42s linear infinite; }
.wx-cloud span {
  position: absolute; inset: 0; border-radius: 12px; background: rgba(255,255,255,.92);
}
.wx-cloud span::before, .wx-cloud span::after {
  content: ''; position: absolute; border-radius: 50%; background: inherit;
}
.wx-cloud span::before { width: 26px; height: 26px; top: -13px; left: 8px; }
.wx-cloud span::after  { width: 18px; height: 18px; top: -8px; right: 8px; }
@keyframes wx-cloud-drift { to { left: 110%; } }

/* ── Horarios Salida / Puesta (tipografía cuidada, sin emojis) ── */
.wx-sun-times {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .55rem .1rem 0;
}
.wx-sun-time { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.wx-sun-time i { font-size: .95rem; color: #f9b23c; }
.wx-sun-time:last-child i { color: #e8874a; }
.wx-sun-time b { font-size: 1rem; letter-spacing: .5px; }
.wx-sun-time small {
  display: block; font-size: .62rem; color: var(--muted, #888);
  text-transform: uppercase; letter-spacing: .6px;
}
.wx-sun-dur {
  font-size: .72rem; color: var(--muted, #888); padding-top: 1px;
  font-family: var(--mono, "SFMono-Regular", Consolas, monospace);
  white-space: nowrap;
}

/* ── Fase lunar (mes sinódico calculado en el motor CHGeo) ── */
.wx-moon {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  margin: .5rem auto 0; padding: .42rem .85rem;
  background: var(--card-bg, rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.1); border-radius: 999px;
  width: max-content; max-width: 100%;
}
.wx-moon > i { color: #93c5fd; font-size: .95rem; }
#wx-moon-name {
  font-size: .82rem; font-weight: 600; color: var(--text, #eee);
  white-space: nowrap;
}
.wx-moon-illum {
  font-size: .72rem; color: var(--muted, #888);
  font-family: var(--mono, "SFMono-Regular", Consolas, monospace);
  white-space: nowrap;
}

/* ── Reflejo día/noche en la sección de sismos (mismo motor) ── */
.sismos-map[data-sky="night"] { box-shadow: inset 0 0 60px rgba(5,10,30,.6); }
.sismos-map[data-sky="dusk"],
.sismos-map[data-sky="dawn"] { box-shadow: inset 0 0 50px rgba(255,150,60,.14); }
.sismos-map[data-sky="day"] { box-shadow: inset 0 0 40px rgba(255,255,255,.06); }

/* ── Responsivo (solo breakpoints canónicos) ─────────────── */
@media (max-width: 768px) {
  .wx-sun-sky { height: 104px; }
}
@media (max-width: 480px) {
  .wx-sun-sky { height: 92px; }
  .wx-sun-disc { width: 38px; height: 38px; }
  .wx-sun-disc::before { inset: -12px; }
  .wx-moon-disc { width: 32px; height: 32px; }
  .wx-sun-times { flex-wrap: wrap; }
  .wx-sun-dur { width: 100%; text-align: center; padding-top: .25rem; }
  .geo-dock-btn { font-size: .76rem; padding: .45rem .5rem; }
}
@media (max-width: 380px) {
  .wx-moon { width: 100%; }
  .wx-moon-illum { white-space: normal; text-align: center; }
}

/* Pausa animaciones CSS de secciones fuera del viewport. La clase .vp-off
   la gestiona un IntersectionObserver en index.html (batería/rendimiento). */
.vp-off,
.vp-off * {
  animation-play-state: paused !important;
}

/* ── Galería "MI PUEBLO": <img> lazy dentro de los expanding panels ──
   Convierte la carga de fondo en imágenes reales diferidas (loading, decoding)
   con el MISMO aspecto visual que el background-image original.
   NOTA: content-visibility:auto se retiró — en algunos WebView no pintaba
   los <img> lazy dentro de los expanding panels mientras el flex anima el
   ancho, dejándolos en blanco. index.html fuerza eager al acercarse la
   sección (IntersectionObserver). */
.pueblo-panel {
  position: relative;
}
.pueblo-panel-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  z-index: 0;
  pointer-events: none;
  backface-visibility: hidden;
  will-change: transform;
}
/* Ken Burns real sobre el <img> (el keyframe original de background-position
   quedó inerte al pasar a <img>). */
.pueblo-panel.active .pueblo-panel-img {
  animation: puebloKenBurnsImg 16s ease-in-out infinite alternate;
}
@keyframes puebloKenBurnsImg {
  0%   { transform: scale(1.03) translateY(-2%); }
  100% { transform: scale(1.12) translateY(1.5%); }
}
.pueblo-panel h3 {
  position: relative;
  z-index: 2;
}

/* ── Imágenes generadas del chat: contenedor sin distorsión ── */
.ai-gen-img {
  aspect-ratio: auto;
  object-fit: contain;
}

/* ── FIX: iconos de la sección Servicios (#services) ─────────────
   El icono es un <i class="fas"> cuyo glifo se dibuja en ::before.
   components.css/index-responsive.css lo convierten en flex y le
   aplican iconFloat con rotateY(5deg): en algunas pantallas el glifo
   queda descentrado/torcido dentro de su caja. Se fuerza una caja
   de icono centrada, sin rotación 3D (solo flotación vertical), con
   ancho de línea neutro para que ninguna regla previa lo descoloque
   ni desborde la tarjeta en el rango móvil 380–720px. */
#services .service-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  line-height: 1;
  margin-bottom: clamp(0.6rem, 2vw, 1.2rem);
  animation: serviceIconFloat 3s ease-in-out infinite;
  filter: drop-shadow(0 5px 15px rgba(255, 69, 0, 0.4));
}

@keyframes serviceIconFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}

/* En los grids de 2 columnas del rango móvil el icono no debe
   comprimirse ni desbordar su tarjeta compacta. */
@media (max-width: 720px) {
  #services .service-icon { font-size: clamp(1.6rem, 6vw, 2.6rem); }
}

/* ── ICONOS INDEX — ajuste uniforme en WebView Android ──────────────
   Emojis y glifos Font Awesome usan métricas de fuente distintas; en el
   WebView Android pueden verse descentrados o con descensor visible.
   Caja fija + línea neutra + centrado vertical = mismo encuadre en
   Chrome móvil y en la app (catalogo de install, panel de permisos,
   dock, nav inferior, botones hero). */
.apk-info-icon {
  width: 20px; height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: .85rem;
  line-height: 1;
}
.ch-perm-icon,
.ios-notif-icon,
.dock-icon,
#mobile-nav-bar a .mnb-icon,
.hero-btn > i.fa,
.hero-proof span i.fa,
.hero-note span i.fa {
  line-height: 1;
}

/* Los emojis del instalador no deben encogerse ni desalinearse en los
   teléfonos más compactos. */
@media (max-width: 380px) {
  .apk-info-icon { width: 18px; height: 18px; font-size: .8rem; }
}

