/* css/perfil.css — perfil clásico, rediseño aprobado v1.
   Fuente de verdad: docs/prototipos/perfil-clasico-nuevo.html (APPROVED). El
   orden de bloques, las clases y los números salen del prototipo; los colores
   vienen de las custom properties de css/global.css (--morbo-*) para no abrir
   una segunda paleta. Los modales (visor de historias y visor de medios) viven
   al final, byte-equivalentes: son superficies de otro contrato. */

* { margin: 0; padding: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; }
html { -webkit-text-size-adjust: 100%; }
body { background: var(--morbo-bg); color: var(--morbo-text); min-height: 100dvh; }
img { display: block; }
a { color: inherit; }
button { font: inherit; cursor: pointer; }

/* ============ Barra superior: flecha + logo + portal inmersivo ============ */
.topbar {
    position: sticky; top: 0; z-index: 40;
    height: calc(env(safe-area-inset-top) + 58px);
    padding: calc(8px + env(safe-area-inset-top)) 14px 8px;
    display: flex; align-items: center;
    background: rgba(7, 7, 7, .92);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border-bottom: 1px solid rgba(255, 255, 255, .06);
}

.btn-back {
    width: 42px; height: 42px; flex: none;
    display: grid; place-items: center;
    color: #fff; transition: color .2s;
}

.btn-back:hover { color: var(--morbo-accent); }
.btn-back svg { width: 22px; height: 22px; }

.fila-marca { flex: 1; display: flex; justify-content: center; }
.fila-marca a { display: flex; align-items: center; text-decoration: none; }
.logo { height: 34px; width: auto; }

/* Portal a la vista inmersiva (coexistencia sellada con la inmersiva). */
.btn-inmersiva {
    width: 42px; height: 42px; flex: none;
    display: grid; place-items: center;
    color: #6b6b6b; transition: color .2s;
}

.btn-inmersiva:hover { color: var(--morbo-accent); }
.btn-inmersiva svg { width: 20px; height: 20px; }

/* Portal al panel (T3, decisión sellada #7): solo existe con sesión de escort
   (lo inyecta js/perfil.js cuando window.MORBO_SHELL.profile existe), así que
   hereda el tratamiento del portal inmersivo — 42px, tono tenue, acento al
   hover — en vez de abrir un tercer lenguaje en la barra. */
.btn-panel {
    width: 42px; height: 42px; flex: none;
    display: grid; place-items: center;
    color: #6b6b6b; transition: color .2s;
}

.btn-panel:hover { color: var(--morbo-accent); }
.btn-panel svg { width: 20px; height: 20px; }

/* ============ Montaje: la barra CTA fija reserva su alto ================== */
/* 76px = alto REAL de .cta-bar (botón 52px + 12px×2 de padding). Si cambia
   alguno de los dos, cambian AMBOS juntos (acá y en .cta-bar). */
#perfilDetalle { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
.perfil-estado { padding: 28px 16px; text-align: center; color: var(--morbo-text-muted); }

/* ============ Portada: la foto manda, identidad encima =================== */
/* Contenedor del navegador de medios (portada + galería). además de agrupar
   las dos piezas es el nodo de la apertura delegada y el que resuelve el foco
   al cerrar el visor (js/perfil.js). min-width:0 para que no desborde la
   columna del grid en desktop. */
.medios-perfil { min-width: 0; }
.col-media, .col-info { min-width: 0; }

.portada { position: relative; }

.portada img {
    width: 100%; height: min(72vh, 620px);
    object-fit: cover; object-position: center 20%;
    background: var(--morbo-surface);
}

.portada .scrim {
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(7, 7, 7, .25) 0%, rgba(7, 7, 7, 0) 35%, rgba(7, 7, 7, .92) 88%);
}

.identidad { position: absolute; left: 0; right: 0; bottom: 0; padding: 0 16px 14px; }

.identidad h1 {
    font-size: clamp(1.6rem, 6vw, 2.1rem); font-weight: 700; letter-spacing: -.02em;
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
}

/* Sello de verificación: esta página SÓLO carga perfiles en estado aprobado,
   así que declara un hecho (mismo criterio que la vista inmersiva). El punto
   verde "online" de la ficha vieja se retiró por completo: era una señal
   inventada (no existe el dato que la respalde). */
.verif {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12px; font-weight: 600; color: var(--morbo-accent); white-space: nowrap;
}

.verif svg { width: 15px; height: 15px; }

.membresia-badge {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11.5px; font-weight: 600; color: var(--morbo-on-accent);
    background: linear-gradient(135deg, var(--morbo-accent), #f3dfa0);
    padding: 4px 10px; border-radius: 999px;
}

.chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }

/* Chips de identidad. El de ubicación llega como <p> POR CONTRATO (#138: el
   bloque de ubicación vive dentro del guard Virtual con la forma exacta que
   pinea scripts/lib/og-imagen.test.mjs), así que comparte el estilo del chip. */
.chip, .chips p {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12.5px; font-weight: 500; color: var(--morbo-text-muted);
    padding: 6px 12px; border-radius: 999px;
    background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .10);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}

.chips p i { font-size: 12px; }

/* Entrada a las historias (sólo cuando el perfil tiene historias vivas). */
.chip-historia { color: var(--morbo-accent); border-color: rgba(229, 197, 91, .4); font-weight: 600; }
.chip-historia:hover { background: rgba(229, 197, 91, .12); }

/* ============ Resumen de decisión: precio + reseñas en una franja ======== */
.resumen { display: flex; align-items: stretch; gap: 8px; padding: 12px 16px 4px; }

.resumen .caja {
    flex: 1; min-width: 0;
    background: var(--morbo-surface); border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 14px; padding: 10px 12px;
}

/* El slot de reseñas se llena (o queda vacío) después del render: cuando no
   hay reseñas aprobadas la caja no existe y la de precio ocupa todo el ancho. */
.caja-slot { display: contents; }

.resumen .caja small {
    display: block; font-size: 10.5px; font-weight: 600; letter-spacing: .08em;
    text-transform: uppercase; color: #6b6b6b; margin-bottom: 4px;
}

.resumen .caja b { font-size: 14.5px; font-weight: 600; }
.resumen .caja.precio b { color: var(--morbo-accent); }
.resumen .caja a { text-decoration: none; color: var(--morbo-text-muted); font-size: 13px; }
.resumen .caja a b { color: var(--morbo-text); }
.resumen .caja a:hover b { color: var(--morbo-accent); }

/* ============ Bloques ==================================================== */
.bloque { padding: 14px 16px 0; }

/* Pulido de secciones (#perfil-polish): más aire entre secciones + divisor.
   El divisor es un hairline con degradado, alineado al contenido (16px, el
   mismo padding horizontal del bloque en móvil). Sólo separa secciones
   CONSECUTIVAS de la columna de información: portada/galería (col-media) y
   la caja de precio (.resumen) conservan su ritmo propio. El padding de
   .bloque no se toca: está pineado por tests (perfil-redes.test.mjs). */
.col-info > * + .bloque,
.col-info > * + .placa-redes {
    margin-top: 28px;
    position: relative;
}

.col-info > * + .bloque::before,
.col-info > * + .placa-redes::before {
    content: ""; position: absolute; top: 0; left: 16px; right: 16px;
    height: 1px;
    background: linear-gradient(90deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, .03));
}

.bloque h2 {
    font-size: 13px; font-weight: 600; letter-spacing: .08em;
    text-transform: uppercase; color: #6b6b6b; margin-bottom: 9px;
}

.descripcion { color: var(--morbo-text-soft); font-size: 14.5px; line-height: 1.55; overflow-wrap: anywhere; }

/* Clamp VISUAL de 3 líneas: el texto completo queda en el DOM (SEO y lectores
   de pantalla); JS jamás recorta el string. */
.descripcion.recortada { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }

.ver-mas {
    background: none; border: 0; color: var(--morbo-accent); font-size: 13px; font-weight: 600;
    padding: 6px 0 0;
}

/* ============ Calificaciones ============================================= */
.rating-linea { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rating-linea .nota { font-size: 2rem; font-weight: 700; }
.estrellas { color: var(--morbo-story-gold); font-size: 15px; letter-spacing: 2px; }
.estrellas .apagada { color: rgba(255, 255, 255, .18); }
.rating-linea .cuenta { color: var(--morbo-text-muted); font-size: 13px; }
.sin-resenas { color: var(--morbo-text-muted); font-size: 13.5px; }

.review-card {
    background: var(--morbo-surface); border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 14px; padding: 12px 14px; margin-top: 10px;
}

.review-card header { display: flex; align-items: center; gap: 8px; }
.review-card .quien { font-weight: 600; font-size: 14px; }
.review-card .cuando { color: #6b6b6b; font-size: 12px; margin-left: auto; }
.review-card .estrellas { font-size: 12px; letter-spacing: 1px; }
.review-card p { color: var(--morbo-text-muted); font-size: 13.5px; line-height: 1.5; margin-top: 6px; white-space: pre-wrap; }

.link-todas {
    display: inline-block; margin-top: 12px; padding: 6px 0;
    background: none; border: 0;
    color: var(--morbo-accent); font-size: 13.5px; font-weight: 600; text-decoration: none;
}

.form-review { margin-top: 16px; }

.form-review input, .form-review select, .form-review textarea {
    width: 100%; background: var(--morbo-surface); border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 10px; color: var(--morbo-text); font: inherit; font-size: 14px;
    padding: 10px 12px; margin-bottom: 8px;
}

.form-review textarea { min-height: 74px; resize: vertical; }

.form-review button {
    width: 100%; padding: 11px; border: 0; border-radius: 999px;
    background: #16161a; color: var(--morbo-text); font-weight: 600; font-size: 14px;
}

.form-review small { display: block; margin-top: 7px; color: #6b6b6b; font-size: 11.5px; }

/* ============ Galería densa ============================================== */
/* El grid NO duplica el padding del bloque (el prototipo lo tenía dos veces:
   .bloque 16px + .galeria 16px). Las celdas quedan alineadas con el resto de
   los bloques; el aspecto 3:4 es el del prototipo. */
.galeria { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }

.galeria .celda { aspect-ratio: 3 / 4; border-radius: 10px; overflow: hidden; background: var(--morbo-surface); cursor: pointer; }
.galeria img { width: 100%; height: 100%; object-fit: cover; }
.galeria .foto-galeria:hover { opacity: .92; }

/* ============ Tarifas y servicios ======================================== */
.fila-tarifa {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    padding: 10px 2px; border-bottom: 1px solid rgba(255, 255, 255, .06);
    font-size: 14.5px;
}

.fila-tarifa:last-child { border-bottom: 0; }
.fila-tarifa .t { color: #dcdcdc; }
.fila-tarifa .p { color: var(--morbo-accent); font-weight: 600; white-space: nowrap; }

.chips-servicios { display: flex; flex-wrap: wrap; gap: 7px; }
.chips-servicios .chip { background: var(--morbo-surface); }

/* ============ Mis plataformas (redes externas) =========================== */
/* La placa vive en el flujo de bloques, entre "Sobre mí" y Calificaciones
   (decisión sellada del dueño). El markup lo genera el componente COMPARTIDO
   de js/redes-externas.js — mismas clases que la vista inmersiva; acá lleva
   las métricas de .bloque y su escalón de h2, sin fondo (como el resto).
   Layout de dos tiers: VENTA = botón-card lleno con acento morbo y microcopy
   de beneficio; SOCIAL = botón tenue y compacto con el handle visible. Los
   íconos son monocromos (currentColor): el acento lo pone el botón, no la
   marca. */
.placa-redes { padding: 14px 16px 0; }

.placa-redes h2 {
    font-size: 13px; font-weight: 600; letter-spacing: .08em;
    text-transform: uppercase; color: #6b6b6b; margin-bottom: 9px;
}

.tier-redes { display: grid; gap: 8px; }
.tier-redes + .tier-redes { margin-top: 10px; }

.fila-redes {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 14px; text-decoration: none;
    border-radius: 14px;
}

/* Tier venta: lleno y prominente (altura táctil ≥44px), acento morbo. */
.fila-redes-venta {
    background: linear-gradient(135deg, var(--morbo-accent), #f3dfa0);
    color: #111;
}
.fila-redes-venta .icono-redes,
.fila-redes-venta .plataforma-redes { color: #111; }
.fila-redes-venta .micro-redes { color: rgba(0, 0, 0, .72); }
.fila-redes-venta .flecha-redes { color: rgba(0, 0, 0, .55); }

/* Tier social: tenue y compacto, el handle es el contenido. */
.fila-redes-social {
    background: var(--morbo-surface);
    border: 1px solid rgba(255, 255, 255, .10);
}
.fila-redes-social .icono-redes { color: var(--morbo-accent); }

.icono-redes { width: 22px; height: 22px; flex: none; display: grid; place-items: center; }
.icono-redes svg { width: 20px; height: 20px; }

.datos-redes { display: flex; flex-direction: column; min-width: 0; }
.plataforma-redes { font-size: 14.5px; font-weight: 600; color: var(--morbo-text); }
.micro-redes { font-size: 12.5px; line-height: 1.35; overflow-wrap: anywhere; }
.handle-redes { font-size: 12.5px; color: var(--morbo-text-muted); overflow-wrap: anywhere; }

.flecha-redes { margin-left: auto; flex: none; display: grid; place-items: center; transition: color .2s, transform .2s; }
.flecha-redes svg { width: 16px; height: 16px; }
.fila-redes:hover .flecha-redes { transform: translateX(2px); }
.fila-redes-venta:hover .flecha-redes { color: #111; }
.fila-redes-social:hover .flecha-redes { color: var(--morbo-accent); }

/* ============ Cierre: recorrido inmersivo ================================ */
.cierre-inmersiva {
    margin: 22px 16px 0;
    border: 1px dashed rgba(229, 197, 91, .4); border-radius: 14px;
    padding: 16px;
    display: flex; align-items: center; gap: 12px;
    color: var(--morbo-text-muted); font-size: 13.5px;
    text-decoration: none;
}

.cierre-inmersiva svg { width: 22px; height: 22px; color: var(--morbo-accent); flex: none; }
.cierre-inmersiva b { color: var(--morbo-text); display: block; font-size: 14.5px; }

footer { padding: 20px 16px calc(20px + env(safe-area-inset-bottom)); color: #6b6b6b; font-size: 11.5px; text-align: center; }

/* ============ Barra CTA fija: el contacto siempre a un tap =============== */
/* z-index 900: debajo de cualquier overlay full-screen (visor de historias
   5000, visor de medios 6000). */
.cta-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
    display: flex; gap: 10px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: linear-gradient(0deg, rgba(7, 7, 7, .97) 65%, rgba(7, 7, 7, 0));
}

/* Ocultación de la barra detrás de un overlay full-screen. Selector COMPUESTO
   a propósito: .cta-bar tiene display:flex y un selector suelto
   .oculto-por-visor perdería la cascada contra él (bug de revisión previo). */
.cta-bar.oculto-por-visor { display: none; }

/* ============ Contenido entre las dos barras (T2, decisión #6) ============ */
/* Con sesión de escort, js/escort-shell.js pone `.escort-shell` en <body> y el
   kit (css/escort-ui.css) pinta la nav inferior: 45px (--escort-nav-h) MÁS la
   safe-area que la barra agrega por su cuenta. La CTA se sube ENCIMA de la nav
   (ni la tapa ni queda tapada) y la reserva del contenido crece el mismo alto,
   para que el cierre legal y el último bloque no terminen detrás de la barra.
   La nav del kit se oculta desde 768px, así que los offsets viven en el rango
   móvil: en desktop la barra conserva su bottom:18px y la columna su aire. */
@media (max-width: 767px) {
    body.escort-shell .cta-bar {
        bottom: calc(var(--escort-nav-h, 45px) + env(safe-area-inset-bottom, 0px));
        /* La safe-area la aporta la nav: la barra no la suma dos veces. */
        padding-bottom: 12px;
    }

    /* Fix 3 (dueño, 2026-10 — "Calificaciones pegadas al bottom nav"): la
       reserva de antes medía EXACTAMENTE el chrome fijo (76px reales de la
       barra CTA + el alto de la nav), así que la página terminaba donde empieza
       la barra: cero aire. El cierre del perfil — el bloque de Calificaciones
       cuando el perfil no tiene tarifas ni servicios, el cierre inmersivo y el
       pie legal — se leía pegado a la barra inferior.
       Ahora la página reserva, ADEMÁS del chrome, el alto REAL de la nav
       (--escort-nav-h + safe-area: la misma aritmética de los offsets de
       .cta-bar) como aire de cierre. Cada capa se cuenta una sola vez: los
       76px de la barra, el alto de la nav que la barra ocupa y el mismo alto
       otra vez como respiro final. La safe-area entra una única vez (la aporta
       la nav con su propio padding). */
    body.escort-shell #perfilDetalle {
        padding-bottom: calc(
            76px + var(--escort-nav-h, 45px) * 2 + env(safe-area-inset-bottom)
        );
    }
}

/* Los anchors llevan TAMBIÉN las clases legacy .btn.whatsapp / .btn.llamar:
   esos SELECTORES son el contrato del wiring de analítica (no editables desde
   este slice) y el estilo es el del prototipo, en .btn-whatsapp/.btn-llamar.
   Por eso no hay regla para .btn/.whatsapp/.llamar: son ganchos, no diseño. */
.btn-whatsapp {
    flex: 1; min-height: 52px;
    display: flex; align-items: center; justify-content: center; gap: 9px;
    border-radius: 999px;
    background: var(--morbo-accent); color: #111;
    font-weight: 700; font-size: 15px; text-decoration: none;
    box-shadow: 0 10px 34px rgba(229, 197, 91, .25);
    transition: transform .15s, background .2s;
}

.btn-whatsapp:active { transform: scale(.98); }
.btn-whatsapp svg { width: 19px; height: 19px; }

.btn-llamar {
    width: 52px; min-height: 52px; flex: none;
    display: grid; place-items: center;
    border-radius: 999px;
    background: #16161a; border: 1px solid rgba(255, 255, 255, .10);
    color: #fff; text-decoration: none;
}

.btn-llamar svg { width: 19px; height: 19px; }

/* ============ Desktop: dos columnas ===================================== */
@media (min-width: 900px) {
    .layout {
        max-width: 1160px; margin: 0 auto;
        display: grid; grid-template-columns: minmax(0, 7fr) minmax(320px, 5fr); gap: 28px;
        padding: 24px 28px;
    }

    .col-media { min-width: 0; }
    .portada img { height: min(78vh, 700px); border-radius: 20px; }
    .portada .scrim { display: none; }
    .identidad { position: static; padding: 16px 0 0; }
    .resumen { padding: 16px 0 0; }
    .bloque, .placa-redes { padding: 14px 0 0; }

    /* El divisor (ver "Pulido de secciones") a ancho completo de columna:
       en desktop los bloques no tienen padding horizontal. */
    .col-info > * + .bloque,
    .col-info > * + .placa-redes { margin-top: 24px; }
    .col-info > * + .bloque::before,
    .col-info > * + .placa-redes::before { left: 0; right: 0; }
    .galeria { grid-template-columns: repeat(4, 1fr); }
    .cierre-inmersiva { display: none; }
    .cta-bar {
        left: 50%; transform: translateX(-50%); width: min(680px, 92vw);
        bottom: 18px;
        background: none; padding: 0;
    }
    .btn-whatsapp { box-shadow: 0 14px 40px rgba(0, 0, 0, .5); }
    footer { padding: 20px 0; text-align: left; }
}

/* Historias dentro del perfil */
/* Fix 4 (dueño, 2026-10): el visor es un modal full-screen LIMPIO. El fondo
   pasa de rgba(0,0,0,.97) a negro opaco: con el 3% de transparencia la nav
   inferior del shell (z-index 900, con el FAB dorado) y la fila de historias
   se seguían viendo por debajo del visor. z-index 5000 lo deja por encima de
   cualquier chrome de página (topbar 40, CTA y nav 900) y por debajo del visor
   de medios (6000), que es una superficie distinta y nunca se abre a la vez
   (ver tapEnIdentidad en js/perfil.js). */
.perfil-story-viewer{position:fixed;inset:0;z-index:5000;background:#000;display:grid;place-items:center;padding:20px}
.perfil-story-viewer.oculto{display:none}
.perfil-story-content{position:relative;width:min(430px,100%);height:min(760px,82vh);display:grid;place-items:center;/* Pulsación sostenida: apoyar el dedo ~250ms pausa la historia, así que el long-press no puede volverse selección ni menú nativo del medio. */user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.perfil-story-content img,.perfil-story-content video{max-width:100%;max-height:100%;border-radius:16px;object-fit:contain}
.perfil-story-close{position:fixed;right:22px;top:14px;z-index:6;background:none;border:0;color:#fff;font-size:42px;cursor:pointer}
.perfil-story-progress{position:fixed;top:12px;left:50%;transform:translateX(-50%);width:min(430px,70vw);display:flex;gap:4px;z-index:5}
.perfil-story-progress span{flex:1;height:4px;background:rgba(255,255,255,.32);border-radius:99px;overflow:hidden}
.perfil-story-progress span.completado{background:#fff}
.perfil-story-progress i{display:block;width:0;height:100%;background:#fff}.perfil-story-progress i.animando{animation:perfilStoryProgressFill var(--story-duration,7000ms) linear forwards}@keyframes perfilStoryProgressFill{from{width:0}to{width:100%}}
/* Pausa del video = tiempo congelado: la barra se frena donde estaba. */
.perfil-story-progress i.pausado{animation-play-state:paused}
/* Altavoz accesible del video de la historia (defecto del dueño 2026-10):
   "el mismo concepto" que el feed y que el visor del catálogo — 44px de toque,
   arriba a la izquierda del marco del medio, sube sobre las franjas invisibles
   de navegación de mobile (que son de 45% de ancho) y sobre el bloque de autor. */
.perfil-story-sonido{position:absolute;top:96px;left:12px;z-index:6;width:44px;height:44px;display:grid;place-items:center;padding:0;border:1px solid rgba(255,255,255,.24);border-radius:999px;background:rgba(7,7,7,.62);backdrop-filter:blur(8px);color:#fff;font-size:1rem;cursor:pointer;transition:background .2s,color .2s,border-color .2s}
.perfil-story-sonido:hover{border-color:rgba(255,255,255,.45)}
.perfil-story-sonido:active{transform:scale(.92)}
/* Estado "se escucha": el botón se enciende (control de estado, no reacción). */
.perfil-story-sonido.activo{background:rgba(255,255,255,.93);border-color:#fff;color:#0b0b0d}
.perfil-story-author{position:fixed;top:28px;left:50%;transform:translateX(-50%);width:min(430px,70vw);z-index:4;display:flex;align-items:center;gap:10px;padding:10px 44px 8px 4px;color:#fff;text-decoration:none;background:linear-gradient(180deg,rgba(0,0,0,.72),transparent);border-radius:12px 12px 0 0}
.perfil-story-author img{width:38px;height:38px;min-width:38px;border-radius:50%;object-fit:cover;border:2px solid rgba(255,255,255,.9)}
.perfil-story-author span{display:flex;flex-direction:column;min-width:0}.perfil-story-author strong{font-size:.93rem;line-height:1.15}.perfil-story-author small{font-size:.72rem;color:rgba(255,255,255,.72);margin-top:3px}
.perfil-story-nav{position:fixed;top:50%;transform:translateY(-50%);z-index:3;width:48px;height:76px;border:0;border-radius:14px;background:rgba(0,0,0,.38);color:#fff;font-size:34px;cursor:pointer;display:grid;place-items:center}.perfil-story-nav:disabled{opacity:.18}.perfil-story-prev{left:max(18px,calc(50% - 280px))}.perfil-story-next{right:max(18px,calc(50% - 280px))}
@media(max-width:600px){.perfil-story-viewer{padding:0}.perfil-story-content{height:100vh;width:100vw}.perfil-story-content img,.perfil-story-content video{border-radius:0}.perfil-story-progress,.perfil-story-author{width:calc(100vw - 28px)}.perfil-story-author{top:25px}.perfil-story-close{right:14px}.perfil-story-nav{opacity:0;width:45%;height:78vh;background:transparent}.perfil-story-prev{left:0}.perfil-story-next{right:0}}
/* S4a (odd/tasks/perfil-ui-redesign): visor de medios — overlay a pantalla
   completa con TODOS los medios en una columna vertical, UNA foto por
   pantalla sin recorte: cada slide mide exactamente 100dvh (la geometría no
   depende de que las imágenes hayan cargado) y la imagen vive en contain
   (nunca recortada, nunca estirada). El scroll es vertical con snap
   mandatory y overscroll-behavior contain (el fondo ni el propio visor se
   scrollean de más). Vive sobre el visor de historias (5000). */
.visor-medios{--visor-peek:72px;position:fixed;inset:0;z-index:6000;background:#000}
.visor-medios.oculto{display:none}
.visor-medios-pila{width:100%;height:100dvh;overflow-y:auto;scroll-snap-type:y mandatory;overscroll-behavior:contain;touch-action:pan-y}
.visor-medios-item{width:100%;height:calc(100dvh - var(--visor-peek));display:grid;place-items:center;scroll-snap-align:start;scroll-snap-stop:always}
.visor-medios-img{display:block;max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}
.visor-medios-contador{position:fixed;top:14px;left:50%;transform:translateX(-50%);z-index:6010;padding:6px 14px;border-radius:999px;background:rgba(0,0,0,.6);color:#fff;font-size:14px;font-weight:600;line-height:1.4;pointer-events:none}
.visor-medios-cerrar{position:fixed;top:10px;right:12px;z-index:6020;width:44px;height:44px;min-width:44px;min-height:44px;border:0;border-radius:50%;background:rgba(0,0,0,.6);color:#fff;font-size:24px;line-height:1;cursor:pointer;display:grid;place-items:center}
.visor-medios-cerrar:hover{background:rgba(0,0,0,.85)}
.visor-medios-siguiente{position:fixed;bottom:18px;right:12px;z-index:6020;width:48px;height:48px;min-width:48px;min-height:48px;border:0;border-radius:50%;background:rgba(0,0,0,.6);color:#fff;cursor:pointer;padding:0;display:grid;place-items:center}
.visor-medios-siguiente:hover{background:rgba(0,0,0,.85)}
.visor-medios-siguiente[hidden]{display:none}
.visor-medios-pista{position:fixed;bottom:26px;left:50%;transform:translateX(-50%);z-index:6010;max-width:calc(100% - 130px);padding:8px 16px;border-radius:999px;background:rgba(0,0,0,.72);color:#fff;font-size:13px;font-weight:600;line-height:1.4;text-align:center;pointer-events:none;opacity:1;transition:opacity .3s ease}
.visor-medios-pista[hidden]{display:none}
@media (prefers-reduced-motion: reduce){.visor-medios-pista{transition:none}}


/* Corrección: el encabezado del visor no queda cubierto por la navegación. */
.perfil-story-progress{z-index:30}
.perfil-story-author{z-index:40;pointer-events:auto}
.perfil-story-author *{pointer-events:auto}
.perfil-story-close{z-index:50}
.perfil-story-nav{
  top:86px;
  bottom:0;
  height:auto;
  transform:none;
  align-items:center;
}
@media(max-width:600px){
  .perfil-story-nav{
    top:86px;
    bottom:0;
    height:auto;
  }
}
