/* ================================================================
 CONSULADO HABANA v6 — Soft UI · Neumorphism · MarketLabs Style
 DM Sans · Warm Gray · Embossed Cards · Physical Depth
 Fuentes cargadas desde <head> del HTML (no @import)
 ================================================================ */

/* ── Accesibilidad / SEO: visually hidden pero legible para crawlers ── */
.sr-only {
 position: absolute;
 width: 1px;
 height: 1px;
 padding: 0;
 margin: -1px;
 overflow: hidden;
 clip: rect(0, 0, 0, 0);
 white-space: nowrap;
 border: 0;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
 --bg: #e8e8ed;
 --bg-card: #eaeaf0;

 /* Sombra neumórfica — de vuelta a DOS capas (luz + oscuridad), porque
    eso es lo que en realidad define al neumorfismo: sin la capa clara
    de contraste, ya no se ve como una pieza saliendo del mismo fondo,
    se ve como una sombra plana genérica. Lo caro nunca fue "tener dos
    capas" — es el radio de blur. El original tenía 8-14px de blur POR
    capa; acá cada capa tiene 3-5px. Dos capas de blur chico siguen
    costando bastante menos que una sola capa con blur grande, y se ve
    neumórfico de nuevo. Como TODO el sitio (tarjetas, botones, tabs,
    inputs, timeline, selector de fecha) referencia estas 5 variables en
    vez de escribir su propia sombra, este es el único lugar que hace
    falta tocar. */
 --neu-out: 3px 3px 5px rgba(0,0,0,0.14), -2px -2px 4px rgba(255,255,255,0.75);
 --neu-out-sm: 2px 2px 3px rgba(0,0,0,0.13), -1px -1px 3px rgba(255,255,255,0.70);
 --neu-in: inset 2px 2px 3px rgba(0,0,0,0.13), inset -1px -1px 3px rgba(255,255,255,0.60);
 --neu-btn: 2px 2px 4px rgba(0,0,0,0.16), -2px -2px 3px rgba(255,255,255,0.75);
 --neu-btn-press: inset 2px 2px 3px rgba(0,0,0,0.14), inset -1px -1px 2px rgba(255,255,255,0.55);
 /* Sombras de las cards: ~35% más suaves que --neu-out (menos opacidad,
    menos offset y menos blur). Solo afecta a .card; el resto del sitio
    sigue con las variables --neu-* de arriba. */
 --card-out: 2px 2px 4px rgba(0,0,0,0.09), -1px -1px 3px rgba(255,255,255,0.50);
 --card-out-hover: 3px 3px 5px rgba(0,0,0,0.12), -2px -2px 4px rgba(255,255,255,0.55);
 --card-in: inset 2px 2px 3px rgba(0,0,0,0.09), inset -1px -1px 3px rgba(255,255,255,0.42);
 /* Mismo criterio (~35% más suaves) para el panel de estado, la barra de
    pestañas y el botón "Elegir Tarjetas". */
 --soft-out-sm: 2px 2px 3px rgba(0,0,0,0.085), -1px -1px 3px rgba(255,255,255,0.46);
 --soft-btn: 2px 2px 4px rgba(0,0,0,0.10), -2px -2px 3px rgba(255,255,255,0.50);
 --soft-btn-press: inset 2px 2px 3px rgba(0,0,0,0.09), inset -1px -1px 2px rgba(255,255,255,0.36);

 --border: rgba(255,255,255,0.60);
 --border2: rgba(0,0,0,0.06);
 --t1: #1c1c1e;
 --t2: #3a3a3c;
 --t3: #8e8e93;
 --t4: #aeaeb2;

 --green: #30b855;
 --green-bg: rgba(48,184,85,0.12);
 --red: #e03030;
 --red-bg: rgba(224,48,48,0.10);
 --blue: #2060c8;
 /* Azul "Aceptar" del kit UI neumórfico de referencia (mismo tono en
    TODOS los botones Aceptar del sitio: barra de picking, cards,
    selector de ícono, diálogo genérico). Cancelar usa el mismo panel
    claro que --bg-card, sin variable propia. */
 --accept-blue: #578cc4;
 --violet: #5040b8;
 --violet-bg: rgba(80,64,184,0.10);
 --gray-bg: rgba(142,142,147,0.12);
 --gray-chip: #d6d6db;
 --cyan: #0891b2;
 --cyan-bg: rgba(8,145,178,0.10);
 --cyan-chip: #c9ecf3;

 --tab-h: 58px;
 --nav-idle: #66666c; /* texto/ícono de tab inactivo: ~4.6:1 sobre --bg (antes --t4 daba ~1.9:1) */
 --wrap-h: 81px;
 --head-h: 52px;
 --r: 14px;
 --r2: 20px;
 --r3: 32px;
 --f: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
 --f-serif: 'DM Serif Display', Georgia, serif;
}

/* ── Iconos SVG (icons/*.svg) — se pintan con currentColor via mask,
 así heredan el color del texto que los rodea (ej. verde si sube, rojo si baja) ── */
.ic {
 display: inline-block; width: 1em; height: 1em;
 background-color: currentColor; flex-shrink: 0;
 -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
 -webkit-mask-position: center; mask-position: center;
 -webkit-mask-size: contain; mask-size: contain;
 vertical-align: -0.125em;
}
.ic-deficit { -webkit-mask-image: url('icons/deficit.svg'); mask-image: url('icons/deficit.svg'); }
.ic-eye { -webkit-mask-image: url('icons/eye.svg'); mask-image: url('icons/eye.svg'); }
/* Estos 3 van inline (data-URI) en vez de icons/*.svg: son los del diálogo
 chAlert/chConfirm, que aparece en TODA acción (guardar, error, advertencia
 al editar). Antes se pedían por red justo al abrir el diálogo — con
 conexión lenta esa espera se sentía como un ícono que tarda en aparecer,
 aunque el archivo pesara apenas ~470 bytes. Al ir adentro del CSS, ya
 están disponibles apenas carga la hoja de estilos, sin pedido aparte. */
.ic-check-circle { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M22%2011.08V12a10%2010%200%201%201-5.93-9.14%22/%3E%3Cpolyline%20points%3D%2222%204%2012%2014.01%209%2011.01%22/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M22%2011.08V12a10%2010%200%201%201-5.93-9.14%22/%3E%3Cpolyline%20points%3D%2222%204%2012%2014.01%209%2011.01%22/%3E%3C/svg%3E"); }
.ic-alert-triangle { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M10.29%203.86L1.82%2018a2%202%200%200%200%201.71%203h16.94a2%202%200%200%200%201.71-3L13.71%203.86a2%202%200%200%200-3.42%200z%22%3E%3C/path%3E%3Cline%20x1%3D%2212%22%20y1%3D%229%22%20x2%3D%2212%22%20y2%3D%2213%22%3E%3C/line%3E%3Cline%20x1%3D%2212%22%20y1%3D%2217%22%20x2%3D%2212.01%22%20y2%3D%2217%22%3E%3C/line%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M10.29%203.86L1.82%2018a2%202%200%200%200%201.71%203h16.94a2%202%200%200%200%201.71-3L13.71%203.86a2%202%200%200%200-3.42%200z%22%3E%3C/path%3E%3Cline%20x1%3D%2212%22%20y1%3D%229%22%20x2%3D%2212%22%20y2%3D%2213%22%3E%3C/line%3E%3Cline%20x1%3D%2212%22%20y1%3D%2217%22%20x2%3D%2212.01%22%20y2%3D%2217%22%3E%3C/line%3E%3C/svg%3E"); }
.ic-x-circle { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%2210%22%20/%3E%3Cline%20x1%3D%2215%22%20y1%3D%229%22%20x2%3D%229%22%20y2%3D%2215%22%20/%3E%3Cline%20x1%3D%229%22%20y1%3D%229%22%20x2%3D%2215%22%20y2%3D%2215%22%20/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%2210%22%20/%3E%3Cline%20x1%3D%2215%22%20y1%3D%229%22%20x2%3D%229%22%20y2%3D%2215%22%20/%3E%3Cline%20x1%3D%229%22%20y1%3D%229%22%20x2%3D%2215%22%20y2%3D%2215%22%20/%3E%3C/svg%3E"); }


::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 3px; }
::selection { background: rgba(32,96,200,0.14); }

/* Quita el recuadro/flash celeste nativo que Chrome/Safari móvil muestran
 al tocar cualquier elemento (botones, cards, links) — eso es lo que se
 veía "de página barata". El foco por teclado sigue intacto más abajo,
 con *:focus-visible, así que la accesibilidad no se pierde. */
* { -webkit-tap-highlight-color: transparent; }

html { font-size: 90%; }
html, body { height: 100%; }

body {
 font-family: var(--f);
 background: var(--bg);
 color: var(--t1);
 min-height: 100vh;
 overflow-x: hidden;
 padding-top: var(--head-h);
 padding-bottom: calc(var(--wrap-h) + 28px + env(safe-area-inset-bottom, 0px));
 -webkit-font-smoothing: antialiased;
}

@keyframes fadeUp { from { opacity:0; transform:translateY(16px); } to { opacity:1; transform:translateY(0); } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes pulse { 0%,100% { opacity:1; transform:scale(1); } 50% { opacity:0.3; transform:scale(0.80); } }
@keyframes slideDown { from { transform:translateY(-100%); opacity:0; } to { transform:translateY(0); opacity:1; } }
/* TICKER — animación única, GPU-accelerated, sin saltos */
@keyframes ticker-scroll {
 0% { transform: translateX(0); }
 100% { transform: translateX(-50%); }
}
@keyframes overlayIn { from { opacity:0; } to { opacity:1; } }
@keyframes sheetUp { from { transform:translateY(100%); } to { transform:translateY(0); } }
@keyframes cardIn { from { opacity:0; transform:translateY(20px) scale(0.96); } to { opacity:1; transform:translateY(0) scale(1); } }
@keyframes cardOut { from { opacity:1; transform:translateY(0) scale(1); } to { opacity:0; transform:translateY(14px) scale(0.94); } }
@keyframes btnPopIn { from { opacity:0; transform:translateY(10px) scale(0.8); } to { opacity:1; transform:translateY(0) scale(1); } }

/* ═══ HEADER + PANEL DE ESTADO — mismo lenguaje neumórfico claro del sitio ═══
   Todo alineado al mismo margen lateral (16px) que las pestañas y las cards.
   Izquierda: identidad (banderas + título). Derecha: visitas. */
header {
 position: fixed;
 top: 0; left: 0; right: 0;
 height: var(--head-h);
 z-index: 400;
 background: var(--bg);
 box-shadow: 0 1px 0 rgba(255,255,255,0.75), 0 2px 5px rgba(0,0,0,0.045);
 animation: slideDown 0.5s cubic-bezier(0.34,1.56,0.64,1);
}

.header-inner {
 height: 100%;
 display: flex;
 align-items: center;
 justify-content: space-between;
 padding: 0 16px;
 gap: 12px;
 max-width: 900px;
 margin: 0 auto;
}

.header-left { display:flex; align-items:center; gap:11px; flex:1; min-width:0; }

/* Las dos banderas separadas por un divisor fino, sin píldora */
.header-flags {
 display:flex; align-items:center; gap:9px; flex-shrink:0;
}
.flag-es, .flag-cu { display:inline-flex; }
.flag-ic { width:18px; height:18px; display:block; flex-shrink:0; }
.flag-divider { width:1px; height:12px; background:rgba(0,0,0,0.10); display:block; }

.header-text { min-width:0; }
.header-text h1 {
 font-size: 0.95rem; font-weight: 700; color: var(--t1);
 letter-spacing: -0.02em; line-height: 1.2;
 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.header-text p {
 font-size:0.68rem; color:var(--t3); font-weight:500; margin-top:1px;
 white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

.header-right { display:flex; align-items:center; flex-shrink:0; }

/* ═══ BOTÓN HAMBURGUESA — mismo lenguaje neumórfico del sitio, con
   morph a "×" cuando el panel está abierto. Un solo acento (violeta,
   el mismo del splash) para no repetir el truco en todo el sitio. ═══ */
.menu-toggle {
 position: relative; width: 38px; height: 38px;
 border: none; border-radius: 12px;
 background: var(--bg-card); box-shadow: var(--neu-btn);
 display: flex; align-items: center; justify-content: center;
 cursor: pointer;
 transition: box-shadow 0.12s linear, transform 0.12s cubic-bezier(0.2,0,0,1);
}
.menu-toggle:hover { transform: translateY(-1px); }
.menu-toggle:active, .menu-toggle[aria-expanded="true"] {
 box-shadow: var(--neu-btn-press); transform: translateY(0);
}
.menu-toggle-bars { position: relative; width: 16px; height: 12px; }
.menu-toggle-bars span {
 position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px;
 background: var(--t2);
 transition: transform 0.28s cubic-bezier(0.65,0,0.35,1), opacity 0.16s linear, background 0.2s;
}
.menu-toggle-bars span:nth-child(1) { top: 0; }
.menu-toggle-bars span:nth-child(2) { top: 5px; }
.menu-toggle-bars span:nth-child(3) { top: 10px; }
.menu-toggle[aria-expanded="true"] .menu-toggle-bars span { background: var(--violet); }
.menu-toggle[aria-expanded="true"] .menu-toggle-bars span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] .menu-toggle-bars span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.menu-toggle[aria-expanded="true"] .menu-toggle-bars span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* ═══ PANEL LATERAL — entra de derecha a izquierda. Vacío por ahora:
   solo cabecera con título y cierre, listo para lo que se le agregue. ═══ */
.side-panel-overlay {
 position: fixed; inset: 0; z-index: 999;
 background: rgba(20,20,24,0.32);
 opacity: 0; pointer-events: none;
 transition: opacity 0.28s ease;
}
.side-panel-overlay.open { opacity: 1; pointer-events: auto; }

.side-panel {
 position: fixed; top: 0; right: 0; bottom: 0; z-index: 1000;
 width: min(84vw, 340px);
 background: var(--bg);
 display: flex; flex-direction: column;
 transform: translateX(100%);
 transition: transform 0.34s cubic-bezier(0.16,1,0.3,1);
 box-shadow: -10px 0 30px rgba(0,0,0,0.16);
 padding-top: env(safe-area-inset-top, 0px);
 padding-bottom: env(safe-area-inset-bottom, 0px);
}
.side-panel.open { transform: translateX(0); }

.side-panel-head {
 display: flex; align-items: center; justify-content: space-between;
 padding: 18px 18px 16px; flex-shrink: 0;
}
.side-panel-head h2 {
 font-size: 1.05rem; font-weight: 700; color: var(--t1); letter-spacing: -0.01em;
}
.side-panel-close {
 width: 34px; height: 34px; border: none; border-radius: 10px;
 background: var(--bg-card); box-shadow: var(--neu-btn); color: var(--t2);
 display: flex; align-items: center; justify-content: center; cursor: pointer;
 transition: box-shadow 0.12s linear;
}
.side-panel-close svg { width: 16px; height: 16px; }
.side-panel-close:active { box-shadow: var(--neu-btn-press); }

.side-panel-body { flex: 1; padding: 0 18px 18px; overflow-y: auto; }

.side-panel-nav { display: flex; flex-direction: column; gap: 4px; }

.side-panel-divider {
 border: none; height: 1px; margin: 14px 0;
 background: var(--border2);
}

.side-panel-link {
 display: flex; align-items: center; gap: 12px;
 padding: 10px 10px; border-radius: 12px;
 text-decoration: none; color: var(--t1);
 font-size: 0.92rem; font-weight: 600; letter-spacing: -0.01em;
 transition: background 0.12s linear;
 -webkit-tap-highlight-color: transparent;
}
.side-panel-link:hover { background: var(--bg-card); }
.side-panel-link:active { box-shadow: var(--neu-btn-press); border-radius: 12px; }

.side-panel-link-icon {
 display: flex; align-items: center; justify-content: center;
 width: 34px; height: 34px; flex-shrink: 0;
 border-radius: 10px;
 background: var(--bg-card); box-shadow: var(--neu-btn);
 font-family: 'SFMono-Regular', Menlo, Consolas, monospace;
 font-size: 0.78rem; font-weight: 700;
 color: var(--violet);
}

.side-panel-section-title {
 font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em;
 text-transform: uppercase; color: var(--t3);
 padding: 0 10px; margin-bottom: 8px;
}

.side-panel-apk-list { display: flex; flex-direction: column; gap: 8px; }

@media (min-width: 768px) { .side-panel { width: 320px; } }

@media (prefers-reduced-motion: reduce) {
 .side-panel, .side-panel-overlay, .menu-toggle-bars span { transition-duration: 0.01ms !important; }
}

/* STATUS PANEL */
#statusPanel {
 position: sticky; top: var(--head-h); z-index: 300;
 background: var(--bg);
 border-bottom: 1px solid rgba(255,255,255,0.5);
 box-shadow: 0 3px 9px rgba(0,0,0,0.045);
 padding: 12px 16px 14px;
 max-width: 900px; margin: 0 auto; width: 100%;
}
/* Punto "en vivo": solo el punto parpadeante, en la esquina superior derecha
   del recuadro de datos (padding del panel 12/16 + 8px de margen interior). */
.live-dot {
 position:absolute; top:20px; right:27px; z-index:1;
 width:6px; height:6px; background:var(--red); border-radius:50%;
 box-shadow:0 0 5px rgba(224,48,48,0.5); animation:pulse 1.8s ease-in-out infinite;
}

.status-panel-data { display:flex; flex-direction:column; }

/* Las 4 lecturas viven en UN solo pozo hundido, separadas por finas ranuras
   grabadas — en vez de 4 tarjetas elevadas peleando por atención entre sí y
   con el header. Datos de solo lectura = superficie hundida, sin hover.
   El color queda SOLO para lo que es una alerta (el déficit); las divisas
   van en tinta neutra. */
.status-panel-row {
 display:flex; background:var(--bg-card);
 border-radius:16px; box-shadow:var(--card-in); overflow:hidden;
}
.status-item {
 flex:1 1 0; min-width:0; min-height:52px; padding:9px 4px;
 display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
}
/* Separador: hilo fino que se desvanece arriba y abajo (no llega a los bordes) */
.status-item, #statusPanel .status-item-skeleton { position:relative; }
.status-item + .status-item::before,
#statusPanel .status-item-skeleton + .status-item-skeleton::before {
 content:''; position:absolute; left:0; top:20%; bottom:20%; width:1px;
 background:linear-gradient(to bottom, transparent, rgba(0,0,0,0.11), transparent);
}
.status-item .label {
 display:flex; align-items:center; gap:4px;
 font-size:0.62rem; font-weight:600; color:var(--t3); white-space:nowrap; letter-spacing:0.03em;
}
.status-item .value {
 font-size:0.98rem; font-weight:500; line-height:1.1; color:var(--t2);
 white-space:normal; overflow-wrap:break-word; width:100%; text-align:center;
 letter-spacing:-0.02em; font-variant-numeric:tabular-nums;
}
.status-item.deficit .value { color:var(--red); }
.status-panel-container.focus-mode { display:none; }

/* Skeleton con el mismo alto/radio que un .status-item real (sin saltos al cargar) */
#statusPanel .status-skeleton-row {
 gap:0; background:var(--bg-card); border-radius:16px; box-shadow:var(--card-in); overflow:hidden;
}
#statusPanel .status-item-skeleton {
 background:none; box-shadow:none; border-radius:0; min-height:52px; padding:9px 4px; justify-content:center; gap:6px;
}

/* Pantallas muy angostas (≤360px): que el título no se corte y que
   "1.850 MW" quepa en su recuadro */
@media (max-width:360px) {
 .header-inner { padding:0 12px; gap:8px; }
 .header-left { gap:8px; }
 .header-flags { gap:7px; }
 .header-text h1 { font-size:0.88rem; }
 .status-item { padding:9px 4px; }
 .status-item .value { font-size:0.9rem; letter-spacing:-0.03em; }
}

#statusPanel, .news-ticker-container {
 transition: opacity .35s ease, transform .35s ease, max-height .4s cubic-bezier(0.4,0,0.2,1);
 max-height: 300px; overflow:hidden;
}
body.chat-active #statusPanel, body.chat-active .news-ticker-container {
 opacity:0; max-height:0; transform:translateY(-8px); pointer-events:none;
}
body.tabs-ready #statusPanel, body.tabs-ready .news-ticker-container {
 transition: opacity .22s ease, transform .22s ease, max-height .25s ease;
}
body.no-panel-anim #statusPanel, body.no-panel-anim .news-ticker-container {
 transition: none !important;
}
body.focus-mode .news-ticker-container { display:none; }

/* TICKER — antes era una franja roja sólida, plana, que no pegaba con
   el resto del neumorfismo del sitio. Ahora es una barra sticky en el
   mismo tono de fondo que el status panel de arriba (con el que
   comparte fila), y "Reportes" pasa a ser un chip flotante — el mismo
   truco: fondo del panel + sombra suave + texto
   de color, en vez de un bloque de color sólido. */
.news-ticker-container {
 width:100%; max-width:900px; margin:0 auto;
 background:var(--bg); color:var(--t1);
 border-bottom:1px solid rgba(255,255,255,0.5);
 box-shadow:0 3px 9px rgba(0,0,0,0.045);
 overflow:hidden; padding:9px 0;
 display:flex; align-items:center; position:sticky; top:var(--head-h); z-index:200;
}
.news-ticker-fixed-label {
 display:flex; align-items:center; gap:5px;
 font-size:0.62rem; font-weight:800; letter-spacing:0.10em; text-transform:uppercase;
 color:var(--red); background:var(--bg); box-shadow:var(--neu-out-sm);
 padding:4px 10px; border-radius:20px;
 margin-left:10px; flex-shrink:0; line-height:1.5;
}
.news-ticker-dot { width:5px; height:5px; background:var(--red); border-radius:50%; box-shadow:0 0 6px var(--red); animation:pulse 1.8s ease-in-out infinite; flex-shrink:0; }
.news-ticker-wrap { overflow:hidden; flex-grow:1; }
.news-ticker-content {
 white-space: nowrap;
 font-size: 0.82rem;
 font-weight: 600;
 color: var(--t2);
 display: inline-block;
 /* GPU layer — elimina jank y saltos */
 will-change: transform;
 transform: translateZ(0);
 backface-visibility: hidden;
 animation: ticker-scroll var(--ticker-dur, 30s) linear infinite;
}
.news-item { padding:0 16px; display:inline-block; }
.news-item small { font-size:0.67rem; color:var(--t3); margin-left:4px; }
.news-item a { color:var(--blue); text-decoration:underline; font-weight:700; }

/* ── Status panel tweaks ── */

/* TAB VIEWS */.tab-view { display:none; }
.tab-view.active { display:block; animation:fadeUp .32s cubic-bezier(0.34,1.2,0.64,1); }
.tab-view.active.no-anim { animation:none; }

/* TAB 1 - CALENDARIO */
#view-calendario { padding:20px 16px 0; max-width:900px; margin:0 auto; }

.container { display:grid; grid-template-columns:repeat(2,1fr); gap:14px; margin-top:16px; }
@media (min-width:480px) { .container { grid-template-columns:repeat(3,1fr); } }
@media (min-width:768px) { .container { grid-template-columns:repeat(4,1fr); gap:18px; } }

/* ── AÑADIR TARJETAS: CTA vacío (centrado) + botón superior (con tarjetas) ── */
.add-cards-wrap {
 display:flex; flex-direction:column; align-items:center; text-align:center;
 gap:10px; padding:22px 20px; transition:padding .3s ease;
}
.add-cards-wrap.centered { padding:54px 20px 60px; }
.add-cards-hint { display:none; margin:0; font-size:0.85rem; color:var(--t3); max-width:260px; }
.add-cards-wrap.centered .add-cards-hint { display:block; }
.btn-add-cards {
 display:inline-flex; align-items:center; gap:8px; border:none; cursor:pointer;
 padding:13px 24px; border-radius:999px; font:inherit; font-weight:700; font-size:0.92rem;
 background:var(--bg-card); color:var(--cyan);
 box-shadow:var(--soft-btn);
 transition:transform .2s,box-shadow .2s;
}
.btn-add-cards:hover:not(:disabled) { transform:translateY(-2px); }
.btn-add-cards:active:not(:disabled) { box-shadow:var(--soft-btn-press); transform:scale(.97); }
/* Identidad nueva (< 30 min): mismo gris silencioso que el resto de
   acciones gateadas (ver .propuesta-btn.is-gated) — sin explicar nada. */
.btn-add-cards.is-gated, .btn-add-cards:disabled { opacity:0.4; filter:grayscale(0.9); cursor:not-allowed; }
.add-cards-wrap.centered .btn-add-cards { padding:15px 28px; font-size:1rem; }

/* ── PESTAÑA ELIMINACIÓN: botón "Eliminar Card" (mismo patrón de "Crear
   Card": revela bajo demanda en vez de mostrar todo todo el tiempo) pero
   con la paleta roja de una acción destructiva — fondo rojo claro, texto
   rojo oscuro — igual que ya se usaba antes en el botón de cada tarjeta.
   Mientras la lista está abierta el botón funciona como "Cancelar". ── */
#btnEliminarCard {
 background:linear-gradient(var(--red-bg), var(--red-bg)), var(--bg-card);
 color:var(--red);
}
.eliminacion-hint {
 margin:0 auto; padding:16px 20px 4px; text-align:center;
 font-size:0.82rem; color:var(--t3); max-width:340px;
}
.eliminacion-hint-limite { color:var(--red); font-weight:600; }
.eliminacion-list { display:flex; flex-direction:column; gap:10px; padding:16px 4px 24px; }

/* "Mis Card" con tarjetas elegidas: el botón deja de ser un bloque grande y
   pasa a una fila compacta: solo "+ Elegir", alineado a la derecha.
   Sin ninguna tarjeta elegida (.centered) se mantiene el CTA grande y
   centrado de siempre. Solo aplica a #addCardsWrap: "Crear Card" (pestaña
   Nuevas) comparte .add-cards-wrap y queda intacto. */
/* Sin transición de padding: al cambiar de compacto a centrado (o al revés) el
   bloque debe aparecer ya en su sitio, no "crecer" — ese crecimiento era otro
   salto visible al cargar. (Al salir del modo elegir el bloque reaparece desde
   display:none, así que esa transición nunca se veía de todos modos.) */
#addCardsWrap { transition:none; }
#addCardsWrap:not(.centered) {
 flex-direction:row; justify-content:flex-end; align-items:center;
 padding:2px 0 0;
}
#addCardsWrap:not(.centered) .btn-add-cards { padding:8px 16px; font-size:0.8rem; gap:6px; }
#addCardsWrap:not(.centered) .btn-add-cards svg { width:14px; height:14px; }
#addCardsWrap:not(.centered) .btn-label-more { display:none; }

/* Título que aparece encima de las tarjetas mientras se están eligiendo */
.card-picker-title {
 display:none; margin:0 0 14px; padding:0 16px;
 font-family:var(--f); font-size:0.95rem; font-weight:700;
 color:var(--t1); text-align:center;
}
.card-picker-title.show { display:block; }

/* Barra de 3 "pestañas" (Mis Card / Nuevas / Eliminación), como un
   segmented control neumórfico:
   - El panel es una ranura cóncava (--neu-in), no una tarjeta elevada.
   - Cada botón vive suelto dentro de esa ranura (gap, sin bordes ni
     líneas divisorias entre ellos).
   - El botón .active "sale" de la ranura como una píldora con sombra
     suave (--soft-out-sm) y un tinte de color de fondo suave según la
     categoría — el resto queda plano y en gris, sin competir. */
.view-filter-bar {
 display:flex; gap:6px;
 background:var(--bg-card);
 border-radius:var(--r2);
 box-shadow:var(--card-in);
 padding:6px;
 margin-bottom:18px;
}
.view-filter-btn {
 flex:1; min-width:0; display:flex; align-items:center; justify-content:center;
 padding:13px 4px; border:none; border-radius:14px; background:transparent;
 font-family:var(--f); font-size:0.72rem; font-weight:700; color:var(--t3);
 line-height:1.15; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
 cursor:pointer;
 transition:background .2s ease, color .2s ease, box-shadow .2s ease, transform .15s ease;
}
.view-filter-btn:active { transform:scale(.95); }
.view-filter-btn.active { box-shadow:var(--soft-out-sm); }
.view-filter-btn.active.view-filter-mis { color:#40b3e0; background:rgba(64,179,224,0.12); }
.view-filter-btn.active.view-filter-nuevas { color:var(--t1); background:var(--gray-bg); }
.view-filter-btn.active.view-filter-eliminacion { color:var(--red); background:var(--red-bg); }

/* ── FORMULARIO "CREAR CARD" (modal, pestaña Nuevas) ──────────────────
   .icon-picker-trigger se reutiliza tal cual (ya es genérico, no depende
   de estar dentro de .card). Título y fecha SÍ necesitan clases propias
   porque .editable-title/.fecha-valor-btn del modo edición están
   pensadas para vivir dentro de .card. */
.crear-card-form { display:flex; flex-direction:column; align-items:center; gap:12px; margin:4px 0 8px; }
.crear-card-titulo-input {
 width:100%; background:var(--bg-card); border:1px solid rgba(255,255,255,0.55);
 box-shadow:var(--neu-in); border-radius:var(--r); color:var(--t1);
 /* Mismo tratamiento que .card h3 (el título ya renderizado de una card
    real): negrita, mayúsculas, letras espaciadas. Solo el tamaño se deja
    un poco más grande que el 0.72rem de la card (0.85rem) para que se
    pueda escribir cómodo en el teléfono — la "voz" tipográfica es la
    misma, nada más cambia la escala. */
 font-family:var(--f); font-size:0.85rem; font-weight:800; text-transform:uppercase;
 letter-spacing:0.06em; padding:12px 16px; text-align:center;
}
.crear-card-titulo-input::placeholder { font-weight:600; text-transform:none; letter-spacing:normal; color:var(--t3); }
.crear-card-titulo-input:focus { outline:none; box-shadow:inset 2px 2px 5px rgba(0,0,0,0.13),inset -2px -2px 4px rgba(255,255,255,0.70),0 0 0 3px rgba(32,96,200,0.12); }
.crear-card-fecha-btn {
 width:100%; padding:12px 16px; border:none; border-radius:var(--r);
 background:var(--bg-card); box-shadow:var(--neu-btn); color:var(--t1);
 /* Mismo tratamiento que .fecha-display (la fecha ya renderizada de una
    card real): negrita, letras un poco más juntas, sin mayúsculas. */
 font-family:var(--f); font-weight:800; font-size:0.95rem; letter-spacing:-0.01em; cursor:pointer;
 transition:transform .15s, box-shadow .15s;
}
.crear-card-fecha-btn.vacio { color:var(--t3); font-weight:600; letter-spacing:normal; }
.crear-card-fecha-btn:hover { transform:translateY(-2px); }
.crear-card-fecha-btn:active { box-shadow:var(--neu-btn-press); transform:scale(.98); }

/* Modo selección: se ven todas las cards, en gris salvo las elegidas */
.container.picking .card {
 cursor:pointer;
 filter:grayscale(1); opacity:.55;
 transition:filter .25s ease,opacity .25s ease,box-shadow .25s ease;
}
.container.picking .card:hover { transform:none; }
.container.picking .card.is-picked {
 filter:none; opacity:1;
 box-shadow:0 0 0 1.5px #40b3e0, var(--card-out);
}
.container.picking .card.is-picked::after {
 content:''; position:absolute; top:8px; right:8px; width:22px; height:22px; z-index:2;
 border-radius:50%; background-color:#40b3e0;
 background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
 background-repeat:no-repeat; background-position:center; background-size:58%;
 box-shadow:0 2px 5px rgba(0,0,0,.3),0 0 0 2px var(--bg-card);
}
.card.filtered-hidden { display:none; }

/* Barra fija Aceptar/Cancelar mientras se eligen tarjetas */
.card-picker-bar {
 position:fixed; left:50%; right:auto;
 bottom:calc(var(--wrap-h) + 14px + env(safe-area-inset-bottom, 0px)); z-index:600;
 display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px;
 padding:12px 16px; background:var(--bg-card); border-radius:var(--r2);
 max-width:320px; margin:0 auto;
 box-shadow:var(--neu-out);
 transform:translate(-50%,120%); opacity:0; pointer-events:none;
 transition:transform .3s cubic-bezier(0.34,1.2,0.64,1),opacity .25s ease;
}
.card-picker-bar.show { transform:translate(-50%,0); opacity:1; pointer-events:auto; }
.card-picker-count { font-weight:700; color:var(--t1); font-size:0.88rem; }
.card-picker-actions { display:flex; gap:10px; }
/* Aceptar hereda el azul unificado de .btn-primary (--accept-blue).
   Cancelar se deja con el estilo blanco original de .btn-secondary. */

/* CARDS NEUMORFICAS */
/* .card es el marco exterior: fondo, borde, radio y sombra neumórfica.
 A propósito SIN overflow:hidden ni padding/layout propios — eso vive en
 .card-inner (regla siguiente) — porque el badge de estado (.card-label,
 más abajo) necesita flotar centrado justo ENCIMA de esta línea de borde
 superior, mitad afuera/mitad adentro, y un .card con overflow:hidden se
 lo recortaría a la mitad. */
.card {
 background:var(--bg-card); border:1px solid rgba(255,255,255,0.60);
 border-radius:var(--r2); min-width:0;
 text-align:center; cursor:pointer; position:relative;
 min-height:130px; box-shadow:var(--card-out);
 transition:transform .28s cubic-bezier(0.34,1.2,0.64,1);
 animation:cardIn .4s cubic-bezier(0.34,1.2,0.64,1) both;
}
/* refreshCardDisplay (cambio pendiente) y actualizarCardPropuestaNueva
 (Creación de card) reemplazan una card por otra recién montada cada vez
 que se actualiza algo — salir de edición, un voto, lo que sea — pero
 ninguna de esas veces es una card entrando de cero al grid: es SIEMPRE
 la misma card de siempre. Sin esto, heredaría cardIn de la regla de
 arriba y "entraría" de nuevo en cada actualización. Se le pone a la card
 que se actualiza en su lugar, nunca a las hermanas, así ninguna otra
 vuelve a jugar su animación de entrada por una acción ajena. */
.card.sin-entrada { animation:none; }
/* Propuesta resuelta (aprobada o rechazada): se despide con un fundido de
 salida — lo opuesto de cardIn — en vez de desaparecer de un tirón. */
.card.voto-resuelto-saliendo { animation:cardOut .32s cubic-bezier(0.4,0,0.6,1) both; pointer-events:none; }

/* "Cambio pendiente" (edición de una card ya existente) resuelto: a
 diferencia de "Creación de card", esta card no se va a ningún lado —
 sigue en el mismo lugar del grid, solo que ya sin la UI de votación. En
 vez de un modal, un anillo de color aparece y se apaga sobre la card
 misma (aprobada = cian, rechazada = el mismo rojo de siempre) — dura
 menos de un segundo y no dice una palabra, pero se nota que algo pasó.
 Necesita más especificidad que .sin-entrada (que también trae esta
 misma card) para no perder el forcejeo por la propiedad animation. */
@keyframes cardResuelto {
 0%   { box-shadow:var(--card-out); }
 30%  { box-shadow:0 0 0 3px var(--card-resuelto-color), var(--card-out); }
 100% { box-shadow:var(--card-out); }
}
.card.sin-entrada.resuelto-aprobado { animation:cardResuelto .9s ease; --card-resuelto-color:rgba(8,145,178,0.32); }
.card.sin-entrada.resuelto-rechazado { animation:cardResuelto .9s ease; --card-resuelto-color:rgba(224,48,48,0.26); }

/* Todo lo que antes vivía directo en .card (ícono, título, contenido,
 botón Editar, panel de tiempo deslizable) vive acá adentro. Este sí
 recorta overflow —esconde el panel de tiempo cuando está deslizado
 fuera, ver .card-time-panel— y hereda el radio de .card para que ese
 recorte no deje esquinas cuadradas asomando en las inferiores. */
.card-inner {
 position:relative; overflow:hidden; border-radius:inherit; height:100%;
 padding:20px 14px;
 display:flex; flex-direction:column; align-items:center; gap:8px;
 /* Con muchos trámites cargados, esto es lo que de verdad reemplaza a la
    virtualización: el navegador deja de calcular layout/estilo/pintado
    para cualquier tarjeta fuera de pantalla (texto, ícono, panel de
    hora — todo), sin desmontar el nodo del DOM. Como no se desmonta,
    nada de los listeners/estado por tarjeta (edición, votos, panel de
    hora) se rompe cuando vuelve a entrar en pantalla. contain-intrinsic-size
    le da una altura estimada mientras está "saltada" para que el scroll
    no salte; "auto" hace que el navegador recuerde el alto real después
    del primer render y deje de depender de la estimación. No se puso en
    .card (el padre) porque .card a propósito NO recorta overflow —el
    badge de estado necesita asomar mitad afuera de su borde superior— y
    el contenimiento de pintado que implica content-visibility sí
    recortaría eso. Acá adentro no cambia nada porque ya recortábamos con
    overflow:hidden de todas formas. */
 content-visibility: auto;
 contain-intrinsic-size: auto 200px;
}
.card::before {
 content:''; position:absolute; top:0; left:18px; right:18px; height:2px;
 background:rgba(255,255,255,0.90); border-radius:0 0 2px 2px;
}
.card:hover { transform:translateY(-5px); box-shadow:var(--card-out-hover); }
.card:active { transform:translateY(-1px); box-shadow:var(--card-in); }
/* Se queda "hundida" (mismo look que el :active de arriba) mientras esta
 card sea la tocada — reusa show-time-panel, que ya se apaga sola al
 tocar otra card o a los TIME_PANEL_AUTOHIDE_MS (script.js), así que no
 hace falta ningún temporizador nuevo para esto. */
.card.show-time-panel { transform:translateY(-1px); box-shadow:var(--card-in); }

/* El animation-delay de entrada de cada card YA NO se fija acá por
   posición fija (nth-child): se calcula en script.js (staggerDelayFor,
   usado desde applyCardFilter/enterPickingMode) según el orden de las
   cards que están VISIBLES en cada momento, no su posición entre todas.
   Así el escalonado siempre corresponde a lo que se ve en pantalla, elijas
   las cards que elijas desde "Elegir Tarjetas". */

/* Sin filter:drop-shadow acá (ni en .card-ic / .card-flag-ic más abajo):
   es un filtro por píxel sobre el canal alfa, más caro que un box-shadow
   normal, y se multiplica por cuántas tarjetas haya en pantalla. La
   sombra era sutil (12% de opacidad); quitarla no se nota, pero deja de
   pagarse por cada emoji/ícono/bandera de cada tarjeta. */
.card span.emoji { font-size:2.2rem; line-height:1; display:block; transition:transform .3s cubic-bezier(0.34,1.56,0.64,1); }
.card:hover span.emoji { transform:scale(1.18) translateY(-3px); }

/* Ícono SVG de tarjeta (reemplaza al emoji cuando la tarjeta usa uno de icons/*.svg) */
.card-icon-wrap { display:block; transition:transform .3s cubic-bezier(0.34,1.56,0.64,1); }
.card:hover .card-icon-wrap { transform:scale(1.18) translateY(-3px); }
.card-ic { width:36px; height:36px; display:inline-block; }
.card-flag-ic { width:38px; height:38px; border-radius:8px; }
.card h3 { font-size:0.72rem; font-weight:800; color:var(--t1); text-transform:uppercase; letter-spacing:0.06em; line-height:1.3; }
/* .card-content pasa a ser flex column que SE ESTIRA (flex:1 1 auto) para
 ocupar todo el alto sobrante de .card-inner. En una card normal esto no
 se nota (el contenido sigue arriba, el sobrante queda invisible debajo);
 es lo que le da a .propuesta-votacion, adentro, una altura real de la
 cual tirar para clavar conteo+botones abajo del todo — ver .propuesta-
 votacion y .propuesta-resultado más abajo, y el porqué completo en el
 comentario de .propuesta-votacion. */
.card-content { display:flex; flex-direction:column; flex:1 1 auto; width:100%; }
.card-content p { font-size:0.82rem; color:var(--t2); line-height:1.6; white-space:pre-wrap; text-align:center; overflow-wrap:anywhere; word-break:break-word; }
.card-content p.fecha-display { font-size:0.95rem; font-weight:800; color:var(--t1); letter-spacing:-0.01em; }

.card-time-panel {
 position:absolute; bottom:0; left:0; right:0;
 /* Sin backdrop-filter: a 96% de opacidad ya casi no se veía nada del
    fondo detrás, así que el blur pagaba un costo real (y este panel
    existe una vez POR TARJETA, no una vez por overlay como los modales
    de abajo) por un efecto casi invisible. Se sube a 98% para tapar del
    todo lo que el blur disimulaba. */
 background:rgba(232,232,237,0.98);
 padding:8px; font-size:0.7rem; font-weight:600; color:var(--t3);
 transform:translateY(100%); transition:transform .28s cubic-bezier(0.34,1.2,0.64,1);
 border-top:1px solid rgba(255,255,255,0.5); border-radius:0 0 var(--r2) var(--r2);
 display:flex; flex-direction:column; align-items:center; gap:3px;
}
.card.show-time-panel .card-time-panel { transform:translateY(0); }
.card-time-text { line-height:1.3; }

/* "Ver Detalles" — píldora neumórfica (mismo patrón que .tl-calc-btn),
 dentro del panel deslizable. La sombra elevada invita a tocarla. */
.card-details-btn {
 display:flex; align-items:center; justify-content:center; gap:6px;
 background:var(--bg-card); border:none; box-shadow:var(--neu-btn);
 padding:8px 16px; margin-top:2px; border-radius:20px;
 color:var(--blue); font-family:var(--f); font-size:0.72rem; font-weight:700;
 letter-spacing:0.02em; cursor:pointer;
}
.card-details-btn .ic { width:13px; height:13px; }
.card-details-btn:active { box-shadow:var(--neu-btn-press); }

/* Píldora de estado ("!RECIENTE!" / "EN VOTACIÓN"): mismo patrón que
 .bloque-titulo de la votación (ver más abajo) — flota centrada justo
 ENCIMA de la línea del borde superior de la card (position:absolute +
 translate(-50%,-50%), mitad afuera/mitad adentro), como la leyenda de
 un <fieldset>. Vive directo dentro de .card (no de .card-inner) para no
 quedar recortada por el overflow:hidden de esta última. */
.card-label {
 position:absolute; top:0; left:50%; transform:translate(-50%, -50%);
 font-size:0.6rem; font-weight:800; padding:3px 12px; border-radius:20px;
 letter-spacing:.08em; text-transform:uppercase; white-space:nowrap;
 z-index:5; display:none;
}
.card-recent .card-label { display:block; color:var(--red); background:var(--bg-card); }

/* "EN VOTACIÓN" — mismo badge, mismo tamaño y misma posición que
 "Reciente" (ambas comparten .card-label de arriba); solo cambia a cian.
 Ya no necesita achicarse (antes vivía apretada en la esquina), ahora
 centrada tiene todo el ancho de la card para respirar. */
.card-voting .card-label-voting { display:block; color:var(--cyan); background:var(--bg-card); }

/* Basurita roja parpadeante — a diferencia de .card-label (centrada,
   reemplaza el contenido) esta es solo un aviso discreto en la esquina:
   la card se sigue viendo normal, nada más avisa que está en votación de
   eliminación. Vive en createCardHTML (script.js) para cualquier card que
   tenga una fila pendiente en propuestasEliminacionPendientes — aparece
   donde sea que esa card se muestre (Mis Card, elegir tarjetas, etc). */
.card-delete-badge {
 position:absolute; top:8px; right:8px; z-index:6;
 width:22px; height:22px; border-radius:50%;
 background:var(--bg-card); box-shadow:var(--neu-btn);
 display:flex; align-items:center; justify-content:center;
 color:var(--red);
 animation:pulse 1.3s ease-in-out infinite;
}
.card-delete-badge svg { width:12px; height:12px; }

/* Botón "Editar" — vive arriba a la izquierda, lejos del centro donde
 flota .card-label, y solo se ve cuando la card ya está "abierta" (mismo
 estado que el panel de tiempo de abajo). Un segundo toque, ahora sí
 sobre el ícono, entra en modo edición SOLO en esa card — ver
 enterCardEditMode en script.js. */
.card-edit-btn {
 position:absolute; top:8px; left:8px; z-index:6;
 width:30px; height:30px; padding:0; border-radius:50%;
 display:flex; align-items:center; justify-content:center;
 background:var(--bg-card); color:#000; border:1px solid rgba(255,255,255,0.35);
 box-shadow:var(--neu-btn); cursor:pointer;
 opacity:0; transform:scale(0.7); pointer-events:none;
 transition:opacity .2s ease, transform .2s cubic-bezier(0.34,1.56,0.64,1), filter .15s, box-shadow .15s ease;
}
.card.show-time-panel .card-edit-btn { opacity:1; transform:scale(1); pointer-events:auto; }
.card-edit-btn:hover:not(.is-gated) { filter:brightness(1.12); }
.card-edit-btn:active:not(.is-gated) { transform:scale(0.85); box-shadow:var(--neu-btn-press); }
.card.editing-active .card-edit-btn { display:none; }

/* Identidad nueva (< 30 min, ver IDENTIDAD_NUEVA_GATE_MS en script.js):
 el botón se ve pero gris, con cursor de "no permitido" y disabled real
 — a propósito no explica nada al tocarlo (decisión de producto, ver
 script.js). */
.card-edit-btn.is-gated { cursor:not-allowed; }
.card.show-time-panel .card-edit-btn.is-gated { opacity:0.4; filter:grayscale(0.9); }

/* Aceptar / Cancelar — reemplazan, dentro de la misma card, al botón único
 "Guardar Cambios" que antes vivía fuera de todas las cards.
 min-width:0 es la parte importante: sin eso, un botón flex NUNCA se
 encoge más allá del ancho de su texto, así que con letra grande/zoom
 raro el texto "empuja" el botón fuera de la card en vez de achicarse. */
.card-edit-actions { display:flex; gap:6px; width:100%; max-width:100%; margin-top:2px; }
.card-edit-actions button {
 flex:1; min-width:0; display:flex; align-items:center; justify-content:center; gap:4px;
 padding:9px 4px; border:none; border-radius:50px; cursor:pointer;
 font-family:var(--f); font-size:0.72rem; font-weight:700; color:#fff;
 line-height:1.15; text-align:center; white-space:normal;
 transition:transform .15s cubic-bezier(0.34,1.56,0.64,1), filter .12s ease;
 animation:btnPopIn .4s cubic-bezier(0.34,1.56,0.64,1) both;
}
.card-edit-actions button svg { flex-shrink:0; }
.card-edit-actions button:hover { transform:translateY(-2px); filter:brightness(1.06); }
.card-edit-actions button:active { transform:scale(0.92) translateY(0); filter:brightness(0.94); }
.card-accept-btn {
  background:var(--accept-blue); color:#fff;
  box-shadow:2px 2px 6px rgba(87,140,196,0.38),-1px -1px 4px rgba(255,255,255,0.70);
  animation-delay:.05s;
}
.card-accept-btn:hover { box-shadow:3px 3px 9px rgba(87,140,196,0.46),-2px -2px 5px rgba(255,255,255,0.75); }
.card-edit-actions .card-cancel-btn {
  background:var(--bg-card); color:#000;
  box-shadow:var(--neu-btn);
  animation-delay:.14s;
}
.card-cancel-btn:hover { box-shadow:3px 3px 8px rgba(0,0,0,0.16),-2px -2px 6px rgba(255,255,255,0.90); }

/* Elige un ícono: mismo esquema Aceptar=azul unificado / Cancelar=blanco+negro */
#iconPickerAcceptBtn.btn-success {
  background:var(--accept-blue);
  box-shadow:2px 2px 6px rgba(87,140,196,0.38),-1px -1px 4px rgba(255,255,255,0.70);
}
#iconPickerAcceptBtn.btn-success:hover {
  box-shadow:3px 3px 9px rgba(87,140,196,0.46),-2px -2px 5px rgba(255,255,255,0.75);
}
#iconPickerCancelBtn.btn-secondary { color:#000; }

/* ── Votación de cambios (título, ícono y/o fecha) ─────────────────────
 Sustituye el <p class="fecha-display"> normal cuando la card tiene una
 propuesta pendiente (propuestasPendientes en script.js). Un solo bloque
 gris "Actual": ícono + título + fecha tal como están hoy, los tres
 siempre, sin importar cuál de ellos es el que está en votación — da el
 "antes" completo sin subir la vista al <h3>/card-icon-wrap de arriba de
 esta misma card.
 Dentro de ese bloque, SOLO el campo que tiene un cambio propuesto
 (ícono, título y/o fecha) alterna cada 2s entre su valor de hoy y una
 píldora cian con el valor nuevo (.campo-crossfade, más abajo) — el
 resto de la card se queda fijo en gris, así el cambio real salta a la
 vista en vez de perderse en un crossfade de card entera.
 La píldora-título ("Actual" / "Cambio Propuesto") NO va metida dentro
 del bloque: flota centrada justo ENCIMA de la línea de su borde
 superior (position:absolute + translateY(-50%), mitad afuera/mitad
 adentro), como la leyenda de un <fieldset> — así se lee como el título
 del bloque/campo, no como el primer renglón de su contenido. */
/* Dos cards en votación una al lado de la otra ya miden lo mismo por
 fuera (el .container es CSS grid, y sus filas estiran todas las cards a
 la altura de la más alta por defecto) — pero por dentro cada una seguía
 apilando su contenido desde arriba sin más, así que si a una le tocaba
 un título de una sola línea y a la de al lado un título de dos, el
 sobrante de alto de la más baja quedaba como aire suelto AL FINAL, y los
 chips de Aprobar/Rechazar terminaban a distinta altura entre una card y
 otra (desfasados). Acá growth (flex:1, ver .card-content arriba) +
 justify-content:space-between con solo DOS hijos —el bloque "Actual"/
 "Nueva Tarjeta" arriba y .propuesta-resultado abajo (los chips, ver más
 abajo)— hace que ese sobrante de alto quede siempre EN EL MEDIO, entre
 el bloque y el resultado. Así el resultado queda pegado al borde
 inferior de la card en las dos, sin importar cuántas líneas ocupe el
 título de cada una. */
.propuesta-votacion { display:flex; flex-direction:column; align-items:center; width:100%; flex:1 1 auto; justify-content:space-between; }
/* Wrapper de una sola pieza (los dos chips de voto) — se mantiene como
 nivel propio, en vez de que .propuesta-votos-actions cuelgue directo de
 .propuesta-votacion, para que el hueco flexible de arriba (ver comentario
 previo) tenga siempre un único hijo de abajo contra el que pegarse. */
.propuesta-resultado { display:flex; flex-direction:column; align-items:center; width:100%; }

.propuesta-bloque {
 position:relative;
 display:flex; flex-direction:column; align-items:center; width:100%;
 border-radius:16px; padding:18px 12px 14px;
 margin-top:14px;
}

.bloque-actual { background:var(--gray-bg); }

/* Campo (ícono/título/fecha) con cambio propuesto: mismo patrón de grid
 que antes se usaba para la card completa — los dos estados ocupan la
 misma celda (el alto lo define el más alto de los dos, nadie se
 recorta) y la animación de opacity los cruza solos cada 2 segundos —
 sin JS, así que el navegador la pausa sola si la card queda fuera de
 pantalla. */
.campo-crossfade { position:relative; display:grid; justify-items:center; align-items:center; }
.campo-crossfade > * { grid-column:1; grid-row:1; }

@media (prefers-reduced-motion: no-preference) {
 .campo-crossfade .campo-actual { animation:propuestaCrossfade 4s ease-in-out infinite; }
 /* Mismo keyframe que el valor de hoy, pero arrancando ya a mitad de
 vuelta (delay negativo) — así queda siempre en el punto opuesto:
 cuando uno se ve, el otro está en 0. Evita escribir el keyframe dos
 veces. */
 .campo-crossfade .campo-nuevo { animation:propuestaCrossfade 4s ease-in-out infinite; animation-delay:-2s; }
}
@keyframes propuestaCrossfade {
 0%, 40% { opacity:1; }
 50%, 90% { opacity:0; }
 100% { opacity:1; }
}
/* Menos animación: se ven las dos fijas, una debajo de la otra, en vez
 de cruzarse solas. */
@media (prefers-reduced-motion: reduce) {
 .campo-crossfade { display:flex; flex-direction:column; gap:6px; }
}

/* Píldora cian del valor nuevo: crece alrededor del campo que cambió
 (no de la card entera). Sin etiqueta propia — el texto "Cambio
 Propuesto" vive en .bloque-titulo de arriba, no acá (ver más abajo). */
.campo-nuevo {
 display:flex; flex-direction:column; align-items:center;
 background:var(--cyan-chip); border-radius:12px; padding:6px 12px;
}

.bloque-titulo {
 position:absolute; top:0; left:50%; transform:translate(-50%, -50%);
 display:inline-block; padding:3px 12px;
 border-radius:20px; font-size:0.6rem; font-weight:800;
 text-transform:uppercase; letter-spacing:.08em; white-space:nowrap;
 box-shadow:var(--neu-out-sm);
}
.bloque-actual .bloque-titulo { background:var(--gray-chip); color:var(--t2); }

/* Con un campo en votación, "Actual" y "Cambio Propuesto" se superponen
 en ESE MISMO lugar (las dos heredan la misma position:absolute de
 .bloque-titulo, con .propuesta-bloque como ancestro posicionado, así
 que caen exactas una sobre otra) y se cruzan con el mismo keyframe y
 el mismo timing que el campo cian de abajo — nunca una etiqueta suelta
 flotando junto al campo. */
.bloque-titulo.titulo-nuevo { background:var(--cyan-chip); color:var(--cyan); }
@media (prefers-reduced-motion: no-preference) {
 .titulo-actual, .titulo-nuevo { animation:propuestaCrossfade 4s ease-in-out infinite; }
 .titulo-nuevo { animation-delay:-2s; }
}
@media (prefers-reduced-motion: reduce) {
 .titulo-actual, .titulo-nuevo { position:static; transform:none; margin-bottom:6px; }
}

.bloque-contenido { display:flex; flex-direction:column; align-items:center; gap:5px; width:100%; }
.propuesta-bloque .card-ic, .propuesta-bloque .card-flag-ic { width:28px; height:28px; }
.propuesta-bloque span.emoji { font-size:1.6rem; }

.card-content p.bloque-nombre { font-size:0.72rem; font-weight:800; text-transform:uppercase; letter-spacing:0.04em; line-height:1.3; }
.card-content p.bloque-fecha { font-size:0.88rem; font-weight:800; letter-spacing:-0.01em; }

.bloque-actual .bloque-nombre, .bloque-actual .bloque-fecha { color:var(--t2); }
.campo-nuevo .bloque-nombre, .campo-nuevo .bloque-fecha { color:var(--cyan); }


/* Aprobar/Rechazar — el conteo ya NO vive en una fila aparte (era
 redundante: mismo cian/rojo repetido dos veces, una vez como texto
 pasivo y otra en el botón). Cada voto es un solo chip neumórfico —
 ícono + número fundidos en un único botón, mismo patrón de "reacción"
 de apps modernas (like/reaction buttons) — así la card gana una fila
 completa de aire. Superficie IDÉNTICA en los dos chips (--bg-card +
 --neu-btn, igual que .card-edit-btn/.tl-btn): lo único que distingue
 Aprobar de Rechazar es el color (cian/rojo) y un tinte MUY sutil pintado
 ENCIMA de ese mismo panel — dos capas de background, el gradiente plano
 de color arriba y el panel neumórfico de siempre abajo, así el tinte no
 pisa la sombra ya calibrada del sitio. */
.propuesta-votos-actions { display:flex; gap:10px; width:100%; justify-content:center; align-items:center; margin-top:10px; }
.propuesta-btn {
 flex:0 1 auto; min-width:0; display:flex; align-items:center; justify-content:center; gap:5px;
 padding:8px 13px; border:none; border-radius:20px; cursor:pointer;
 font-family:var(--f); font-size:0.76rem; font-weight:800; line-height:1;
 transition:transform .15s cubic-bezier(0.34,1.56,0.64,1), box-shadow .15s ease, filter .12s ease;
}
.propuesta-btn svg { flex-shrink:0; }
.propuesta-btn:hover:not(:disabled):not(.is-gated) { transform:translateY(-2px); filter:brightness(1.05); }
.propuesta-btn:active:not(:disabled):not(.is-gated) { transform:scale(0.92) translateY(0); box-shadow:var(--neu-btn-press); filter:brightness(0.97); }
.propuesta-btn:disabled { opacity:0.4; cursor:not-allowed; }

/* Feedback del toque, SIN mensaje en pantalla — ver attachVotoListeners en
 script.js. No alcanza con :active: runGuarded deshabilita el botón casi
 en el mismo instante del click (para bloquear doble envío), y muchos
 navegadores cortan :active en cuanto el elemento queda disabled — el
 "hundido" nunca llegaba a verse. Por eso el press-in es una animación
 disparada a mano (clase .voto-pulsando, un solo ciclo) en vez de depender
 de un pseudo-estado que puede no disparar. */
@keyframes votoPress {
 0%   { transform:scale(1); box-shadow:var(--neu-btn); }
 45%  { transform:scale(0.86); box-shadow:var(--neu-btn-press); }
 100% { transform:scale(1); box-shadow:var(--neu-btn); }
}
.propuesta-btn.voto-pulsando { animation:votoPress .38s cubic-bezier(0.45,0,0.55,1); }

/* El chip que se vota siempre se vuelve a montar de cero (refreshCardDisplay
 reemplaza el HTML entero de la card, ver script.js) — así que no hay un
 "antes" en el DOM contra el que hacer transition del número. Un
 @keyframes SÍ se dispara solo con que el elemento nazca ya con esa
 animación puesta, sin necesitar dos estados: por eso el número entra con
 un pop chiquito cada vez que cambia, y el chip elegido asienta su tono
 final (satura + define color) en vez de aparecer ya resuelto de golpe. */
@keyframes votoNumIn {
 from { transform:scale(0.4); opacity:0; }
 to   { transform:scale(1); opacity:1; }
}
.voto-num { display:inline-block; min-width:1ch; animation:votoNumIn .3s cubic-bezier(0.34,1.56,0.64,1) both; }

@keyframes votoTonoIn {
 from { filter:saturate(0.3) brightness(1.05); }
 to   { filter:saturate(1) brightness(1); }
}
/* Tu voto: mismo chip de siempre, pero el tono asienta suave (no aparece
 ya "prendido" de una) y queda casi a opacidad plena aunque esté disabled
 — es justo el que ganó, no tiene sentido que se vea apagado. */
.propuesta-btn.mi-voto { animation:votoTonoIn .5s ease both; }
.propuesta-btn.mi-voto:disabled { opacity:0.95; cursor:default; }
/* El que no elegiste se apaga un poco más que el disabled genérico —
 la diferencia de opacidad ENTRE los dos chips es la que cuenta la
 historia de "esto fue lo que votaste", sin una palabra de texto. */
.propuesta-btn.no-elegido:disabled { opacity:0.32; filter:saturate(0.3); cursor:default; }

/* Identidad nueva (< 30 min): mismo gris y mismo disabled real que el
 estado "ya votaste" — a propósito no explica nada al tocarlo (decisión
 de producto, ver script.js). */
.propuesta-btn.is-gated { opacity:0.4; filter:grayscale(0.9); cursor:not-allowed; }
.propuesta-aprobar { background:linear-gradient(var(--cyan-bg), var(--cyan-bg)), var(--bg-card); box-shadow:var(--neu-btn); color:var(--cyan); }
.propuesta-rechazar { background:linear-gradient(var(--red-bg), var(--red-bg)), var(--bg-card); box-shadow:var(--neu-btn); color:var(--red); }

.card .editable-title, .card .editable-emoji {
 background:var(--bg); border:1px solid rgba(0,0,0,0.08); color:var(--t1);
 box-shadow:var(--neu-in); border-radius:10px; width:100%; padding:7px 12px;
 font-family:var(--f); font-size:0.9rem; margin-bottom:4px;
}
.card .fecha-edit-row {
 display:flex; flex-direction:column; gap:6px; margin-bottom:8px;
}

/* Botón que abre el selector de iconos (reemplaza al emoji mientras se edita) */
.icon-picker-trigger {
 display:flex; align-items:center; justify-content:center;
 width:56px; height:56px; margin:0 auto 8px; padding:0;
 background:var(--bg); border:1px dashed rgba(0,0,0,0.18); border-radius:14px;
 cursor:pointer; transition:transform .15s, border-color .15s;
}
.icon-picker-trigger:hover { transform:scale(1.06); border-color:var(--blue); }
.icon-picker-trigger .card-icon-wrap { transform:none !important; }
.icon-picker-trigger .emoji { font-size:1.8rem; filter:none; }

/* Modal selector: cuadrícula de iconos */
.icon-picker-glass { max-width:380px; max-height:80vh; overflow-y:auto; }
.icon-picker-grid {
 display:grid; grid-template-columns:repeat(4, 1fr); gap:10px;
 max-height:46vh; overflow-y:auto; padding:2px;
}
.icon-pick-btn {
 display:flex; flex-direction:column; align-items:center; gap:6px;
 padding:10px 4px; background:var(--bg); border:1px solid rgba(0,0,0,0.06);
 border-radius:14px; cursor:pointer; box-shadow:var(--neu-out-sm);
 transition:transform .15s; font-family:var(--f);
}
.icon-pick-btn:hover { transform:translateY(-2px) scale(1.04); }
.icon-pick-btn:active { transform:scale(0.96); }
.icon-pick-btn img { width:26px; height:26px; }
.icon-pick-btn span { font-size:0.6rem; color:var(--t3); font-weight:600; text-align:center; line-height:1.2; overflow-wrap:anywhere; }

/* Encabezado de categoría dentro de la cuadrícula (pack ampliado) */
.icon-picker-category {
 grid-column: 1 / -1;
 font-size:0.66rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
 color:var(--t3); margin-top:12px; padding-top:10px; border-top:1px solid rgba(0,0,0,0.08);
}
.icon-pick-btn.selected {
 background:rgba(32,96,200,0.08); box-shadow:var(--neu-in), 0 0 0 2px var(--blue);
}
.icon-pick-btn.selected span { color:var(--blue); }

/* Vista previa: muestra lo que se va a elegir antes de tocar "Aceptar" */
.icon-picker-custom {
 display:flex; align-items:center; gap:10px; margin-top:16px;
}
.icon-picker-preview {
 display:flex; align-items:center; justify-content:center; flex-shrink:0;
 width:44px; height:44px; background:var(--bg); border-radius:12px; box-shadow:var(--neu-in);
}
.icon-picker-preview .card-ic { width:26px; height:26px; filter:none; }
.icon-picker-preview .card-flag-ic { width:28px; height:28px; filter:none; }
.icon-picker-preview .emoji { font-size:1.5rem; }
.icon-picker-custom input {
 flex:1; min-width:0; background:var(--bg); border:1px solid rgba(0,0,0,0.08);
 box-shadow:var(--neu-in); border-radius:10px; padding:8px 10px;
 font-family:var(--f); font-size:1rem; text-align:center;
}

/* BOTONES */
.btn {
 display:inline-flex; align-items:center; justify-content:center; gap:8px;
 padding:12px 24px; border:none; border-radius:50px;
 font-family:var(--f); font-weight:700; font-size:0.88rem; cursor:pointer; color:#fff;
 transition:transform .2s cubic-bezier(0.34,1.56,0.64,1);
}
.btn svg { width:15px; height:15px; }
.btn:hover { transform:translateY(-2px); }
.btn:active { transform:scale(.97); }
.btn:disabled { opacity:.45; cursor:not-allowed; transform:none !important; box-shadow:none !important; }
.btn-primary { background:var(--accept-blue); box-shadow:2px 2px 6px rgba(87,140,196,0.38),-1px -1px 4px rgba(255,255,255,0.70); }
.btn-primary:hover { box-shadow:3px 3px 9px rgba(87,140,196,0.46),-2px -2px 5px rgba(255,255,255,0.75); }
.btn-success { background:var(--green); box-shadow:2px 2px 6px rgba(48,184,85,0.35),-1px -1px 4px rgba(255,255,255,0.70); }
.btn-success:hover { box-shadow:3px 3px 9px rgba(48,184,85,0.42),-2px -2px 5px rgba(255,255,255,0.75); }
.btn-danger { background:var(--red); box-shadow:2px 2px 6px rgba(224,48,48,0.35),-1px -1px 4px rgba(255,255,255,0.70); }
.btn-secondary { background:var(--bg-card); color:var(--t1); box-shadow:var(--neu-btn); }
.btn-secondary:hover { box-shadow:3px 3px 8px rgba(0,0,0,0.16),-2px -2px 6px rgba(255,255,255,0.90); }
.btn-sm { padding:8px 16px; font-size:0.82rem; }
.btn-sm svg { width:13px; height:13px; }

/* ⏳ ESTADO DE CARGA — reutilizable en cualquier botón (.btn, .card-accept-btn,
 .like-button, .modal-submit-btn...). El texto/ícono se vuelve transparente
 y un spinner se centra encima con ::after, así el botón NUNCA cambia de
 tamaño (sin salto de layout) y no hace falta tocar su HTML/innerHTML. */
.is-loading, .is-loading * { color:transparent !important; pointer-events:none; }
.btn.is-loading:disabled, .is-loading:disabled { opacity:1; } /* ocupado ≠ apagado */
.is-loading { position:relative; }
.is-loading::after {
 content:''; position:absolute; top:50%; left:50%;
 width:15px; height:15px; margin:-8px 0 0 -8px;
 border:2px solid rgba(255,255,255,.4); border-top-color:#fff;
 border-radius:50%; animation:btn-spin .65s linear infinite;
}
/* Botones claros (fondo pálido / sin fondo) → spinner oscuro en vez de blanco */
.like-button.is-loading::after, .btn-secondary.is-loading::after {
 border-color:rgba(0,0,0,.15); border-top-color:var(--t2);
}
@keyframes btn-spin { to { transform:rotate(360deg); } }

/* TAB 2 - NOTICIAS */
#view-noticias { padding:20px 16px calc(var(--wrap-h) + 36px); max-width:900px; margin:0 auto; }
#view-chat { padding:20px 16px 0; max-width:900px; margin:0 auto; }
.tab-top-bar { display:flex; align-items:center; justify-content:space-between; margin-bottom:18px; }
.tab-top-actions { display:flex; align-items:center; gap:10px; }

.glass-delete-btn {
 display:inline-flex; align-items:center; justify-content:center;
 width:40px; height:40px; background:var(--bg-card);
 border:1px solid rgba(255,255,255,0.55); border-radius:50%;
 color:var(--red); cursor:pointer; flex-shrink:0;
 box-shadow:var(--neu-out-sm);
 transition:transform .2s cubic-bezier(0.34,1.56,0.64,1);
}
.glass-delete-btn svg { width:15px; height:15px; stroke:var(--red); }
.glass-delete-btn:hover { transform:translateY(-2px); box-shadow:3px 3px 6px rgba(0,0,0,0.15),-2px -2px 4px rgba(255,255,255,0.90); }
.glass-delete-btn:active { box-shadow:var(--neu-btn-press); }
.tab-section-title { font-family:var(--f-serif); font-size:1.7rem; font-weight:400; color:var(--t1); letter-spacing:-0.02em; font-style:italic; }

.glass-add-btn {
 display:inline-flex; align-items:center; gap:8px; padding:10px 18px;
 background:var(--bg-card); border:1px solid rgba(255,255,255,0.55); border-radius:50px;
 color:var(--t1); font-family:var(--f); font-size:0.84rem; font-weight:700; cursor:pointer;
 box-shadow:var(--neu-btn); transition:transform .2s cubic-bezier(0.34,1.56,0.64,1);
}
.glass-add-btn:hover { transform:translateY(-2px); box-shadow:3px 3px 8px rgba(0,0,0,0.15),-2px -2px 5px rgba(255,255,255,0.90); }
.glass-add-btn:active { box-shadow:var(--neu-btn-press); }
.glass-add-icon { width:22px; height:22px; background:var(--blue); border-radius:50%; display:flex; align-items:center; justify-content:center; flex-shrink:0; box-shadow:2px 2px 6px rgba(32,96,200,0.40); }
.glass-add-icon svg { width:11px; height:11px; stroke:#fff; }

#noticias-list { display:flex; flex-direction:column; gap:12px; }

.noticia-card {
 background:var(--bg-card); border:1px solid rgba(255,255,255,0.55);
 border-radius:var(--r2); padding:18px 20px;
 box-shadow:var(--neu-out); animation:fadeUp .32s ease;
 transition:transform .22s cubic-bezier(0.34,1.2,0.64,1);
 position:relative; overflow:hidden;
}
.noticia-card::before { content:''; position:absolute; left:0; top:12px; bottom:12px; width:3px; background:var(--red); border-radius:0 2px 2px 0; opacity:0.7; }
.noticia-card:hover { transform:translateY(-3px); box-shadow:4px 4px 10px rgba(0,0,0,0.14),-2px -2px 6px rgba(255,255,255,0.90); }
.noticia-card .noticia-texto { font-size:0.92rem; color:var(--t1); line-height:1.65; word-break:break-word; padding-left:8px; }
.noticia-card .noticia-texto a { color:var(--blue); text-decoration:none; font-weight:700; }
.noticia-card .noticia-texto a:hover { text-decoration:underline; }
.noticia-card .noticia-meta { margin-top:10px; font-size:0.72rem; color:var(--t3); display:flex; align-items:center; gap:6px; padding-left:8px; }
.noticia-card .noticia-meta::before { content:''; width:4px; height:4px; border-radius:50%; background:var(--red); flex-shrink:0; opacity:0.6; }

.noticias-empty {
 text-align:center; color:var(--t3); padding:52px 20px; font-size:0.86rem;
 background:var(--bg-card); border:1px solid rgba(255,255,255,0.55);
 border-radius:var(--r2); box-shadow:var(--neu-out);
}

/* MODAL */
.modal-overlay {
 position:fixed; inset:0; z-index:900;
 background:rgba(0,0,0,0.18); backdrop-filter:blur(5px); -webkit-backdrop-filter:blur(5px);
 display:flex; align-items:flex-end; justify-content:center;
 padding:0 0 calc(var(--tab-h) + 40px); animation:overlayIn .22s ease;
}
.modal-glass {
 width:100%; max-width:600px; background:var(--bg);
 border:1px solid rgba(255,255,255,0.70); border-bottom:none;
 border-radius:var(--r2) var(--r2) 0 0; padding:22px 22px 28px;
 box-shadow:-2px -4px 20px rgba(0,0,0,0.12),0 0 0 1px rgba(255,255,255,0.6);
 animation:sheetUp .32s cubic-bezier(0.34,1.3,0.64,1);
}
.modal-glass::before { content:''; display:block; width:38px; height:4px; background:rgba(0,0,0,0.12); border-radius:2px; margin:0 auto 20px; box-shadow:0 1px 0 rgba(255,255,255,0.8); }
.modal-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:6px; }
.modal-title { font-size:1.08rem; font-weight:800; color:var(--t1); }
.modal-close {
 width:30px; height:30px; border-radius:50%; background:var(--bg-card);
 border:1px solid rgba(255,255,255,0.55); cursor:pointer;
 display:flex; align-items:center; justify-content:center;
 box-shadow:var(--neu-out-sm); transition:transform .15s;
}
.modal-close:hover { transform:scale(1.1); }
.modal-close:active { box-shadow:var(--neu-in); }
.modal-close svg { width:13px; height:13px; stroke:var(--t2); }
.modal-subtitle { font-size:0.82rem; color:var(--t3); margin-bottom:16px; line-height:1.55; }
.modal-textarea {
 width:100%; min-height:92px; resize:none;
 background:var(--bg-card); border:1px solid rgba(255,255,255,0.55);
 box-shadow:var(--neu-in); border-radius:var(--r);
 color:var(--t1); font-family:var(--f); font-size:0.95rem; padding:14px 16px; line-height:1.55;
 
}
.modal-textarea:focus { outline:none; box-shadow:inset 2px 2px 5px rgba(0,0,0,0.13),inset -2px -2px 4px rgba(255,255,255,0.70),0 0 0 3px rgba(32,96,200,0.12); }
.modal-meta { display:flex; justify-content:flex-end; margin:7px 0 18px; }
.modal-char { font-size:0.72rem; color:var(--t4); }
.modal-submit-btn {
 width:100%; padding:15px; background:var(--blue); border:none; border-radius:50px;
 color:#fff; font-family:var(--f); font-size:1rem; font-weight:700; cursor:pointer;
 display:flex; align-items:center; justify-content:center; gap:8px;
 box-shadow:2px 2px 8px rgba(32,96,200,0.40),-1px -1px 4px rgba(255,255,255,0.60);
 transition:opacity .15s, transform .2s cubic-bezier(0.34,1.56,0.64,1);
}
.modal-submit-btn svg { width:16px; height:16px; }
.modal-submit-btn:hover { opacity:.92; transform:translateY(-2px); box-shadow:3px 4px 11px rgba(32,96,200,0.46),-1px -1px 4px rgba(255,255,255,0.65); }
.modal-submit-btn:active { transform:scale(.97); }
.modal-submit-btn:disabled { opacity:.45; cursor:not-allowed; }

/* DIÁLOGOS (alert/confirm propios) — flotan centrados en cualquier pantalla,
 con su propia animación suave. Independientes del modal-hoja de arriba. */
@keyframes chDialogIn { from { opacity:0; transform:scale(0.92) translateY(8px); } to { opacity:1; transform:scale(1) translateY(0); } }
.ch-dialog-overlay {
 position:fixed; inset:0; z-index:950;
 background:rgba(0,0,0,0.22); backdrop-filter:blur(5px); -webkit-backdrop-filter:blur(5px);
 display:flex; align-items:center; justify-content:center;
 padding:24px; animation:overlayIn .2s ease;
}
.ch-dialog-glass {
 width:100%; max-width:340px; background:var(--bg);
 border:1px solid rgba(255,255,255,0.70); border-radius:var(--r2);
 padding:26px 22px 20px; text-align:center;
 box-shadow:5px 5px 20px rgba(0,0,0,0.16),-3px -3px 10px rgba(255,255,255,0.75),0 0 0 1px rgba(255,255,255,0.5);
 animation:chDialogIn .28s cubic-bezier(0.34,1.4,0.64,1);
}
.ch-dialog-message { font-size:0.94rem; line-height:1.55; color:var(--t1); text-align:center; margin:2px 0 22px; }
.ch-dialog-actions { display:flex; gap:10px; }
.ch-dialog-actions .btn { flex:1; padding:13px 18px; }

.ch-dialog-icon {
 width:56px; height:56px; border-radius:50%;
 display:flex; align-items:center; justify-content:center;
 margin:0 auto 16px;
}
.ch-dialog-icon .ic { width:28px; height:28px; }
.ch-dialog-icon.success { background:rgba(52,199,89,0.14); color:#2e9e4d; }
.ch-dialog-icon.warning { background:rgba(255,159,10,0.15); color:#c9760a; }
.ch-dialog-icon.error { background:rgba(255,59,48,0.13); color:#d33a30; }

/* TAB 3 - CHAT */
.chat-view { display:none; }
.chat-view.active {
 display:block; position:fixed;
 top:var(--head-h); left:0; right:0; bottom:var(--wrap-h);
 overflow:hidden; padding:14px 16px 0;
 max-width:900px; margin:0 auto;
 padding-bottom:env(safe-area-inset-bottom,0px);
}
.chat-view .tab-section-title { margin-bottom:12px; }

.comments-display-wrap {
 position:absolute; top:64px; left:16px; right:16px; bottom:116px;
 overflow-y:auto; background:var(--bg-card); border:1px solid rgba(255,255,255,0.55);
 border-radius:var(--r2); padding:14px; box-shadow:var(--neu-in);
}
.loading-msg { text-align:center; color:var(--t4); padding:28px; font-size:0.88rem; }

.comment-item {
 margin-bottom:14px; animation:fadeUp .3s ease;
}
.comment-main-row { display:flex; gap:10px; align-items:flex-start; }
.comment-avatar {
 width:34px; height:34px; border-radius:50%;
 font-weight:800; font-size:0.82rem; display:flex; align-items:center; justify-content:center;
 flex-shrink:0; color:#fff; text-transform:uppercase; user-select:none;
 box-shadow:var(--neu-btn);
}
.comment-bubble {
 flex-grow:1; background:var(--bg); border:1px solid rgba(255,255,255,0.55);
 padding:10px 14px; border-radius:4px var(--r) var(--r) var(--r);
 max-width:100%; box-shadow:var(--neu-out-sm);
}
.comment-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:4px; }
.comment-name { color:var(--t1); font-weight:800; font-size:.8rem; }
.comment-date { font-size:.68rem; color:var(--t4); }
.comment-content { color:var(--t2); font-size:.82rem; line-height:1.55; word-wrap:break-word; }
.comment-actions { display:flex; align-items:center; justify-content:flex-end; gap:12px; margin-top:7px; padding-top:7px; border-top:1px solid rgba(0,0,0,0.05); }
.like-button { background:transparent; border:none; cursor:pointer; font-size:.9rem; color:var(--t4); transition:color .15s,transform .2s cubic-bezier(0.34,1.56,0.64,1); display:flex; align-items:center; gap:4px; padding:0; }
.like-button:hover { color:var(--red); transform:scale(1.18); }
.like-button.liked { color:var(--red); }
.like-count { font-size:.8rem; color:var(--t3); font-weight:700; }
.reply-form-toggle { font-size:.78rem; color:var(--blue); font-weight:700; cursor:pointer; text-transform:uppercase; padding:2px 10px; border-radius:50px; letter-spacing:.04em; background:var(--bg-card); box-shadow:var(--neu-out-sm); }
.reply-form-toggle:hover { box-shadow:2px 2px 5px rgba(0,0,0,0.13),-1px -1px 4px rgba(255,255,255,0.85); }
.replies-container {
 margin-top:8px; padding-left:10px; padding-bottom:6px; margin-left:18px;
 border-left:2px solid rgba(80,64,184,0.12); width:calc(100% - 18px);
 /* El contenido que de verdad puede crecer sin límite en un comentario
    es esto — los hilos de respuestas, no la fila principal (avatar +
    burbuja, que es siempre una sola fila fija). Por eso el ahorro de
    layout/pintado fuera de pantalla va acá y no en .comment-item: como
    .replies-container es HERMANO de .comment-main-row (no su padre), el
    recorte de pintado que impone content-visibility nunca llega a tocar
    la sombra del avatar ni de la burbuja — quedan totalmente libres de
    sangrar hacia afuera, sin el problema que tuvimos antes. El
    padding-bottom de 6px es sólo para que, si la ÚLTIMA respuesta del
    hilo es corta, su propia sombra tenga un pelito de margen antes de
    tocar este mismo borde. La mayoría de los comentarios no tienen
    respuestas — por eso el intrinsic-size de abajo arranca en 0, no en
    una estimación grande. */
 content-visibility: auto;
 contain-intrinsic-size: auto 0px;
}
.comment-item.reply-style { margin-bottom:8px; }
.comment-item.reply-style .comment-avatar { width:28px; height:28px; font-size:.76rem; }
.comment-item.reply-style .comment-bubble { padding:8px 12px; }
.comment-item.reply-style .comment-content { font-size:.8rem; }
.reply-form { display:none; margin-top:8px; background:var(--bg-card); border:1px solid rgba(255,255,255,0.55); border-radius:var(--r); padding:14px; margin-left:44px; width:calc(100% - 44px); box-shadow:var(--neu-in); }
.reply-form input, .reply-form textarea { width:100%; padding:9px 14px; margin-bottom:8px; border:1px solid rgba(255,255,255,0.55); border-radius:50px; background:var(--bg); font-family:var(--f); font-size:.82rem; color:var(--t1); box-shadow:var(--neu-in); }
.reply-form input:focus, .reply-form textarea:focus { outline:none; box-shadow:inset 2px 2px 4px rgba(0,0,0,0.12),inset -1px -1px 3px rgba(255,255,255,0.70),0 0 0 3px rgba(80,64,184,0.10); }

/* CHAT COMPOSER */
.chat-composer { position:absolute; bottom:22px; left:16px; right:16px; }
.chat-composer-inner { background:var(--bg-card); border:1px solid rgba(255,255,255,0.60); border-radius:var(--r2); padding:14px 16px; display:flex; flex-direction:column; gap:10px; box-shadow:var(--neu-out); }
.chat-name-input { background:var(--bg); border:1px solid rgba(255,255,255,0.55); box-shadow:var(--neu-in); border-radius:50px; color:var(--t1); font-family:var(--f); font-size:0.85rem; padding:9px 18px; width:100%; }
.chat-name-input:focus { outline:none; box-shadow:inset 2px 2px 4px rgba(0,0,0,0.12),inset -1px -1px 3px rgba(255,255,255,0.70),0 0 0 3px rgba(80,64,184,0.10); }
.chat-msg-row { display:flex; gap:10px; align-items:center; }
.chat-msg-input { flex:1; background:var(--bg); border:1px solid rgba(255,255,255,0.55); box-shadow:var(--neu-in); border-radius:50px; color:var(--t1); font-family:var(--f); font-size:0.9rem; padding:9px 20px; }
.chat-msg-input:focus { outline:none; box-shadow:inset 2px 2px 4px rgba(0,0,0,0.12),inset -1px -1px 3px rgba(255,255,255,0.70),0 0 0 3px rgba(32,96,200,0.10); }
.chat-send-btn { width:40px; height:40px; flex-shrink:0; background:var(--blue); border:none; border-radius:50%; cursor:pointer; display:flex; align-items:center; justify-content:center; box-shadow:2px 2px 5px rgba(32,96,200,0.40),-1px -1px 3px rgba(255,255,255,0.60); transition:opacity .15s, transform .2s cubic-bezier(0.34,1.56,0.64,1); }
.chat-send-btn svg { width:15px; height:15px; stroke:#fff; }
.chat-send-btn:hover { opacity:.92; transform:scale(1.08); box-shadow:3px 3px 8px rgba(32,96,200,0.46),-1px -1px 4px rgba(255,255,255,0.65); }
.chat-send-btn:active { transform:scale(.92); }

/* BARRA INFERIOR — neumorfismo de "una sola superficie".
   - La barra es UNA pieza elevada. Los tabs inactivos van planos, sin
     sombra propia (antes eran 3 botones elevados a la vez: más ruido
     visual y 3 sombras dobles que repintar).
   - El tab activo se "hunde" en la superficie (--neu-in) y toma el color
     de su sección. Ese hundido vive en un ::before que SOLO cambia de
     opacidad: no se anima box-shadow (más barato y sin saltos).
   - Reglas de la casa: cero blur grande, cero backdrop-filter. */
.tab-bar-wrap {
 position:fixed; bottom:0; left:0; right:0; z-index:500;
 background:var(--bg);
 box-shadow:0 -1px 0 rgba(255,255,255,0.80), 0 -3px 8px rgba(0,0,0,0.07);
}
.tab-bar {
 height:var(--tab-h); max-width:540px; margin:0 auto; padding:0 14px;
 display:flex; align-items:center; justify-content:center; gap:4px;
}
.tab-bar-footer {
 text-align:center; padding:1px 0 calc(6px + env(safe-area-inset-bottom,0px));
 font-size:0.67rem; line-height:1.4; color:var(--nav-idle);
}
.tab-bar-footer a { color:#2b6cb0; text-decoration:none; font-weight:700; }
.tab-bar-footer a:hover { text-decoration:underline; }

.tab-btn {
 --tab-accent:var(--blue);
 position:relative; isolation:isolate;
 flex:1; min-width:0; max-width:120px; height:46px;
 display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
 padding:0 6px; background:none; border:none; border-radius:16px; cursor:pointer;
 color:var(--nav-idle); font-family:var(--f);
 -webkit-tap-highlight-color:transparent; touch-action:manipulation; user-select:none;
 transition:color .2s ease;
}
.tab-btn[data-tab="view-noticias"] { --tab-accent:#c42626; }
.tab-btn[data-tab="view-chat"] { --tab-accent:var(--violet); }
.tab-btn::before {
 content:''; position:absolute; inset:0; z-index:-1; border-radius:inherit;
 background:var(--bg-card); box-shadow:var(--neu-in);
 opacity:0; transition:opacity .2s ease;
}
.tab-btn .ti { transition:transform .2s cubic-bezier(0.34,1.4,0.64,1); }
.tab-label { font-size:0.68rem; font-weight:700; letter-spacing:0.01em; line-height:1; }

.tab-btn.active { color:var(--tab-accent); }
.tab-btn.active::before { opacity:1; }
.tab-btn:active:not(.active)::before { opacity:0.55; }
.tab-btn:active .ti { transform:scale(0.9); }
@media (hover:hover) { .tab-btn:not(.active):hover { color:var(--t2); } }
@media (prefers-reduced-motion:reduce) { .tab-btn, .tab-btn::before, .tab-btn .ti { transition:none; } }

/* ICONOS CSS */
.ti { display:block; position:relative; width:26px; height:26px; }
.ti-cal { display:flex; flex-direction:column; width:22px; height:20px; }
.ti-cal-cap { height:6px; background:currentColor; border-radius:3px 3px 0 0; opacity:.9; position:relative; }
.ti-cal-cap::before, .ti-cal-cap::after { content:''; position:absolute; top:-3px; width:3px; height:5px; background:currentColor; border-radius:2px 2px 0 0; }
.ti-cal-cap::before { left:4px; } .ti-cal-cap::after { right:4px; }
.ti-cal-body { flex:1; background:rgba(0,0,0,0.04); border:1.5px solid currentColor; border-top:none; border-radius:0 0 3px 3px; display:grid; grid-template-columns:repeat(3,1fr); gap:2px; padding:2px 3px 2px; }
.ti-cal-row { display:contents; }
.ti-cal-body i, .ti-cal-row i { display:block; width:3px; height:3px; background:currentColor; border-radius:1px; opacity:.55; justify-self:center; align-self:center; }
.ti-cal-row:first-child i:first-child { opacity:1; }

.ti-signal { width:22px; height:20px; display:flex; align-items:flex-end; justify-content:center; position:relative; }
.ti-sig-dot { width:4px; height:4px; background:currentColor; border-radius:50%; position:absolute; bottom:0; left:50%; transform:translateX(-50%); }
.ti-sig-arc { position:absolute; border:1.8px solid currentColor; border-radius:50%; bottom:1px; left:50%; transform:translateX(-50%); border-left-color:transparent; border-right-color:transparent; border-bottom-color:transparent; }
.ti-sig-arc.a1 { width:8px; height:8px; }
.ti-sig-arc.a2 { width:14px; height:14px; opacity:.65; }
.ti-sig-arc.a3 { width:20px; height:20px; opacity:.35; }

.ti-bubble { width:22px; height:20px; position:relative; }
.ti-bub-main { position:absolute; top:0; left:0; right:0; height:16px; background:currentColor; border-radius:10px 10px 10px 3px; opacity:.9; display:flex; align-items:center; justify-content:center; gap:3px; }
.ti-bub-main i { display:block; width:3px; height:3px; background:var(--bg); border-radius:50%; }
.ti-bub-tail { position:absolute; bottom:0; left:2px; width:7px; height:6px; background:currentColor; opacity:.9; clip-path:polygon(0 0,100% 0,0 100%); }

/* RESPONSIVE PC */
@media (min-width:768px) {
 .tab-bar-wrap { width:100%; max-width:560px; left:50%; right:auto; transform:translateX(-50%); border-radius:var(--r2) var(--r2) 0 0; box-shadow:0 -1px 0 rgba(255,255,255,0.80), -2px -2px 5px rgba(255,255,255,0.65), 2px -3px 8px rgba(0,0,0,0.08); }
 .modal-overlay { align-items:center; padding:0; }
 .modal-glass { border-radius:var(--r2); max-width:460px; border:1px solid rgba(255,255,255,0.65); box-shadow:5px 5px 20px rgba(0,0,0,0.14),-3px -3px 10px rgba(255,255,255,0.80); }
 .modal-glass::before { display:none; }
}
@media (min-width:768px) { @keyframes sheetUp { from { opacity:0; transform:scale(0.94) translateY(10px); } to { opacity:1; transform:scale(1) translateY(0); } } }

/* UTILITIES */
input::placeholder, textarea::placeholder { color:var(--t4); }
*:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }
*:focus:not(:focus-visible) { outline:none; }

/* MODO BORRAR NOTICIAS */
.noticia-card.selectable { cursor:pointer; }
.noticia-card.selectable:active { transform:scale(0.98); }
.noticia-card.selected { background:rgba(224,48,48,0.06); border-color:rgba(224,48,48,0.25); }
.noticia-card.selected::before { background:var(--red); width:4px; opacity:1; }
.noticia-checkbox { position:absolute; top:12px; right:12px; width:24px; height:24px; border-radius:50%; background:var(--bg-card); box-shadow:var(--neu-out-sm); display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:bold; color:white; transition:background .15s; flex-shrink:0; }
.noticia-card.selected .noticia-checkbox { background:var(--red); box-shadow:2px 2px 6px rgba(224,48,48,0.40); }
.noticia-card.selectable .noticia-texto { padding-right:38px; }
.noticias-delete-bar { display:flex; gap:10px; margin-top:14px; animation:fadeUp .2s ease; }
.noticias-delete-bar .btn-cancelar { flex:1; padding:12px 0; border:1px solid rgba(255,255,255,0.55); border-radius:var(--r2); background:var(--bg-card); box-shadow:var(--neu-btn); color:var(--t2); font-size:0.88rem; font-weight:600; cursor:pointer; }
.noticias-delete-bar .btn-cancelar:hover { box-shadow:3px 3px 7px rgba(0,0,0,0.13),-2px -2px 5px rgba(255,255,255,0.88); }
.noticias-delete-bar .btn-confirmar { flex:2; padding:12px 0; border:none; border-radius:var(--r2); background:rgba(224,48,48,0.12); box-shadow:var(--neu-out-sm); color:var(--red); font-size:0.88rem; font-weight:700; cursor:not-allowed; transition:background .15s; }
.noticias-delete-bar .btn-confirmar.activo { background:var(--red); color:white; cursor:pointer; box-shadow:2px 2px 6px rgba(224,48,48,0.40),-1px -1px 4px rgba(255,255,255,0.70); }
.noticias-delete-bar .btn-confirmar.activo:hover { box-shadow:6px 6px 18px rgba(224,48,48,0.46); }

/* ============================================================
 SKELETON SCREENS — Pantallas Esqueleto
 ============================================================ */

@keyframes skeleton-shimmer {
 0% { background-position: -400px 0; }
 100% { background-position: 400px 0; }
}

.skeleton {
 background: linear-gradient(90deg,
 rgba(0,0,0,0.07) 25%,
 rgba(0,0,0,0.04) 50%,
 rgba(0,0,0,0.07) 75%
 );
 background-size: 800px 100%;
 animation: skeleton-shimmer 1.5s infinite linear;
 border-radius: 8px;
}

/* --- Tarjetas principales (#contenedor) --- */
.card-skeleton {
 border-radius: var(--r2);
 background: var(--bg-card);
 box-shadow: var(--neu-out);
 padding: 18px 14px 16px;
 display: flex;
 flex-direction: column;
 align-items: center;
 gap: 10px;
 min-height: 130px;
}
.card-skeleton .sk-emoji {
 width: 44px; height: 44px;
 border-radius: 50%;
}
.card-skeleton .sk-title {
 width: 75%; height: 11px;
 border-radius: 6px;
}
.card-skeleton .sk-line {
 width: 90%; height: 9px;
 border-radius: 6px;
}
.card-skeleton .sk-line.short {
 width: 60%;
}

/* --- Panel de estado (statusDataContainer) --- */
.status-skeleton-row {
 display: flex; gap: 8px;
}
.status-item-skeleton {
 flex: 1;
 border-radius: var(--r2);
 background: var(--bg-card);
 box-shadow: var(--neu-out-sm);
 padding: 10px 10px 10px;
 display: flex;
 flex-direction: column;
 align-items: center;
 gap: 6px;
}
.status-item-skeleton .sk-label {
 width: 55%; height: 8px;
 border-radius: 4px;
}
.status-item-skeleton .sk-value {
 width: 70%; height: 14px;
 border-radius: 5px;
}

/* --- Noticias (noticias-list) --- */
.noticia-skeleton {
 border-radius: var(--r2);
 background: var(--bg-card);
 box-shadow: var(--neu-out);
 padding: 14px 16px;
 display: flex;
 flex-direction: column;
 gap: 8px;
 position: relative;
 overflow: hidden;
}
.noticia-skeleton::before {
 content: '';
 position: absolute; left: 0; top: 12px; bottom: 12px;
 width: 3px;
 background: rgba(0,0,0,0.1);
 border-radius: 0 2px 2px 0;
}
.noticia-skeleton .sk-line { width: 100%; height: 10px; border-radius: 5px; }
.noticia-skeleton .sk-line.med { width: 80%; }
.noticia-skeleton .sk-line.short { width: 45%; }

/* --- Comentarios (commentsContainer) --- */
.comment-skeleton {
 display: flex;
 gap: 10px;
 padding: 4px 0;
}
.comment-skeleton .sk-avatar {
 width: 36px; height: 36px;
 border-radius: 50%;
 flex-shrink: 0;
 margin-top: 2px;
}
.comment-skeleton .sk-bubble {
 flex: 1;
 border-radius: var(--r2);
 background: var(--bg-card);
 box-shadow: var(--neu-out-sm);
 padding: 10px 14px;
 display: flex;
 flex-direction: column;
 gap: 7px;
}
.comment-skeleton .sk-name { width: 30%; height: 9px; border-radius: 4px; }
.comment-skeleton .sk-text { width: 90%; height: 9px; border-radius: 4px; }
.comment-skeleton .sk-text.short { width: 65%; }




/* ═══════════════════════════════════════════
 SEO DARK SECTION — Ola + neumorfismo oscuro
 ═══════════════════════════════════════════ */

.seo-dark-wrap {
 display: flex;
 flex-direction: column;
 width: calc(100% + 32px); /* compensa padding 16px de cada lado */
 margin-top: 16px;
 margin-left: -16px;
 margin-right: -16px;

}

/* ── Ola SVG ── */
.seo-wave-top {
 display: block;
 line-height: 0;
 margin-bottom: -2px; /* elimina gap entre svg y fondo negro */
}
.seo-wave-top svg {
 width: 100%;
 height: 56px;
 display: block;
}

/* ── Zona negra ── */
.seo-dark-body {
 background: #0d0d0d;
 padding: 20px 16px 32px;
}

/* ── Card neumórfica oscura ── */
.seo-neu-card {
 background: #131313;
 border-radius: 18px;
 padding: 20px 18px;
 box-shadow:
 2px 2px 6px rgba(0, 0, 0, 0.7),
 -2px -2px 4px rgba(255, 255, 255, 0.04);
 border: 1px solid rgba(255,255,255,0.05);
 max-width: 640px;
 margin: 0 auto;
}

.seo-neu-card p {
 font-size: 13.5px;
 line-height: 1.7;
 color: #8a8a8e;
 margin-bottom: 12px;
 font-family: var(--f, -apple-system, sans-serif);
}
.seo-neu-card p:last-child {
 margin-bottom: 0;
}

.seo-neu-card strong {
 color: #e0e0e5;
 font-weight: 500;
}


/* ══════════════════════════════════════════════════
 ABOUT DARK BAR + MODAL NEUMÓRFICO
 ══════════════════════════════════════════════════ */

/* ── Barra oscura ── */
/* Dock al fondo: con pocas (o ninguna) tarjeta elegidas, el contenido de
 Calendario es corto y el bloque negro quedaba flotando a media pantalla,
 con un hueco claro debajo. #view-calendario pasa a ser una columna flex y
 el bloque se ancla al final con margin-top:auto. La altura mínima de la
 columna (= alto de pantalla − lo que hay encima) la fija el bloque
 "Acerca de – dock" del script inline de index.html; si ese JS no corre,
 la columna se comporta como antes (bloque justo después del contenido).
 Con muchas tarjetas el contenido ya llena la pantalla: no cambia nada. */
#view-calendario.active {
 display: flex;
 flex-direction: column;
 width: 100%; /* con margin:auto, un ítem flex no se estira solo */
}

.about-dark-bar {
 width: 100%;
 display: flex;
 flex-direction: column;
 flex-shrink: 0;
 margin-top: auto;
 padding-top: 4px; /* el respiro de 4px que antes era margin-top */
}

.about-wave-top {
 display: block;
 line-height: 0;
 margin-bottom: -1px;
}
.about-wave-top svg {
 width: 100%;
 height: 22px;
 display: block;
}

/* Altura mínima de la parte negra: SIEMPRE se ven al menos --about-min-h
 px de negro por encima de la barra de pestañas (esta tapa los últimos
 --wrap-h px, por eso se suman). El botón queda centrado en esa franja
 visible: el padding-bottom reserva justo el espacio que tapa la barra. */
.about-dark-body {
 --about-min-h: 96px;
 background: #0d0d0d;
 display: flex;
 align-items: center;
 justify-content: center;
 min-height: calc(var(--about-min-h) + var(--wrap-h, 81px) + env(safe-area-inset-bottom, 0px));
 padding: 0 16px calc(var(--wrap-h, 81px) + env(safe-area-inset-bottom, 0px));
}

/* ── Enlaces del pie (Acerca de · Términos · Privacidad) ── */
.about-links {
 display: flex;
 flex-direction: column;
 align-items: center;
 justify-content: center;
 gap: 0;
 padding: 10px 0;
}
.about-trigger {
 background: none;
 border: 0;
 padding: 5px 12px;
 color: #7c7c82;
 font-size: 11.5px;
 font-weight: 500;
 font-family: var(--f, -apple-system, sans-serif);
 letter-spacing: 0.02em;
 cursor: pointer;
 transition: color 0.2s;
 -webkit-tap-highlight-color: transparent;
}
.about-trigger:active { color: #e0e0e5; }

/* ── Modal overlay ── */
.about-modal-overlay {
 position: fixed;
 inset: 0;
 z-index: 8000;
 background: rgba(0,0,0,0.6);
 backdrop-filter:blur(4px);
 -webkit-backdrop-filter:blur(4px);
 display: flex;
 align-items: center;
 justify-content: center;
 padding: 24px 20px;
 opacity: 0;
 pointer-events: none;
 transition: opacity 0.25s ease;
}
.about-modal-overlay.is-open {
 opacity: 1;
 pointer-events: auto;
}

/* ── Card neumórfica oscura ── */
.about-modal-card {
 position: relative;
 width: 100%;
 max-width: 360px;
 background: #131313;
 border-radius: 24px;
 border: 1px solid rgba(255,255,255,0.07);
 box-shadow:
 4px 4px 12px rgba(0,0,0,0.8),
 -2px -2px 6px rgba(255,255,255,0.04),
 inset 0 1px 0 rgba(255,255,255,0.06);
 padding: 26px 22px 22px;
 text-align: center;
 transform: translateY(16px) scale(0.97);
 transition: transform 0.3s cubic-bezier(0.34,1.4,0.64,1);
}
.about-modal-overlay.is-open .about-modal-card {
 transform: translateY(0) scale(1);
}

/* ── Botón cerrar ── */
.about-modal-close {
 position: absolute;
 top: 14px;
 right: 14px;
 width: 30px;
 height: 30px;
 border-radius: 50%;
 background: #1e1e1e;
 border: 1px solid rgba(255,255,255,0.07);
 box-shadow:
 1px 1px 3px rgba(0,0,0,0.6),
 -1px -1px 2px rgba(255,255,255,0.04);
 display: flex;
 align-items: center;
 justify-content: center;
 cursor: pointer;
 color: #666;
 transition: color 0.2s;
}
.about-modal-close:active { color: #ccc; }

/* ── Ícono superior ── */
.about-modal-icon {
 width: 42px;
 height: 42px;
 border-radius: 13px;
 background: #1a1a1a;
 border: 1px solid rgba(255,255,255,0.07);
 box-shadow:
 2px 2px 6px rgba(0,0,0,0.7),
 -1px -1px 4px rgba(255,255,255,0.04);
 display: flex;
 align-items: center;
 justify-content: center;
 margin: 0 auto 12px;
 color: #6060c8;
}

/* ── Título ── */
.about-modal-title {
 font-size: 15px;
 font-weight: 600;
 color: #e0e0e5;
 margin-bottom: 12px;
 font-family: var(--f, -apple-system, sans-serif);
 letter-spacing: -0.01em;
}

/* ── Cuerpo del modal ── */
.about-modal-body p {
 font-size: 13px;
 line-height: 1.65;
 color: #7a7a7e;
 margin-bottom: 12px;
 font-family: var(--f, -apple-system, sans-serif);
 text-align: left;
}
.about-modal-body p:last-child { margin-bottom: 0; }
.about-modal-body strong {
 color: #c0c0c8;
 font-weight: 500;
}

/* ── Disclaimer ── */
.about-modal-disclaimer {
 font-size: 11px !important;
 color: #444 !important;
 text-align: center !important;
 margin-top: 16px !important;
 line-height: 1.5 !important;
 border-top: 1px solid rgba(255,255,255,0.05);
 padding-top: 12px;
}

/* ── Modales legales (Términos de uso / Privacidad) ── */
.about-modal-card--legal {
 max-width: 400px;
 max-height: calc(100vh - 48px);
 max-height: calc(100dvh - 48px);
 display: flex;
 flex-direction: column;
 padding: 22px 0 0;
 text-align: left;
}
.about-modal-card--legal .about-modal-title {
 text-align: left;
 padding: 0 56px 12px 22px;
 margin: 0;
 border-bottom: 1px solid rgba(255,255,255,0.06);
}
.about-modal-card--legal .about-modal-close { top: 16px; right: 16px; }
.about-modal-scroll {
 overflow-y: auto;
 overscroll-behavior: contain;
 -webkit-overflow-scrolling: touch;
 padding: 14px 22px 24px;
}
.about-modal-body h4 {
 font-size: 12.5px;
 font-weight: 600;
 color: #c8c8d0;
 letter-spacing: 0.01em;
 margin: 18px 0 6px;
 font-family: var(--f, -apple-system, sans-serif);
}
.about-modal-body ul {
 margin: 0 0 12px;
 padding-left: 18px;
}
.about-modal-body li {
 font-size: 13px;
 line-height: 1.65;
 color: #7a7a7e;
 margin-bottom: 6px;
 font-family: var(--f, -apple-system, sans-serif);
}
.about-modal-body a {
 color: #8a8ae0;
 text-decoration: none;
 border-bottom: 1px solid rgba(138,138,224,0.35);
}
.about-modal-body .legal-updated {
 font-size: 11px;
 color: #55555a;
 margin-bottom: 10px;
 letter-spacing: 0.02em;
}
.legal-callout {
 background: #171717;
 border: 1px solid rgba(255,255,255,0.06);
 border-radius: 14px;
 padding: 12px 14px 6px;
 margin: 14px 0 4px;
}
.legal-callout ul { list-style: none; padding: 0; margin: 0; }
.legal-callout li {
 position: relative;
 padding-left: 20px;
 color: #a8a8b0;
}
.legal-callout li::before {
 content: '';
 position: absolute;
 left: 2px; top: 0.55em;
 width: 9px; height: 5px;
 border-left: 1.6px solid #6fbf8a;
 border-bottom: 1.6px solid #6fbf8a;
 transform: rotate(-45deg);
}

/* ================================================================
 LÍNEA DE TIEMPO — modal de "Ver Detalles" en las cards predictivas
 Mismo patrón is-open (opacity+pointer-events) que .about-modal-overlay.
 ================================================================ */
.tl-modal-overlay {
 position:fixed; inset:0; z-index:8500;
 background:rgba(0,0,0,0.45); backdrop-filter:blur(5px); -webkit-backdrop-filter:blur(5px);
 display:flex; align-items:center; justify-content:center; padding:24px 16px;
 opacity:0; pointer-events:none; transition:opacity .25s ease;
}
.tl-modal-overlay.is-open { opacity:1; pointer-events:auto; }
body.tl-no-scroll { overflow:hidden; }
body.tl-no-scroll .news-ticker-content { animation-play-state: paused; }
/* El selector de fecha (datewheel.js, z-index:900) también se usa DENTRO
 del modal de línea de tiempo (z-index:8500) para "¿Cuándo me toca?" —
 necesita quedar por encima. */
body .dp-overlay { z-index: 9000; }

.tl-modal-card {
 position:relative; width:100%; max-width:400px;
 background:var(--bg-card); border-radius:var(--r2); box-shadow:var(--neu-out);
 padding:20px 16px 16px;
 transform:translateY(16px) scale(0.97);
 transition:transform .3s cubic-bezier(0.34,1.4,0.64,1);
}
.tl-modal-overlay.is-open .tl-modal-card { transform:translateY(0) scale(1); }

.tl-modal-close {
 position:absolute; top:-10px; right:-10px; z-index:2;
 width:30px; height:30px; border-radius:50%;
 background:var(--red); border:2px solid var(--bg-card);
 box-shadow:2px 3px 8px rgba(224,48,48,0.45);
 display:flex; align-items:center; justify-content:center; cursor:pointer;
}
.tl-modal-close:active { transform:scale(0.92); }

.tl-modal-title { font-size:0.86rem; font-weight:800; color:var(--t1); text-transform:uppercase; letter-spacing:0.02em; text-align:center; margin-bottom:14px; padding:0 20px; }

.tl-header { display:flex; flex-direction:column; gap:3px; margin-bottom:16px; }
.tl-eyebrow { font-size:0.65rem; font-weight:700; letter-spacing:0.10em; text-transform:uppercase; color:var(--t3); }
.tl-hint { font-size:0.62rem; color:var(--t4); letter-spacing:0.02em; }

/* ── Calculadora: "¿Cuándo me toca?" ── */
.tl-calc { margin-bottom:16px; }
.tl-calc-btn {
 border:none; background:var(--bg-card); box-shadow:var(--neu-btn); color:var(--blue);
 font-family:var(--f); font-size:0.72rem; font-weight:700; letter-spacing:0.02em;
 padding:9px 14px; border-radius:20px; cursor:pointer;
}
.tl-calc-btn:active { box-shadow:var(--neu-btn-press); }
.tl-calc-result {
 margin-top:10px; padding:11px 13px; border-radius:var(--r);
 background:var(--green-bg); color:var(--t2); font-size:0.76rem; line-height:1.45;
}
.tl-calc-result strong { color:var(--green); }
.tl-calc-result.tl-calc-empty { background:rgba(0,0,0,0.045); color:var(--t3); font-size:0.72rem; }

.tl-focus { display:flex; align-items:flex-end; justify-content:space-between; margin-bottom:16px; padding:0 2px; }
.tl-focus-date { display:flex; align-items:baseline; gap:10px; }
.tl-day { font-size:2.6rem; font-weight:800; color:var(--t1); letter-spacing:-0.03em; line-height:1; }
.tl-daymeta { display:flex; flex-direction:column; gap:2px; padding-bottom:5px; }
.tl-dow { font-size:0.68rem; font-weight:800; letter-spacing:0.08em; color:var(--t2); }
.tl-month { font-size:0.68rem; font-weight:600; letter-spacing:0.04em; color:var(--t3); }
.tl-chip { font-size:0.62rem; font-weight:800; letter-spacing:0.08em; text-transform:uppercase; color:var(--blue); background:rgba(32,96,200,0.10); padding:5px 10px; border-radius:20px; white-space:nowrap; margin-bottom:6px; }
.tl-chip.off { color:var(--t3); background:rgba(0,0,0,0.05); }

.tl-ruler-shell {
 position:relative; height:120px; border-radius:var(--r); box-shadow:var(--neu-in);
 overflow:hidden; touch-action:none; user-select:none;
 /* Tinte ambiental muy sutil: frío arriba (zona de aprobadas), cálido
    abajo (zona de rechazadas). El espacio ya insinúa qué lado es cuál,
    sin una palabra encima — igual que el resto del sitio nunca rotula
    "esto es aprobar" al lado del check verde. */
 background:
   linear-gradient(to bottom, rgba(8,145,178,0.06), transparent 45%, transparent 55%, rgba(224,48,48,0.05)),
   var(--bg-card);
}
.tl-ruler { position:absolute; inset:0; overflow:hidden; cursor:grab; touch-action:none; }
.tl-ruler.grabbing { cursor:grabbing; }
.tl-track { position:absolute; inset:0; }

.tl-baseline {
 position:absolute; left:0; right:0; top:50%; height:2px; margin-top:-1px;
 background:rgba(0,0,0,0.10); box-shadow:0 1px 0 rgba(255,255,255,0.55); border-radius:1px;
}
.tick { position:absolute; bottom:36px; width:1px; background:var(--t4); }
.tick.minor { height:8px; background:rgba(0,0,0,0.15); }
.tick.minor.mid { height:13px; }
.tick.major { height:20px; background:var(--t3); width:1.3px; }
.tick-label { position:absolute; bottom:8px; transform:translateX(-50%); font-size:0.6rem; font-weight:700; color:var(--t3); white-space:nowrap; }

.tick.today-tick { width:2px; background:var(--blue); height:32px; bottom:28px; }
.today-label { position:absolute; bottom:62px; transform:translateX(-50%); font-size:0.56rem; font-weight:800; letter-spacing:0.08em; color:#fff; background:var(--blue); padding:3px 7px; border-radius:6px; white-space:nowrap; }
.today-label::after { content:''; position:absolute; left:50%; bottom:-4px; transform:translateX(-50%); border:4px solid transparent; border-top-color:var(--blue); }

.tick.target-tick { width:2px; background:var(--violet); height:32px; bottom:28px; }
.target-label { position:absolute; bottom:62px; transform:translateX(-50%); font-size:0.56rem; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:#fff; background:var(--violet); padding:3px 7px; border-radius:6px; white-space:nowrap; max-width:120px; overflow:hidden; text-overflow:ellipsis; }
.target-label::after { content:''; position:absolute; left:50%; bottom:-4px; transform:translateX(-50%); border:4px solid transparent; border-top-color:var(--violet); }

.estimado-banda { position:absolute; bottom:28px; height:32px; background:rgba(48,184,85,0.16); border-radius:4px; }
.tick.estimado-tick { width:2px; background:var(--green); height:32px; bottom:28px; }
.estimado-label { position:absolute; bottom:62px; transform:translateX(-50%); font-size:0.56rem; font-weight:800; letter-spacing:0.08em; color:#fff; background:var(--green); padding:3px 7px; border-radius:6px; white-space:nowrap; }
.estimado-label::after { content:''; position:absolute; left:50%; bottom:-4px; transform:translateX(-50%); border:4px solid transparent; border-top-color:var(--green); }

.tl-playhead { position:absolute; left:50%; top:0; bottom:0; width:2px; background:var(--t1); opacity:0.8; pointer-events:none; }
.tl-playhead::before { content:''; position:absolute; top:6px; left:50%; transform:translate(-50%,-50%); width:0; height:0; border-left:5px solid transparent; border-right:5px solid transparent; border-top:6px solid var(--t1); }

.tl-fade { position:absolute; top:0; bottom:0; width:28px; pointer-events:none; z-index:2; }
.tl-fade-l { left:0; background:linear-gradient(to right, var(--bg-card), transparent); }
.tl-fade-r { right:0; background:linear-gradient(to left, var(--bg-card), transparent); }

.tl-controls { display:flex; align-items:center; gap:10px; margin-top:16px; }
.tl-btn { width:34px; height:34px; border-radius:50%; border:none; background:var(--bg-card); box-shadow:var(--neu-btn); color:var(--t2); font-size:1.1rem; font-weight:700; display:flex; align-items:center; justify-content:center; cursor:pointer; font-family:var(--f); }
.tl-btn:active { box-shadow:var(--neu-btn-press); }
.tl-zoomlabel { font-size:0.66rem; font-weight:700; color:var(--t3); letter-spacing:0.05em; text-transform:uppercase; min-width:46px; text-align:center; }
.tl-today-btn { margin-left:auto; border:none; background:var(--blue); color:#fff; font-family:var(--f); font-size:0.68rem; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; padding:9px 16px; border-radius:20px; cursor:pointer; box-shadow:3px 3px 8px rgba(32,96,200,0.35); opacity:0.3; pointer-events:none; transition:opacity .2s; }
.tl-today-btn.show { opacity:1; pointer-events:auto; }
.tl-today-btn:active { transform:scale(0.96); }

/* ── Marcas de votación resuelta — ya NO es una única línea roja partiendo
 el riel a la mitad: cada resultado nace en la base (línea central) y
 crece hacia su lado — APROBADAS hacia ARRIBA (cian, la comunidad avanzó
 la card), RECHAZADAS hacia ABAJO (rojo, se propuso y no prosperó). El
 propio sentido del trazo + el color ya dicen qué fue, sin una palabra. ── */
.tl-mark-stem { position:absolute; width:2.5px; border-radius:2px; transform:translateX(-1.25px); }
.tl-mark-stem.up   { bottom:60px; height:22px; }
.tl-mark-stem.down { top:60px; height:22px; }
/* El tallo nace transparente en la base y se satura al llegar a la
 punta — se siente "brotar" del centro en vez de una barra ya puesta. */
.tl-mark-stem.up.aprobado   { background:linear-gradient(to top, rgba(8,145,178,0), var(--cyan) 85%); }
.tl-mark-stem.down.rechazado { background:linear-gradient(to bottom, rgba(224,48,48,0), var(--red) 85%); }

.tl-mark-dot {
 position:absolute; width:9px; height:9px; border-radius:50%;
 transform:translateX(-4.5px);
 /* Anillo para separarse del fondo + una sombra propia debajo — como un
    pin que se asienta sobre el riel, no un círculo pegado y plano. */
 box-shadow:0 0 0 3px var(--bg-card), 0 2px 3px rgba(0,0,0,0.22);
}
.tl-mark-dot.up   { bottom:82px; }
.tl-mark-dot.down { top:82px; }

.tl-mark-pill {
 position:absolute; height:20px; width:18px; transform:translateX(-9px);
 border-radius:10px;
 display:flex; align-items:center; justify-content:center; color:#fff;
}
.tl-mark-pill.up   { bottom:63px; }
.tl-mark-pill.down { top:63px; }

.tl-mark-badge {
 position:absolute; transform:translateX(-50%);
 min-width:15px; height:15px; padding:0 3px; border-radius:8px;
 color:#fff; font-size:0.5rem; font-weight:800;
 display:flex; align-items:center; justify-content:center;
 box-shadow:0 0 0 3px var(--bg-card), 0 2px 3px rgba(0,0,0,0.22);
}
.tl-mark-badge.up   { bottom:92px; }
.tl-mark-badge.down { top:92px; }

/* Color por resultado — mismo código que ya usa el resto del sitio:
 cian = aprobado (ver .propuesta-aprobar), rojo = rechazado. */
.tl-mark-dot.aprobado, .tl-mark-pill.aprobado, .tl-mark-badge.aprobado { background:var(--cyan); }
.tl-mark-dot.rechazado, .tl-mark-pill.rechazado, .tl-mark-badge.rechazado { background:var(--red); }
.tl-mark-pill.aprobado  { box-shadow:0 2px 5px rgba(8,145,178,0.4); }
.tl-mark-pill.rechazado { box-shadow:0 2px 5px rgba(224,48,48,0.4); }

/* ── Popover: mensaje de cluster o card congelada ── */
.tl-popover {
 position:absolute; inset:0; z-index:5;
 border-radius:var(--r2); background:var(--bg-card);
 display:flex; flex-direction:column; align-items:center; justify-content:center; padding:22px;
 opacity:0; pointer-events:none; transition:opacity .2s ease;
}
.tl-popover.is-open { opacity:1; pointer-events:auto; }
.tl-popover-body { display:flex; flex-direction:column; align-items:center; width:100%; }
.tl-cluster-msg { font-size:0.85rem; color:var(--t2); text-align:center; line-height:1.55; }
.tl-cluster-msg strong { font-size:1.15rem; }
.tl-cluster-msg.is-aprobado strong { color:var(--cyan); }
.tl-cluster-msg.is-rechazado strong { color:var(--red); }
.tl-frozen-tag { font-size:0.6rem; font-weight:700; letter-spacing:0.05em; color:var(--t3); text-transform:uppercase; margin-bottom:8px; text-align:center; }
.tl-frozen-badge {
 display:inline-flex; align-items:center; gap:5px;
 font-size:0.62rem; font-weight:800; letter-spacing:0.03em; text-transform:uppercase;
 padding:5px 13px; border-radius:20px; margin-bottom:12px; white-space:nowrap;
}
.tl-frozen-badge.is-aprobado { color:var(--cyan); background:var(--cyan-bg); }
.tl-frozen-badge.is-rechazado { color:var(--red); background:var(--red-bg); }
.tl-frozen-card { width:100%; max-width:260px; cursor:default; }
.tl-frozen-card:hover, .tl-frozen-card:active { transform:none !important; box-shadow:var(--neu-out) !important; }
/* La rechazada nunca pasó de verdad — se muestra apagada, para no
 confundirla con un estado real de la card (ver .tl-frozen-badge arriba,
 que ya lo deja explícito). */
.tl-frozen-card.tl-frozen-rechazada { opacity:0.62; filter:saturate(0.5); }
.tl-popover-hint { font-size:0.6rem; color:var(--t4); margin-top:14px; text-align:center; }
