/* ==========================================================================
   MiOrigo — hoja de estilos única

   MARCA: luminosa. Fondo casi blanco con un velo frío, tarjetas blancas
   flotando sobre él y un turquesa vivo como acento. El sexo se lee por color
   (azul / rosa, como en las aplicaciones de genealogía al uso) y la LÍNEA
   DIRECTA del usuario se tiñe para distinguir la sangre propia de las ramas
   políticas de un vistazo.

   Todo lo interactivo responde: elevación al pasar el ratón, transiciones
   cortas y entrada animada de los nodos.
   ========================================================================== */

:root {
    /* Superficies */
    --fondo:        #f4f7fa;
    --fondo-2:      #eaeff5;
    --papel:        #ffffff;
    --papel-2:      #f8fafc;

    /* Texto */
    --tinta:        #17222e;
    --tinta-suave:  #56677c;
    --tinta-tenue:  #8b9bb0;

    /* Acento de marca */
    --acento:       #0eA5a4;
    --acento-vivo:  #14c8c4;
    --acento-hondo: #0b7f7e;
    --acento-velo:  #dcfbf8;

    /* Secundario cálido */
    --ambar:        #f59e0b;
    --ambar-hondo:  #b45309;
    --ambar-velo:   #fef3c7;

    /* Sexos */
    --varon:        #3b82f6;
    --varon-velo:   #e8f1ff;
    --mujer:        #ec4899;
    --mujer-velo:   #fdeaf4;
    --neutro:       #94a3b8;
    --neutro-velo:  #eef2f7;

    --borde:        #dde5ee;
    --borde-fuerte: #c3d0e0;
    --rojo:         #e11d48;
    --rojo-velo:    #ffe4e9;

    --sombra-1: 0 1px 2px rgba(23, 34, 46, .05), 0 2px 6px rgba(23, 34, 46, .05);
    --sombra-2: 0 4px 10px rgba(23, 34, 46, .08), 0 12px 28px rgba(23, 34, 46, .09);
    --sombra-3: 0 10px 24px rgba(23, 34, 46, .12), 0 24px 56px rgba(23, 34, 46, .12);
    --sombra-acento: 0 6px 18px rgba(14, 165, 164, .28);

    --radio:    14px;
    --radio-s:  9px;

    --fuente: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
    --fuente-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

    --curva: cubic-bezier(.22, 1, .36, 1);
}

:root[data-tema="oscuro"] {
    --fondo:        #0f1720;
    --fondo-2:      #131c27;
    --papel:        #18222e;
    --papel-2:      #1e2937;
    --tinta:        #e9eef4;
    --tinta-suave:  #a3b2c4;
    --tinta-tenue:  #71829a;
    --acento-velo:  #0d3b3a;
    --varon-velo:   #14263f;
    --mujer-velo:   #35162a;
    --neutro-velo:  #212c3a;
    --ambar-hondo:  #fbbf24;
    --ambar-velo:   #3a2f10;
    --borde:        #2a3846;
    --borde-fuerte: #3b4c5e;
    --rojo-velo:    #3a1520;
    --sombra-1: 0 1px 2px rgba(0,0,0,.3), 0 2px 6px rgba(0,0,0,.25);
    --sombra-2: 0 4px 10px rgba(0,0,0,.4), 0 12px 28px rgba(0,0,0,.35);
    --sombra-3: 0 10px 24px rgba(0,0,0,.5), 0 24px 56px rgba(0,0,0,.45);
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--fondo);
    color: var(--tinta);
    font-family: var(--fuente-ui);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: var(--fuente); font-weight: 600; line-height: 1.22; margin: 0 0 .5em; letter-spacing: -.015em; }
h1 { font-size: 2.5rem; }
h2 { font-size: 1.75rem; }
h3 { font-size: 1.22rem; }

a { color: var(--acento-hondo); text-decoration: none; }
a:hover { text-decoration: underline; }

.contenedor { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 24px; }
.contenedor-estrecho { width: 100%; max-width: 620px; margin: 0 auto; padding: 0 24px; }

/* Los anchos de página, como CLASES y no escritos a mano en cada vista.
   ⚠️ Un `style="max-width:900px"` en la plantilla gana a cualquier regla de
   esta hoja —los estilos en línea siempre ganan—, así que el tope de «no más
   ancho que la ventana» no había forma de aplicarlo: /ajustes se estiraba a
   581 px dentro de un móvil de 360. Aquí se declaran una vez y se pueden
   acotar por pantalla. */
.ancho-medio   { max-width: 940px; }
.ancho-angosto { max-width: 820px; }
.ancho-lectura { max-width: 720px; }
.ancho-corto   { max-width: 640px; }

/* En un móvil, 24 px por cada lado son 48 px de los 360 que hay. */
@media (max-width: 560px) {
    .contenedor, .contenedor-estrecho { padding-left: 16px; padding-right: 16px; }
}

/* ── Cabecera ─────────────────────────────────────────────────────────── */

.cabecera {
    position: sticky; top: 0; z-index: 40;
    display: flex; align-items: center; gap: 20px;
    padding: 12px 24px;
    background: color-mix(in srgb, var(--papel) 82%, transparent);
    backdrop-filter: saturate(1.8) blur(14px);
    border-bottom: 1px solid var(--borde);
}

.marca {
    display: inline-flex; align-items: center; gap: 9px;
    font-family: var(--fuente); font-size: 1.28rem; font-weight: 600;
    color: var(--tinta); letter-spacing: -.02em;
}
.marca:hover { text-decoration: none; }
.marca svg { width: 27px; height: 27px; color: var(--acento); transition: transform .4s var(--curva); }
.marca:hover svg { transform: rotate(-8deg) scale(1.08); }

.nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav a {
    padding: 7px 14px; border-radius: 20px;
    color: var(--tinta-suave); font-size: .93rem; font-weight: 500;
    transition: background .18s var(--curva), color .18s var(--curva);
}
.nav a:hover { background: var(--fondo-2); color: var(--tinta); text-decoration: none; }
/* Un botón dentro de la barra conserva su color (el gris de los enlaces lo dejaba ilegible). */
.nav a.boton, .nav a.boton:hover { color: #fff; }
.nav a.boton:hover { background: var(--acento-vivo); }
/* La barra pública tiene tres enlaces y no se desliza: sin el difuminado de los bordes. */
.cabecera-publica .nav { -webkit-mask-image: none; mask-image: none; overflow: visible; }
.nav a.activo { color: var(--acento-hondo); background: var(--acento-velo); }

/* ── Botones ──────────────────────────────────────────────────────────── */

.boton {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 11px 22px; border: 1px solid transparent; border-radius: 24px;
    font-family: var(--fuente-ui); font-size: .95rem; font-weight: 600;
    cursor: pointer; text-decoration: none;
    background: var(--acento); color: #fff;
    transition: transform .16s var(--curva), background .18s, box-shadow .22s var(--curva);
}
.boton:hover {
    background: var(--acento-vivo); text-decoration: none;
    transform: translateY(-2px); box-shadow: var(--sombra-acento);
}
.boton:active { transform: translateY(0) scale(.98); }
.boton.secundario { background: var(--papel); color: var(--tinta); border-color: var(--borde-fuerte); }
.boton.secundario:hover { background: var(--papel-2); border-color: var(--acento); color: var(--acento-hondo); box-shadow: var(--sombra-2); }
.boton.peligro { background: var(--rojo); }
.boton.pequeno { padding: 7px 15px; font-size: .86rem; }
.boton:disabled { opacity: .45; cursor: not-allowed; transform: none; box-shadow: none; }

/* ── Formularios ──────────────────────────────────────────────────────── */

.campo { margin-bottom: 17px; }
.campo label,
/* Los campos que monta el JS son <label class="campo"><span>rótulo</span>…,
   porque el propio label envuelve al control y no puede llevar otro dentro. */
.campo > span { display: block; margin-bottom: 6px; font-size: .87rem; font-weight: 600; color: var(--tinta-suave); }
.campo input, .campo select, .campo textarea {
    width: 100%; padding: 11px 14px;
    background: var(--papel); color: var(--tinta);
    border: 1px solid var(--borde-fuerte); border-radius: var(--radio-s);
    font-family: var(--fuente-ui); font-size: .97rem;
    transition: border-color .16s, box-shadow .16s;
}
.campo input:focus, .campo select:focus, .campo textarea:focus {
    outline: none; border-color: var(--acento);
    box-shadow: 0 0 0 4px var(--acento-velo);
}
/* ⚠️ `.ayuda` vale en CUALQUIER sitio, no solo dentro de un `.campo`. Estaba
   escrita como `.campo .ayuda`, así que una nota puesta fuera —bajo un grupo de
   opciones, al pie de un paso— salía con el cuerpo de un párrafo normal y
   competía con el texto de verdad en vez de acompañarlo. */
.ayuda { margin-top: 5px; font-size: .82rem; color: var(--tinta-tenue); }
.campos-fila { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* ── Avisos ───────────────────────────────────────────────────────────── */

.aviso {
    padding: 13px 17px; margin-bottom: 20px;
    border-radius: var(--radio-s); border-left: 3px solid var(--acento);
    background: var(--acento-velo); color: var(--tinta); font-size: .93rem;
}
.aviso.error { border-left-color: var(--rojo); background: var(--rojo-velo); }

/* ── Tarjetas ─────────────────────────────────────────────────────────── */

.tarjeta {
    padding: 24px; background: var(--papel);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-1);
    transition: box-shadow .25s var(--curva), transform .25s var(--curva);
}
.tarjeta:hover { box-shadow: var(--sombra-2); }

.panel-acceso {
    max-width: 440px; margin: 60px auto;
    padding: 36px; background: var(--papel);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-3);
    animation: subir .5s var(--curva) both;
}
.panel-acceso h1 { font-size: 1.7rem; margin-bottom: 6px; }
.panel-acceso .sub { color: var(--tinta-suave); margin-bottom: 26px; font-size: .95rem; }

@keyframes subir { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ── Landing ──────────────────────────────────────────────────────────── */

.heroe {
    position: relative; padding: 90px 0 66px; text-align: center; overflow: hidden;
}
.heroe::before {
    content: ""; position: absolute; inset: -40% 20% auto; height: 460px;
    background: radial-gradient(ellipse at center, var(--acento-velo), transparent 65%);
    opacity: .8; pointer-events: none;
}
.heroe > * { position: relative; }
.heroe h1 { font-size: 3.5rem; margin-bottom: 18px; }
.heroe h1 em { font-style: normal; color: var(--acento-hondo); }
.heroe .entradilla {
    max-width: 630px; margin: 0 auto 34px;
    font-size: 1.18rem; color: var(--tinta-suave); line-height: 1.65;
}
.heroe .acciones { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.heroe .tiendas { margin-top: 22px; display: flex; justify-content: center; }
.insignia-app-store { display: inline-flex; border-radius: 9px; }
.insignia-app-store img { display: block; width: auto; }
.como-app .tiendas { display: none; }
/* iPhone fuera de la app: la insignia manda y la web queda como nota. */
.heroe .acciones-iphone { align-items: center; }
.tambien-web { margin-top: 18px; text-align: center; font-size: .95rem; color: var(--tinta-suave); }
.tambien-web a { color: var(--acento-hondo); font-weight: 600; }
/* Android: cómo apuntarse a la prueba cerrada (portada y /android). */
.mb-prueba { margin-bottom: 40px; }
.prueba-android { text-align: left; scroll-margin-top: 80px; }
.prueba-android h2 { font-size: 1.45rem; margin: 10px 0 12px; }
.prueba-android h3 { font-size: 1.08rem; margin: 22px 0 8px; }
.prueba-android p { color: var(--tinta-suave); line-height: 1.6; }
.etiqueta-prueba {
    display: inline-block; padding: 4px 10px; border-radius: 999px;
    background: var(--acento-velo); color: var(--acento-hondo);
    font-size: .78rem; font-weight: 700; letter-spacing: .02em;
}
.pasos-prueba { margin: 18px 0 0; padding-left: 22px; display: grid; gap: 14px; }
.pasos-prueba li { line-height: 1.55; }
.pasos-prueba .boton { display: flex; width: fit-content; margin-top: 8px; }
.mientras-prueba { margin: 0; padding-left: 20px; display: grid; gap: 8px; line-height: 1.5; }
.nota-prueba { margin-top: 18px; font-size: .9rem; }

.franja-datos {
    display: flex; justify-content: center; gap: 52px; flex-wrap: wrap;
    padding: 30px 0; margin: 44px 0;
    border-top: 1px solid var(--borde); border-bottom: 1px solid var(--borde);
}
.dato { text-align: center; }
.dato .cifra { font-family: var(--fuente); font-size: 2.05rem; font-weight: 600; color: var(--acento-hondo); }
.dato .etiqueta { font-size: .82rem; color: var(--tinta-tenue); text-transform: uppercase; letter-spacing: .07em; }

.rejilla-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(265px, 1fr)); gap: 24px; margin: 50px 0; }
.caracteristica {
    padding: 28px; border: 1px solid var(--borde); border-radius: var(--radio);
    background: var(--papel); box-shadow: var(--sombra-1);
    transition: transform .28s var(--curva), box-shadow .28s var(--curva);
}
.caracteristica:hover { transform: translateY(-4px); box-shadow: var(--sombra-2); }
.caracteristica .icono {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin-bottom: 15px;
    border-radius: 12px; background: var(--acento-velo); color: var(--acento-hondo);
}
.caracteristica h3 { margin-bottom: 6px; }
.caracteristica p { margin: 0; color: var(--tinta-suave); font-size: .94rem; }

.pie {
    margin-top: 76px; padding: 34px 0;
    border-top: 1px solid var(--borde);
    color: var(--tinta-tenue); font-size: .88rem;
}
.pie .contenedor { display: flex; gap: 20px; flex-wrap: wrap; align-items: center; }
.pie a { color: var(--tinta-suave); }

/* «Un proyecto de Binaria Labs»: con la imagen de Binaria, no la de MiOrigo,
   así que los colores van fijos y no cambian con el tema. */
.pie-binaria {
    display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
    color: var(--tinta-tenue); font-size: .82rem;
}
.pie .pie-binaria { margin-left: auto; }
.pie a.firma-binaria, .firma-binaria {
    display: inline-flex; align-items: center; gap: 7px;
    background: #0F1115; color: #E8EAF0; border-radius: 8px; padding: 4px 9px;
    text-decoration: none; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 700; font-size: .8rem; letter-spacing: .01em;
}
.firma-binaria svg { width: 13px; height: 13px; flex: none; }
.firma-binaria b { color: #C6F432; font-weight: 700; }
.ml-pie .pie-binaria { display: flex; justify-content: center; margin-top: 12px; }
.ml-usuario a { color: inherit; text-decoration: none; }
.ml-usuario a:hover { color: var(--acento-hondo); }

/* ── Lienzo del árbol ─────────────────────────────────────────────────── */

body.pantalla-arbol { overflow: hidden; }

.arbol-pantalla { display: flex; height: 100%; min-height: 0; }

.lienzo-envoltorio {
    position: relative; flex: 1; overflow: hidden;
    background:
        radial-gradient(circle at 1px 1px, var(--borde-fuerte) 1px, transparent 0) 0 0 / 26px 26px,
        linear-gradient(180deg, var(--fondo) 0%, var(--fondo-2) 100%);
    cursor: grab;
}
.lienzo-envoltorio.arrastrando { cursor: grabbing; }
.lienzo-envoltorio.arrastrando #lienzo { transition: none !important; }

#lienzo { position: absolute; inset: 0; transform-origin: 0 0; will-change: transform; }
#lienzo.suave { transition: transform .5s var(--curva); }
#conexiones { position: absolute; inset: 0; overflow: visible; pointer-events: none; }

/* Tarjeta de persona */
.nodo {
    position: absolute;
    width: 178px;
    /* Altura fija: todas las tarjetas de una misma generación miden lo mismo,
       tengan o no apellidos o fechas. 82 px es lo que ocupa la tarjeta llena
       (nombre + apellidos + años); las incompletas se rellenan con el hueco.
       Además el layout dibuja las líneas suponiendo esta altura exacta: si la
       tarjeta encogía por falta de datos, la línea quedaba despegada. */
    min-height: 82px;
    display: flex; flex-direction: column; justify-content: center;
    padding: 10px 13px 10px 15px;
    background: var(--papel);
    border: 1.5px solid var(--borde-fuerte);
    border-radius: 12px;
    box-shadow: var(--sombra-1);
    cursor: pointer;
    user-select: none;
    animation: aparecerNodo .34s var(--curva) both;
    transition: box-shadow .2s var(--curva), transform .2s var(--curva),
                border-color .2s var(--curva), background .2s;
}
@keyframes aparecerNodo { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }

.nodo:hover {
    box-shadow: var(--sombra-2);
    transform: translateY(-3px) scale(1.02);
    z-index: 5;
}

/* Color por sexo: el borde y la franja lateral */
.nodo.sexo-H { border-color: color-mix(in srgb, var(--varon) 45%, var(--borde)); }
.nodo.sexo-M { border-color: color-mix(in srgb, var(--mujer) 45%, var(--borde)); }
.nodo.sexo-H:hover { border-color: var(--varon); }
.nodo.sexo-M:hover { border-color: var(--mujer); }

.nodo .franja-sexo {
    position: absolute; left: 0; top: 10px; bottom: 10px; width: 4px; border-radius: 0 4px 4px 0;
    background: var(--neutro);
}
.nodo.sexo-H .franja-sexo { background: var(--varon); }
.nodo.sexo-M .franja-sexo { background: var(--mujer); }

/* Línea directa: sangre propia teñida, como en las apps de genealogía */
.nodo.linea-ascendiente  { background: linear-gradient(180deg, var(--papel) 55%, var(--acento-velo)); }
.nodo.linea-descendiente { background: linear-gradient(180deg, var(--papel) 55%, var(--ambar-velo)); }

.nodo.foco {
    /* El resalte va por fuera con outline: engordar el borde sumaba 2 px de
       alto y descuadraba la tarjeta respecto a sus hermanas de fila. */
    border-color: var(--acento);
    outline: 1px solid var(--acento);
    outline-offset: -2px;
    box-shadow: 0 0 0 5px var(--acento-velo), var(--sombra-2);
}
.nodo.ego { border-color: var(--ambar); }
.nodo.ego::after {
    content: "tú"; position: absolute; top: -10px; right: 9px;
    padding: 1px 9px; border-radius: 20px;
    background: var(--ambar); color: #fff;
    font-size: .66rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    box-shadow: 0 2px 6px rgba(245, 158, 11, .4);
}
.nodo.resaltado {
    border-color: var(--acento) !important;
    box-shadow: 0 0 0 5px var(--acento-velo), var(--sombra-2);
    animation: latido 1.6s ease-in-out 2;
}
@keyframes latido {
    0%, 100% { box-shadow: 0 0 0 5px var(--acento-velo), var(--sombra-2); }
    50%      { box-shadow: 0 0 0 11px transparent, var(--sombra-2); }
}
/* Al buscar, lo que no encaja se apaga */
.lienzo-envoltorio.filtrando .nodo { opacity: .28; filter: saturate(.4); }
.lienzo-envoltorio.filtrando .nodo.coincide { opacity: 1; filter: none; }

.nodo .nombre {
    font-family: var(--fuente); font-size: .96rem; font-weight: 600;
    line-height: 1.24; margin-bottom: 2px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nodo .apellidos {
    font-size: .8rem; color: var(--tinta-suave); line-height: 1.24;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nodo .anios { margin-top: 4px; font-size: .76rem; color: var(--tinta-tenue); font-variant-numeric: tabular-nums; }

/* Indicador de persona que enlaza por varias ramas */
.marca-ramas {
    position: absolute; right: 7px; bottom: 7px;
    display: inline-flex; align-items: center; gap: 3px;
    padding: 1px 7px; border-radius: 20px;
    background: var(--ambar-velo); color: #b45309;
    border: 1px solid color-mix(in srgb, var(--ambar) 40%, transparent);
    font-size: .68rem; font-weight: 700;
    cursor: pointer; transition: all .18s var(--curva);
}
.marca-ramas:hover { background: var(--ambar); color: #fff; transform: scale(1.12); }
/* Rama desplegada en el lienzo: la marca queda encendida para que se sepa de
   dónde ha salido esa otra familia que ahora se ve. */
.marca-ramas.abierta {
    background: var(--ambar); color: #fff;
    border-color: var(--ambar);
}

/* Barra del modal de ramas: la acción de traerlas al árbol. */
.ramas-barra {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    margin-bottom: 14px; padding: 10px 12px;
    border: 1px solid var(--borde); border-radius: 10px;
    background: var(--papel-2);
}
.ramas-nota { font-size: .82rem; color: var(--tinta-suave); flex: 1 1 200px; }

/* Flechas de expansión */
.expandir {
    position: absolute; left: 50%;
    display: flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; border-radius: 50%;
    background: var(--papel); border: 1.5px solid var(--borde-fuerte);
    color: var(--acento-hondo); font-size: .68rem; line-height: 1;
    cursor: pointer; box-shadow: var(--sombra-1);
    transform: translateX(-50%);
    transition: all .2s var(--curva);
}
.expandir:hover {
    background: var(--acento); color: #fff; border-color: var(--acento);
    transform: translateX(-50%) scale(1.18);
    box-shadow: var(--sombra-acento);
}
.expandir.arriba { top: -12px; }
.expandir.abajo  { bottom: -12px; }

/* Líneas de parentesco */
.linea { fill: none; stroke: var(--borde-fuerte); stroke-width: 1.6; transition: stroke .25s, stroke-width .25s; }
.linea.union { stroke: var(--ambar); stroke-width: 2.2; }
.linea.camino { stroke: var(--acento); stroke-width: 3.4; }

/* Rombo en mitad de cada vínculo: con dos parejas, una a cada lado, es lo que
   distingue DOS matrimonios de una sola barra que cruza a los tres. */
.nudo-union { fill: var(--ambar); stroke: var(--papel); stroke-width: 1.5; }

/* Controles flotantes */
.controles-lienzo {
    position: absolute; left: 18px; bottom: 18px; z-index: 10;
    display: flex; gap: 5px; padding: 6px;
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: 26px; box-shadow: var(--sombra-2);
}
.controles-lienzo button {
    width: 36px; height: 36px; border: none; border-radius: 50%;
    background: transparent; color: var(--tinta-suave);
    font-size: 1rem; cursor: pointer;
    transition: background .16s, color .16s, transform .16s var(--curva);
}
.controles-lienzo button:hover { background: var(--acento-velo); color: var(--acento-hondo); transform: scale(1.1); }
/* Control encendido (toda la descendencia a la vista): tiene que notarse que
   el lienzo NO está en su estado normal. */
.controles-lienzo button.activo { background: var(--acento); color: #fff; }
.controles-lienzo button.activo:hover { background: var(--acento-hondo); color: #fff; }

.buscador-flotante { position: absolute; top: 18px; left: 18px; right: 18px; z-index: 20; max-width: 430px; }
.buscador-flotante input {
    width: 100%; padding: 12px 18px;
    background: var(--papel); color: var(--tinta);
    border: 1px solid var(--borde); border-radius: 26px;
    box-shadow: var(--sombra-2); font-size: .95rem;
    transition: box-shadow .2s, border-color .2s;
}
.buscador-flotante input:focus { outline: none; border-color: var(--acento); box-shadow: 0 0 0 4px var(--acento-velo), var(--sombra-2); }

.resultados-flotantes {
    margin-top: 7px; max-height: 62vh; overflow-y: auto;
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: var(--radio); box-shadow: var(--sombra-3);
    animation: subir .22s var(--curva) both;
}
.resultados-flotantes:empty { display: none; }
.resultado {
    display: flex; align-items: baseline; gap: 10px;
    padding: 11px 15px; cursor: pointer; border-bottom: 1px solid var(--borde);
    transition: background .14s;
}
.resultado:last-child { border-bottom: none; }
.resultado:hover { background: var(--acento-velo); }
.resultado .r-nombre { font-weight: 600; font-size: .93rem; }
.resultado .r-anios { font-size: .78rem; color: var(--tinta-tenue); margin-left: auto; }
.resultado .r-parentesco {
    padding: 2px 9px; border-radius: 20px;
    background: var(--acento-velo); color: var(--acento-hondo);
    font-size: .74rem; font-weight: 650; white-space: nowrap;
}

/* Panel lateral */
.panel-lateral {
    width: 380px; flex-shrink: 0; overflow-y: auto;
    background: var(--papel); border-left: 1px solid var(--borde); padding: 24px;
    animation: entrarPanel .32s var(--curva) both;
}
@keyframes entrarPanel { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }
.panel-lateral.oculto { display: none; }
.panel-lateral h2 { font-size: 1.38rem; margin-bottom: 2px; }
.panel-lateral .sub { color: var(--tinta-suave); font-size: .9rem; margin-bottom: 16px; }

.chip-parentesco {
    display: inline-block; padding: 5px 14px; margin-bottom: 14px;
    border-radius: 20px; background: var(--acento); color: #fff;
    font-size: .85rem; font-weight: 650;
    box-shadow: var(--sombra-acento);
}

.grupo-relacion { margin-bottom: 18px; }
.grupo-relacion h4 {
    margin-bottom: 7px; font-family: var(--fuente-ui);
    font-size: .72rem; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--tinta-tenue);
}
.lista-personas { display: flex; flex-direction: column; gap: 4px; }
.mini-persona {
    display: flex; align-items: baseline; gap: 8px;
    padding: 8px 11px; border-radius: var(--radio-s);
    background: var(--papel-2); cursor: pointer; font-size: .89rem;
    color: var(--tinta); text-decoration: none;
    border-left: 3px solid transparent;
    transition: background .16s, border-color .16s, transform .16s var(--curva);
}
.mini-persona:hover { background: var(--acento-velo); border-left-color: var(--acento); transform: translateX(3px); text-decoration: none; }
.mini-persona .m-anios { margin-left: auto; font-size: .76rem; color: var(--tinta-tenue); }

.datos-lista { margin: 0 0 18px; font-size: .9rem; }
.datos-lista dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .07em; color: var(--tinta-tenue); margin-top: 11px; }
.datos-lista dd { margin: 2px 0 0; }

/* Diagrama de parentesco: dos ramas que suben al antepasado común */
.diagrama-parentesco {
    margin-top: 12px; padding: 16px;
    background: var(--papel-2); border: 1px solid var(--borde); border-radius: var(--radio);
    animation: subir .3s var(--curva) both;
}
.cadena { display: flex; flex-direction: column; gap: 0; }
.cadena-paso {
    display: flex; align-items: center; gap: 10px; padding: 6px 0; font-size: .88rem;
    cursor: pointer; border-radius: 6px; transition: background .14s;
}
.cadena-paso:hover { background: var(--acento-velo); }
.cadena-paso .punto { width: 10px; height: 10px; border-radius: 50%; background: var(--borde-fuerte); flex-shrink: 0; }
.cadena-paso.ancestro .punto { background: var(--ambar); width: 13px; height: 13px; box-shadow: 0 0 0 4px var(--ambar-velo); }
.cadena-paso.extremo .punto { background: var(--acento); box-shadow: 0 0 0 4px var(--acento-velo); }
.cadena-vinculo {
    margin-left: 4px; padding: 1px 0 1px 16px;
    border-left: 2px solid var(--borde-fuerte);
    font-size: .74rem; color: var(--tinta-tenue); text-transform: lowercase;
}

/* Modal */
.modal-fondo {
    position: fixed; inset: 0; z-index: 100;
    display: flex; align-items: center; justify-content: center;
    padding: 20px; background: rgba(23, 34, 46, .42); backdrop-filter: blur(4px);
    animation: aparecer .18s ease both;
}
@keyframes aparecer { from { opacity: 0; } to { opacity: 1; } }
.modal-fondo.oculto { display: none; }
.modal {
    width: 100%; max-width: 500px; max-height: 86vh; overflow-y: auto;
    padding: 28px; background: var(--papel);
    border-radius: var(--radio); box-shadow: var(--sombra-3);
    animation: subir .28s var(--curva) both;
}
.modal h3 { margin-bottom: 4px; }
.modal .sub { color: var(--tinta-suave); font-size: .9rem; margin-bottom: 18px; }
.modal-acciones { display: flex; gap: 10px; justify-content: flex-end; margin-top: 22px; }

/* ── Utilidades ───────────────────────────────────────────────────────── */

/* Toda tabla que pueda quedarse estrecha va envuelta en `.tabla-marco`: se
   desplaza ella sola en vez de empujar la página. Y las palabras que no caben
   —un correo largo, una URL— se parten antes de estirar la columna, que es lo
   que evita tener que desplazarse en la mayoría de los casos. */
.tabla-marco { overflow-x: auto; max-width: 100%; }
.tabla { width: 100%; border-collapse: collapse; font-size: .91rem; }
.tabla td { overflow-wrap: anywhere; }
.tabla th, .tabla td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--borde); }
.tabla th { font-size: .74rem; text-transform: uppercase; letter-spacing: .07em; color: var(--tinta-tenue); }
.tabla tbody tr { transition: background .14s; }
.tabla tbody tr:hover { background: var(--papel-2); }

.etiqueta-estado {
    display: inline-block; padding: 3px 10px; border-radius: 20px;
    font-size: .74rem; font-weight: 650;
    background: var(--neutro-velo); color: var(--tinta-suave);
}
.etiqueta-estado.ok { background: var(--acento-velo); color: var(--acento-hondo); }
.etiqueta-estado.pendiente { background: var(--ambar-velo); color: #b45309; }

.vacio { padding: 48px 24px; text-align: center; color: var(--tinta-tenue); }
.centrado { text-align: center; }
.mt-1 { margin-top: 8px; }  .mt-2 { margin-top: 16px; }  .mt-3 { margin-top: 28px; }
.mb-1 { margin-bottom: 8px; }

/* ⚠️ El aire de arriba y abajo de una pantalla interior, POR CLASE. Estaba
   escrito en línea en cada vista (`style="padding-top:28px"`) y con un valor
   distinto en cada una —24, 28, 32, 64—: un estilo en línea gana a cualquier
   regla de la hoja, así que no había forma de unificarlo ni de apretarlo en el
   móvil, donde ese hueco es pantalla que se pierde. */
.contenedor.pantalla { padding-top: 30px; padding-bottom: 48px; }
.contenedor.centrado { text-align: center; }

/* El texto explicativo de una tarjeta: dice para qué sirve lo que hay debajo.
   También iba en línea, repetido en cada una. */
.tarjeta-nota { color: var(--tinta-suave); font-size: .93rem; }

/* El párrafo que va justo debajo del título de una pantalla y dice para qué
   sirve. Iba en línea en cada vista, con un margen negativo a ojo. */
.pantalla-intro { color: var(--tinta-suave); margin: -4px 0 18px; max-width: 70ch; }

/* Una tarjeta que solo envuelve una tabla: el relleno lo pone la tabla. */
.tarjeta.sin-relleno { padding: 0; overflow: hidden; }

/* El hueco de un dato que no hay. Es un guion tenue, no un texto más: repetido
   en cada fila, en color normal, pesaría lo mismo que los datos de verdad. */
.sin-dato { color: var(--tinta-tenue); }

/* Un formulario que es solo un botón dentro de una frase. */
.form-en-linea { display: inline; }

/* Algo que reclama atención sin ser un error: un aviso al que se puede ir. */
.marca-atencion { color: var(--ambar-hondo); font-weight: 700; }
a.marca-atencion:hover { text-decoration: underline; }

/* Una tarjeta que se pliega. El `summary` tiene que comportarse como la
   cabecera que sustituye, así que el `h3` va dentro y en línea con la cuenta. */
details.tarjeta > summary {
    display: flex; align-items: baseline; gap: 10px; cursor: pointer;
    list-style: none;
}
details.tarjeta > summary::-webkit-details-marker { display: none; }
details.tarjeta > summary h3 { margin: 0; margin-right: auto; }
/* ⚠️ La flecha se dibuja a mano. Al poner el `summary` en flex, el marcador
   propio del navegador desaparece —y con `list-style-position: outside` se
   colaba fuera de la tarjeta—: la sección quedaba con aspecto de tarjeta vacía
   y nada decía que se pudiera abrir. */
details.tarjeta > summary::after {
    content: "▾"; flex: none; color: var(--tinta-tenue); font-size: .78rem;
    transition: transform .18s var(--curva);
}
details.tarjeta:not([open]) > summary::after { transform: rotate(-90deg); }
details.tarjeta[open] > summary { margin-bottom: 14px; }
.oculto { display: none !important; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

@media (max-width: 860px) {
    .heroe h1 { font-size: 2.4rem; }
    .panel-lateral {
        position: absolute; right: 0; top: 0; bottom: 0;
        width: 100%; max-width: 380px; z-index: 30; box-shadow: var(--sombra-3);
    }
    .campos-fila { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Añadidos: gestos táctiles, diagrama de relaciones, formularios de persona
   y adaptación a móvil.
   ========================================================================== */

/* El lienzo se queda TODOS los gestos: pellizcar amplía el árbol, nunca la
   página. `touch-action` NO se hereda, así que hay que declararlo también en
   el contenido: si no, al pellizcar encima de una tarjeta el navegador se
   quedaba el gesto y no pasaba nada.
   Vale para las tres pantallas que dibujan un gráfico —árbol, ascendencia y
   abanico—, porque las tres montan el mismo marco `.lienzo-envoltorio`. El
   `#lienzo *` cubre de una vez las tarjetas del árbol, las casillas de la
   vista en columnas y los sectores del abanico: dentro del gráfico no hay
   nada que deba desplazarse por su cuenta.
   ⚠️ Este comentario estuvo CERRADO A MEDIAS —llevaba un cierre de más tras
   «no pasaba nada»—, así que el párrafo de abajo quedaba suelto como CSS y el
   parser se comía la regla que viene detrás: el lienzo se quedaba SIN
   `touch-action: none` y en la aplicación el pellizco ampliaba la página
   entera. Y ojo: un cierre de comentario escrito DENTRO de un comentario lo
   cierra igual, así que aquí no se puede citar literalmente. */
.lienzo-envoltorio,
.lienzo-envoltorio #lienzo,
.lienzo-envoltorio #lienzo *,
.lienzo-envoltorio .nodo,
.lienzo-envoltorio #conexiones {
    touch-action: none;
}
.lienzo-envoltorio {
    -webkit-user-select: none;
    user-select: none;
    overscroll-behavior: contain;
}
/* Los controles de la interfaz sí responden al toque normal. */
.buscador-flotante, .buscador-flotante *,
.controles-lienzo, .controles-lienzo * { touch-action: auto; }

/* ── Instalada como aplicación: el pellizco solo amplía el gráfico ──────────
   Ampliar la página entera es un gesto de NAVEGADOR: en una aplicación, que
   la lista, los ajustes o el menú se estiren al pellizcarlos delata que
   debajo hay una web. Se deja `pan-x pan-y`, no `none`: el desplazamiento
   normal (y el horizontal de las tablas anchas de /lista) tiene que seguir
   funcionando; lo que se retira es el zoom y el doble toque que amplía.
   El gráfico conserva el suyo porque `.lienzo-envoltorio` declara `none` y su
   pellizco lo calcula el JS, no el navegador.
   Se aplica por las DOS vías a propósito: la consulta de medios cubre a quien
   la instaló en Android o escritorio, y la clase `como-app` —que pone el
   servidor desde la cookie y confirma `pwa.js`— cubre iOS, donde
   `display-mode: standalone` no siempre se declara. */
@media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
    html, body { touch-action: pan-x pan-y; }
}
html.como-app, body.como-app { touch-action: pan-x pan-y; }

/* Aviso flotante */
.brindis {
    position: fixed; left: 50%; bottom: 24px; z-index: 200;
    transform: translateX(-50%);
    max-width: min(92vw, 460px);
    padding: 12px 20px;
    background: var(--tinta); color: #fff;
    border-radius: 24px; box-shadow: var(--sombra-3);
    font-size: .92rem; text-align: center;
    animation: subir .28s var(--curva) both;
}

/* ── Diagrama de relaciones en dos columnas ───────────────────────────── */

/* Barra para elegir a las dos personas que se comparan. Las sugerencias van
   en posición absoluta para no empujar el diagrama al desplegarse. */
.dg-comparar {
    display: flex; align-items: flex-end; gap: 10px;
    margin: 12px 0 18px; padding: 12px;
    background: var(--papel-2); border: 1px solid var(--borde);
    border-radius: var(--radio-s);
}
.dg-campo { position: relative; flex: 1; min-width: 0; }
.dg-campo label {
    display: block; margin-bottom: 4px;
    font-size: .7rem; text-transform: uppercase; letter-spacing: .07em;
    color: var(--tinta-tenue);
}
.dg-campo input {
    width: 100%; padding: 9px 12px;
    background: var(--papel); color: var(--tinta);
    border: 1px solid var(--borde); border-radius: var(--radio-s);
    font-size: .9rem;
    transition: border-color .16s, box-shadow .16s;
}
.dg-campo input:focus { outline: none; border-color: var(--acento); box-shadow: 0 0 0 3px var(--acento-velo); }

.dg-sugerencias {
    position: absolute; z-index: 5; top: 100%; left: 0; right: 0;
    margin-top: 5px; max-height: 46vh; overflow-y: auto;
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: var(--radio-s); box-shadow: var(--sombra-3);
}
.dg-sugerencias:empty { display: none; }
.dg-sugerencias .resultado { padding: 9px 12px; }

/* La persona ya elegida en «Añadir familiar»: se enseña en lugar del
   buscador, para que quede claro que no se va a crear ninguna ficha. */
.persona-elegida {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 9px 12px;
    background: var(--acento-velo); border: 1px solid var(--acento);
    border-radius: var(--radio-s);
}
.persona-elegida-nombre { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }

.dg-intercambiar {
    flex-shrink: 0; width: 38px; height: 38px; margin-bottom: 1px;
    background: var(--papel); color: var(--tinta-suave);
    border: 1px solid var(--borde); border-radius: 50%;
    font-size: 1rem; cursor: pointer;
    transition: background .16s, color .16s, transform .16s;
}
.dg-intercambiar:hover { background: var(--acento-velo); color: var(--acento-hondo); transform: rotate(180deg); }

.diagrama-explica {
    margin: 0 0 18px; padding: 11px 15px;
    background: var(--acento-velo); border-radius: var(--radio-s);
    font-size: .9rem; color: var(--tinta);
}

.diagrama-rejilla {
    /* Una única rejilla para todo: tarjetas y conectores comparten columnas,
       que es lo que mantiene las líneas verticales rectas y las etiquetas
       alineadas con su rama. */
    display: grid;
    grid-template-columns: 1fr 118px 1fr;
    align-items: stretch;
}

.dg-celda {
    display: flex; justify-content: center;
    /* `stretch` hace que las tarjetas de una misma fila midan LO MISMO aunque
       a una le falten las fechas: los niveles se leen de un vistazo. La pareja
       política vive en su propia fila, así que ya no descuadra la altura. */
    align-items: stretch;
}
.dg-celda > .diagrama-tarjeta { width: 100%; display: flex; flex-direction: column; justify-content: center; }
.dg-vacia { min-height: 8px; }

.dg-comun { padding: 2px 0 4px; }

.diagrama-tarjeta {
    width: 100%;
    padding: 10px 13px;
    background: var(--papel);
    border: 1.5px solid var(--borde-fuerte);
    border-left-width: 4px;
    border-radius: 10px;
    box-shadow: var(--sombra-1);
    cursor: pointer;
    transition: transform .16s var(--curva), box-shadow .16s var(--curva), border-color .16s;
}
.diagrama-tarjeta:hover { transform: translateY(-2px); box-shadow: var(--sombra-2); }
.diagrama-tarjeta.sexo-H { border-left-color: var(--varon); }
.diagrama-tarjeta.sexo-M { border-left-color: var(--mujer); }
.diagrama-tarjeta.comun {
    width: auto; min-width: 58%;
    border-color: var(--ambar); background: var(--ambar-velo);
    text-align: center;
}
.dt-nombre { font-family: var(--fuente); font-weight: 600; font-size: .93rem; line-height: 1.25; }
.dt-anios  { font-size: .76rem; color: var(--tinta-tenue); margin-top: 2px; }

/* Conector vertical entre dos generaciones. La línea va centrada en la
   columna y la etiqueta a su lado, no encima. */
.dg-conector {
    position: relative;
    min-height: 30px;
    align-items: center;
    justify-content: center;
}
.dg-conector::before {
    content: "";
    position: absolute; top: 0; bottom: 0; left: 50%;
    width: 2px; margin-left: -1px;
    background: var(--borde-fuerte);
}
.dg-conector.sin-linea::before { display: none; }
.dg-etiqueta {
    position: relative; z-index: 1;
    padding: 1px 8px;
    background: var(--papel);
    border-radius: 20px;
    font-size: .72rem; color: var(--tinta-tenue);
}

.dg-medio { justify-content: center; align-items: center; min-height: 44px; }
.diagrama-relacion {
    padding: 3px 11px; border-radius: 20px; white-space: nowrap;
    background: var(--acento-velo); color: var(--acento-hondo);
    font-size: .72rem; font-weight: 700; text-align: center;
}
/* La relación diagonal se distingue: no compara dos personas de la misma
   altura, sino una con la de un escalón más abajo. */
.diagrama-relacion.diagonal {
    background: var(--ambar-velo); color: #b45309;
    border: 1px dashed color-mix(in srgb, var(--ambar) 45%, transparent);
}

/* ── Formulario de persona ────────────────────────────────────────────── */

/* ── Alta y edición de una persona ─────────────────────────────────────────
   El formulario va en DOS BLOQUES: arriba lo que identifica a alguien —nombre,
   los dos apellidos, sexo y si vive—, y debajo, plegado, el resto. Antes eran
   once campos seguidos con el apodo ANTES que el sexo y el «sigue viva» al
   final del todo: quien no conoce la aplicación no sabía qué hacía falta de
   verdad y se ponía a rellenar fechas que no tiene. */
.form-persona { display: flex; flex-direction: column; }
.fp-rejilla { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.fp-rejilla .campo-ancho { grid-column: 1 / -1; }
.fp-intercambiar { margin-top: -6px; margin-bottom: 14px; }

/* Lo opcional, plegado. No es esconderlo: es decir en qué orden se hacen las
   cosas. Se abre solo si ya hay algo escrito. */
.fp-mas {
    border: 1px solid var(--borde); border-radius: var(--radio-s);
    background: var(--papel-2); margin-bottom: 4px;
}
.fp-mas-cab {
    display: flex; align-items: baseline; gap: 8px; cursor: pointer;
    padding: 11px 14px; list-style-position: outside;
}
.fp-mas-titulo { font-size: .87rem; font-weight: 600; color: var(--tinta-suave); }
.fp-mas-nota {
    font-size: .72rem; color: var(--tinta-tenue); text-transform: uppercase;
    letter-spacing: .05em;
}
.fp-mas[open] { background: transparent; }
.fp-mas[open] .fp-mas-cab { border-bottom: 1px solid var(--borde); margin-bottom: 15px; }
.fp-mas > .fp-rejilla { padding: 0 14px; }

/* ── Pasos de «Añadir familiar» ────────────────────────────────────────────
   La pantalla hace DOS preguntas —qué parentesco es y quién es— y antes se
   leía como un único formulario largo: el buscador de «¿ya está en el árbol?»
   quedaba enterrado entre dos desplegables y la ficha entera debajo, sin nada
   que dijera que son alternativas. Numeradas y separadas, se ve que son dos
   decisiones y en qué orden van. */
.paso { margin-bottom: 22px; }
.paso:last-of-type { margin-bottom: 0; }
.paso-cabecera { display: flex; align-items: center; gap: 9px; margin-bottom: 11px; }
.paso-numero {
    flex: none; width: 22px; height: 22px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--acento); color: #fff;
    font-size: .74rem; font-weight: 700; font-family: var(--fuente-ui);
}
.paso-titulo { margin: 0; font-size: .97rem; }
.paso-matiz { margin-bottom: 0; }

/* ⚠️ Un grupo de botones en vez de un `<select>`: con dos o cuatro opciones,
   las de un desplegable cerrado NO SE VEN, y quien no conoce la aplicación no
   llega a enterarse de que puede enlazar a alguien que ya está en el árbol.
   El `<select>` sigue existiendo oculto, que es quien guarda el valor. */
/* El aire va DEBAJO del grupo de botones y no en lo que viene detrás: así vale
   igual para el desplegable del paso 1 que para el buscador o la ficha del
   paso 2, que se turnan en el mismo sitio. Pegados a la línea siguiente se
   leían como si formaran parte de ella. */
.opciones-botones {
    display: grid; gap: 8px; grid-template-columns: repeat(2, 1fr);
    margin-bottom: 18px;
}
.opcion-boton {
    display: flex; flex-direction: column; gap: 2px; text-align: left;
    padding: 11px 13px; min-width: 0;
    border: 1.5px solid var(--borde); border-radius: var(--radio-s);
    background: var(--papel); color: var(--tinta);
    font-family: inherit; cursor: pointer;
    transition: border-color .15s, background .15s, box-shadow .15s;
}
.opcion-boton:hover { border-color: var(--borde-fuerte); background: var(--papel-2); }
.opcion-titulo { font-size: .89rem; font-weight: 600; overflow-wrap: anywhere; }
.opcion-nota { font-size: .76rem; color: var(--tinta-tenue); }
.opcion-boton.activo,
.opciones-radio .opcion-boton:has(input:checked) {
    border-color: var(--acento); background: var(--acento-velo);
    box-shadow: 0 0 0 3px var(--acento-velo);
}
.opcion-boton.activo .opcion-titulo,
.opciones-radio .opcion-boton:has(input:checked) .opcion-titulo { color: var(--acento-hondo); }
.opcion-boton.activo .opcion-nota,
.opciones-radio .opcion-boton:has(input:checked) .opcion-nota { color: var(--acento-hondo); opacity: .8; }

/* La misma pieza SIN una línea de JS, para los formularios que se envían al
   servidor: el `radio` de verdad sigue ahí —invisible pero enfocable, y es
   quien manda el valor—, y el aspecto lo decide `:has(input:checked)`. Así
   funciona igual aunque el guion no llegue a cargarse.
   Tres permisos no caben en dos columnas: se reparten por ancho disponible. */
.opciones-radio { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.opciones-radio .opcion-boton { position: relative; }
.opciones-radio .opcion-boton input {
    position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
}
/* El foco tiene que verse: es un control de verdad y se llega con el tabulador. */
.opciones-radio .opcion-boton:has(input:focus-visible) {
    outline: 2px solid var(--acento); outline-offset: 2px;
}
.campo-check {
    display: flex; align-items: center; gap: 8px;
    margin: 4px 0 6px; font-size: .92rem; color: var(--tinta-suave);
    cursor: pointer;
}
.campo-check input { width: 18px; height: 18px; accent-color: var(--acento); }

.modal-ancho { max-width: 760px; }

/* Barra superior y acciones del panel lateral */
.panel-barra { display: flex; justify-content: flex-end; margin-bottom: 6px; }
.acciones-ficha { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 18px; }

.mini-persona.destacada { font-weight: 650; }
.mini-persona.sangrada  { padding-left: 24px; }

/* ── Móvil ────────────────────────────────────────────────────────────── */

@media (max-width: 860px) {
    .cabecera { padding: 10px 14px; gap: 10px; }
    .cabecera .marca { font-size: 1.1rem; }
    .nav { gap: 2px; }
    .nav a { padding: 6px 10px; font-size: .86rem; }



    .buscador-flotante { top: 10px; left: 10px; right: 10px; max-width: none; }
    .buscador-flotante input { padding: 11px 15px; font-size: 16px; } /* 16px evita el zoom de iOS al enfocar */

    /* ⚠️ Los controles suben por encima de la hoja de la ficha. Aquí abajo el
       panel es una hoja pegada al fondo de hasta 72dvh y los tapaba enteros,
       justo al llegar al árbol desde el buscador, desde /lista o pulsando una
       tarjeta —las tres vías que abren ficha—: de ahí que parecieran salir o
       no «según desde dónde entres». `--alto-hoja` la mide `arbol.js`, porque
       depende del contenido y cambia al pasar de Vida a Familia. */
    .controles-lienzo {
        left: 10px; padding: 5px;
        bottom: calc(10px + var(--alto-hoja, 0px));
        transition: bottom .22s var(--curva);
    }
    .controles-lienzo button { width: 42px; height: 42px; } /* objetivos táctiles cómodos */
    /* Cuando encima de la hoja no caben, se retiran en vez de meterse dentro
       del buscador: dos cosas pisándose no las usa nadie. Vuelven al cerrar la
       ficha. */
    .controles-lienzo.sin-sitio {
        opacity: 0; pointer-events: none; transform: translateY(8px);
    }

    /* El panel de la ficha ocupa la mitad inferior, como una hoja deslizante */
    .panel-lateral {
        position: fixed; left: 0; right: 0; bottom: 0; top: auto;
        width: 100%; max-width: none; max-height: 72dvh;
        border-left: none; border-top: 1px solid var(--borde);
        border-radius: 18px 18px 0 0;
        box-shadow: 0 -8px 30px rgba(23, 34, 46, .18);
        padding: 18px 16px 24px;
        animation: subirHoja .3s var(--curva) both;
    }
    @keyframes subirHoja { from { transform: translateY(100%); } to { transform: none; } }
    .panel-lateral::before {
        content: ""; display: block; width: 40px; height: 4px; margin: 0 auto 12px;
        background: var(--borde-fuerte); border-radius: 4px;
    }

    .modal { padding: 20px 16px; max-height: 88dvh; border-radius: 16px; }
    .modal-acciones { position: sticky; bottom: 0; background: var(--papel); padding-top: 12px; }
    .modal-acciones .boton { flex: 1; }

    .contenedor.pantalla { padding-top: 18px; padding-bottom: 32px; }
    .fp-rejilla { grid-template-columns: 1fr; }
    /* Cuatro opciones a lo ancho no caben en 360 px: una por línea se lee, y
       además es el tamaño de dedo que hace falta para acertar. */
    .opciones-botones { grid-template-columns: 1fr; }
    .campo input, .campo select, .campo textarea,
    .dg-campo input { font-size: 16px; }   /* 16px: por debajo, iOS amplía al enfocar */

    /* El diagrama se estrecha pero mantiene las dos columnas */
    .diagrama-rejilla { grid-template-columns: 1fr 84px 1fr; }
    .diagrama-tarjeta { padding: 8px 10px; }
    .dt-nombre { font-size: .84rem; }
    .dt-anios { font-size: .7rem; }
    .diagrama-relacion { font-size: .64rem; padding: 2px 7px; white-space: normal; text-align: center; }

    .heroe { padding: 52px 0 40px; }
    .franja-datos { gap: 26px; }
    .tabla { font-size: .84rem; }
    .tabla th, .tabla td { padding: 8px 7px; }
}

@media (max-width: 480px) {
    .diagrama-rejilla { grid-template-columns: 1fr 72px 1fr; }
    .diagrama-relacion { max-width: 68px; white-space: normal; }
}

/* ==========================================================================
   Lengüeta «+» de la tarjeta, menú contextual, pestañas y cronología
   ========================================================================== */

/* La lengüeta cuelga del borde inferior de la tarjeta, como una pestaña de
   carpeta: invita a añadir familia sin salir del árbol. */
.nodo-mas {
    position: absolute; right: -13px; bottom: -13px;
    transform: none;
    display: flex; align-items: center; justify-content: center;
    width: 27px; height: 27px;
    background: var(--papel);
    border: 1.5px solid var(--borde-fuerte);
    border-radius: 50%;
    color: var(--acento-hondo); font-size: 1rem; font-weight: 600; line-height: 1;
    cursor: pointer; opacity: 0;
    box-shadow: 0 3px 7px rgba(23, 34, 46, .10);
    transition: opacity .18s var(--curva), background .18s, color .18s, transform .18s var(--curva);
}
.nodo:hover .nodo-mas,
.nodo:focus-within .nodo-mas,
.nodo.foco .nodo-mas { opacity: 1; }
.nodo-mas:hover {
    background: var(--acento); color: #fff; border-color: var(--acento);
    transform: scale(1.16);
}
/* En pantallas táctiles no hay «pasar por encima»: siempre visible. */
@media (hover: none) {
    .nodo-mas { opacity: 1; }
}

/* La flecha de desplegar se queda centrada; el «+» vive en la esquina
   inferior derecha. Antes estaban a 26 px y en el móvil se pisaban al tocar. */
.expandir.abajo { bottom: -12px; left: 50%; }

/* Menú contextual */
.menu-flotante {
    position: fixed; z-index: 150;
    padding: 6px;
    background: var(--papel);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-3);
    animation: subir .16s var(--curva) both;
}
.menu-opcion {
    display: block; width: 100%;
    padding: 9px 12px; border: none; border-radius: var(--radio-s);
    background: transparent; color: var(--tinta);
    font-family: var(--fuente-ui); font-size: .9rem; text-align: left;
    cursor: pointer; transition: background .14s, color .14s;
}
.menu-opcion:hover { background: var(--acento-velo); color: var(--acento-hondo); }
.menu-separador { height: 1px; margin: 5px 8px; background: var(--borde); }

/* Pestañas de la ficha */
.pestañas {
    display: flex; gap: 4px; margin: 16px 0 14px;
    border-bottom: 1px solid var(--borde);
}
.pestaña {
    padding: 8px 14px; border: none; background: transparent;
    color: var(--tinta-tenue); font-family: var(--fuente-ui);
    font-size: .9rem; font-weight: 600; cursor: pointer;
    border-bottom: 2px solid transparent; margin-bottom: -1px;
    transition: color .16s, border-color .16s;
}
.pestaña:hover { color: var(--tinta); }
.pestaña.activa { color: var(--acento-hondo); border-bottom-color: var(--acento); }

/* Cronología vital */
.cronologia { position: relative; padding-left: 4px; }
.crono-hito { display: grid; grid-template-columns: 46px 1fr; gap: 10px; padding-bottom: 14px; position: relative; }
.crono-hito::before {
    content: ""; position: absolute; left: 53px; top: 20px; bottom: 0;
    width: 2px; background: var(--borde);
}
.crono-hito:last-child::before { display: none; }
.crono-anio {
    position: relative; padding-top: 9px;
    font-size: .78rem; font-weight: 700; color: var(--tinta-tenue);
    text-align: right; font-variant-numeric: tabular-nums;
}
.crono-anio::after {
    content: ""; position: absolute; right: -13px; top: 13px;
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--borde-fuerte); border: 2px solid var(--papel);
}
.crono-caja {
    padding: 9px 13px; margin-left: 10px;
    background: var(--papel-2); border-radius: var(--radio-s);
    border-left: 3px solid var(--borde-fuerte);
}
.crono-titulo { font-weight: 650; font-size: .89rem; }
.crono-detalle { font-size: .86rem; color: var(--tinta-suave); }
.crono-detalle.enlazado { color: var(--acento-hondo); cursor: pointer; }
.crono-detalle.enlazado:hover { text-decoration: underline; }
.crono-fecha, .crono-lugar { font-size: .78rem; color: var(--tinta-tenue); margin-top: 2px; }

.tipo-nacimiento .crono-caja { border-left-color: var(--acento); }
.tipo-nacimiento .crono-anio::after { background: var(--acento); }
.tipo-union .crono-caja { border-left-color: var(--ambar); }
.tipo-union .crono-anio::after { background: var(--ambar); }
.tipo-hijo .crono-caja { border-left-color: var(--varon); }
.tipo-defuncion .crono-caja { border-left-color: var(--tinta-tenue); }

/* Familiares con su rol */
.mp-texto { display: flex; flex-direction: column; }
.mp-nombre { font-weight: 600; font-size: .9rem; line-height: 1.25; }
.mp-rol { font-size: .76rem; color: var(--tinta-tenue); }
.mini-persona { align-items: center; }

@media (max-width: 860px) {
    .crono-hito { grid-template-columns: 40px 1fr; }
    .crono-hito::before { left: 47px; }
    .menu-flotante { width: 230px !important; }
    .menu-opcion { padding: 12px 14px; font-size: .95rem; }
    /* Objetivos táctiles más grandes y bien separados entre sí. */
    .nodo-mas { width: 32px; height: 32px; right: -15px; bottom: -15px; font-size: 1.15rem; }
    .expandir { width: 28px; height: 28px; }
}

/* ==========================================================================
   Fotos: retrato en la tarjeta y galería de la ficha
   ========================================================================== */

.nodo-retrato {
    position: absolute; right: 9px; top: 9px;
    width: 38px; height: 38px;
    object-fit: cover; border-radius: 50%;
    border: 2px solid var(--papel);
    box-shadow: 0 1px 4px rgba(23, 34, 46, .18);
    background: var(--neutro-velo);
}
/* Con retrato, el texto deja sitio para no pasar por debajo. */
.nodo.con-retrato .nombre,
.nodo.con-retrato .apellidos { padding-right: 46px; }

.galeria {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 8px;
}
.galeria-foto {
    position: relative; aspect-ratio: 1;
    border-radius: 10px; overflow: hidden;
    border: 2px solid var(--borde);
    background: var(--papel-2);
}
.galeria-foto.principal { border-color: var(--ambar); }
.galeria-foto.principal::before {
    content: "retrato"; position: absolute; left: 4px; top: 4px; z-index: 2;
    padding: 1px 6px; border-radius: 20px;
    background: var(--ambar); color: #fff;
    font-size: .6rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}
.galeria-foto img {
    width: 100%; height: 100%; object-fit: cover; cursor: zoom-in; display: block;
    transition: transform .3s var(--curva);
}
.galeria-foto:hover img { transform: scale(1.06); }

.galeria-acciones {
    position: absolute; left: 0; right: 0; bottom: 0;
    display: flex; gap: 4px; justify-content: flex-end;
    padding: 5px; opacity: 0;
    background: linear-gradient(transparent, rgba(23, 34, 46, .62));
    transition: opacity .18s;
}
.galeria-foto:hover .galeria-acciones { opacity: 1; }
@media (hover: none) { .galeria-acciones { opacity: 1; } }

.mini-boton {
    padding: 3px 8px; border: none; border-radius: 6px;
    background: rgba(255, 255, 255, .92); color: var(--tinta);
    font-size: .7rem; font-weight: 650; cursor: pointer;
}
.mini-boton:hover { background: #fff; }
.mini-boton.peligro { background: rgba(225, 29, 72, .92); color: #fff; }

/* ==========================================================================
   Vistas de solo ascendencia: en columnas y en abanico
   ========================================================================== */

.barra-vista {
    position: absolute; top: 14px; left: 14px; right: 14px; z-index: 20;
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    padding: 10px 16px;
    background: color-mix(in srgb, var(--papel) 92%, transparent);
    backdrop-filter: blur(10px);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-1);
}
.barra-titulo { display: flex; flex-direction: column; }
.barra-titulo strong { font-family: var(--fuente); font-size: 1.05rem; }
.barra-titulo .sub { font-size: .8rem; color: var(--tinta-tenue); }
.selector-gen {
    margin-left: auto; display: flex; align-items: center; gap: 8px;
    font-size: .84rem; color: var(--tinta-suave); font-weight: 600;
}
.selector-gen select {
    padding: 6px 10px; border: 1px solid var(--borde-fuerte);
    border-radius: var(--radio-s); background: var(--papel); color: var(--tinta);
    font-size: .88rem;
}

/* Vista en columnas */
.columnas { position: relative; }
.columnas-lineas { position: absolute; inset: 0; overflow: visible; pointer-events: none; }

.casilla {
    position: absolute;
    display: flex; flex-direction: column; justify-content: center;
    padding: 6px 11px;
    background: var(--papel);
    border: 1px solid var(--borde); border-left: 4px solid var(--borde-fuerte);
    border-radius: 8px; box-shadow: var(--sombra-1);
    cursor: pointer; overflow: hidden;
    transition: transform .16s var(--curva), box-shadow .16s var(--curva);
}
.casilla:hover { transform: translateX(3px); box-shadow: var(--sombra-2); z-index: 3; }
.casilla-nombre {
    font-size: .82rem; font-weight: 600; line-height: 1.2;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    color: #17222e;   /* el fondo del sector es claro en todas las generaciones */
}
.casilla-anios { font-size: .7rem; color: #56677c; }

/* La casilla vacía es información: marca dónde falta investigar. */
.casilla.vacia {
    background: transparent;
    border: 1px dashed var(--borde-fuerte); border-left-width: 1px;
    box-shadow: none; cursor: default;
}
.casilla.vacia:hover { transform: none; box-shadow: none; }
.casilla-vacia { text-align: center; color: var(--tinta-tenue); font-size: 1rem; font-weight: 700; }

/* Abanico */
.abanico { display: block; }
.sector path, .sector circle { transition: filter .16s, opacity .16s; }
.sector:hover path, .sector:hover circle { filter: brightness(1.06); }
.sector.vacio:hover path { filter: none; }
.sector-texto {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
    font-size: 11px; font-weight: 600; fill: #17222e;
    text-anchor: middle; dominant-baseline: middle;
    pointer-events: none;
}
.sector-texto.menudo { font-size: 9px; font-weight: 500; }
.sector-texto.centro { font-size: 13px; }
.sector-texto.centro.pequeno { font-size: 10px; font-weight: 500; fill: #56677c; }

/* Cobertura por generación: dónde falta investigar */
.leyenda-vista {
    position: absolute; right: 14px; bottom: 14px; z-index: 15;
    width: 190px; padding: 12px 14px;
    background: color-mix(in srgb, var(--papel) 94%, transparent);
    backdrop-filter: blur(10px);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-1);
}
.leyenda-fila { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; font-size: .74rem; }
.leyenda-gen { width: 20px; color: var(--tinta-tenue); font-weight: 700; }
.leyenda-barra { flex: 1; height: 6px; background: var(--fondo-2); border-radius: 4px; overflow: hidden; }
.leyenda-relleno { height: 100%; background: var(--acento); border-radius: 4px; transition: width .4s var(--curva); }
.leyenda-cifra { color: var(--tinta-tenue); font-variant-numeric: tabular-nums; }

@media (max-width: 860px) {
    .barra-vista { top: 10px; left: 10px; right: 10px; padding: 9px 12px; gap: 10px; }
    .barra-titulo strong { font-size: .95rem; }
    .selector-gen { font-size: .78rem; }
    .leyenda-vista { width: 152px; right: 10px; bottom: 76px; padding: 9px 11px; }
    .leyenda-fila { font-size: .68rem; }
}

/* ==========================================================================
   Dos experiencias: escritorio con paneles, móvil como aplicación
   ========================================================================== */

/* Diagonales de la relación tío/sobrino.
   Van de una fila a OTRA, así que no caben dentro de una celda: se dibujan en
   una capa superpuesta que se mide y se ancla al mismo marco que la rejilla
   —si se midiera desde una y se anclara a otra, todo el trazo saldría
   desplazado—. La etiqueta se coloca sobre el punto medio del propio trazo. */
.dg-lienzo { position: relative; }
.dg-capa {
    position: absolute; left: 0; top: 0;
    pointer-events: none; z-index: 0; overflow: visible;
}
.dg-diagonal {
    stroke: var(--ambar); stroke-width: 1.6;
    stroke-dasharray: 5 4; stroke-linecap: round;
}
.dg-diagonal.final { stroke-width: 2.4; stroke-dasharray: none; }

.dg-etiquetas {
    position: absolute; left: 0; top: 0; right: 0; bottom: 0;
    pointer-events: none; z-index: 3;
}
.dg-etiquetas .diagrama-relacion {
    position: absolute;
    transform: translate(-50%, -50%);
    pointer-events: auto;
}

/* Las tarjetas van por encima del trazo, que así entra «por detrás». */
.dg-celda { position: relative; z-index: 1; }
/* La celda queda vacía, pero reserva el hueco por el que pasa la diagonal. */
.dg-medio.con-diagonal { min-height: 52px; }

/* ── Barra de navegación desplazable en móvil ─────────────────────────── */
@media (max-width: 860px) {
    .cabecera {
        gap: 8px;
        /* La marca se queda fija y los enlaces se deslizan: con seis secciones
           no caben en 390 px y antes se salían de la pantalla. */
        align-items: center;
    }
    .cabecera .marca { flex-shrink: 0; }
    .nav {
        margin-left: auto;
        overflow-x: auto;
        overflow-y: hidden;
        flex-wrap: nowrap;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        mask-image: linear-gradient(90deg, transparent 0, #000 12px, #000 calc(100% - 18px), transparent 100%);
    }
    .nav::-webkit-scrollbar { display: none; }
    .nav a, .nav form { flex-shrink: 0; }
    .nav a { padding: 7px 11px; font-size: .85rem; }
}

/* ── La ficha en móvil se comporta como una hoja de aplicación ────────── */
@media (max-width: 860px) {
    /* Ni la página ni el lienzo se mueven mientras la hoja está abierta: solo
       se desplaza la hoja, que es lo que se espera de una app. */
    body.con-panel { overflow: hidden; }

    .panel-lateral {
        position: fixed; left: 0; right: 0; bottom: 0; top: auto;
        display: flex; flex-direction: column;
        width: 100%; max-width: none;
        height: 82dvh; max-height: 82dvh;
        padding: 0;
        border-left: none; border-top: 1px solid var(--borde);
        border-radius: 20px 20px 0 0;
        box-shadow: 0 -10px 34px rgba(23, 34, 46, .22);
        overflow: hidden;                 /* el scroll va dentro, no en la hoja */
        z-index: 60;
    }
    .panel-lateral::before {
        content: ""; flex-shrink: 0;
        width: 42px; height: 4px; margin: 10px auto 6px;
        background: var(--borde-fuerte); border-radius: 4px;
    }
    .panel-lateral > .ficha-cabecera { flex-shrink: 0; padding: 0 16px; }
    .panel-lateral > .pestañas { flex-shrink: 0; margin: 8px 16px 0; }
    .panel-lateral > .paneles {
        flex: 1; min-height: 0;
        overflow-y: auto; -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        padding: 12px 16px 8px;
    }
    /* Las acciones quedan ancladas abajo, no perdidas al final del scroll. */
    /* Una sola fila: la acción principal y el resto en un menú. Antes eran
       cinco botones en dos filas y se comían 132 px del panel. */
    .panel-lateral > .acciones-ficha {
        flex-shrink: 0;
        margin: 0;
        padding: 8px 16px calc(10px + env(safe-area-inset-bottom));
        border-top: 1px solid var(--borde);
        background: var(--papel);
        display: grid; grid-template-columns: 1fr auto; gap: 8px;
    }
}

/* ── Modales en móvil: hoja completa con acciones fijas ───────────────── */
@media (max-width: 860px) {
    .modal-fondo { padding: 0; align-items: flex-end; }
    .modal {
        display: flex; flex-direction: column;
        width: 100%; max-width: none;
        max-height: 92dvh;
        border-radius: 18px 18px 0 0;
        padding: 18px 16px 0;
        overflow: hidden;
    }
    .modal > h3, .modal > .sub, .modal > .dg-comparar { flex-shrink: 0; }
    /* El cuerpo del modal es lo único que se desplaza.
       ⚠️ **También por CLASE, no solo por esos cuatro ids.** El modal es
       `overflow: hidden`, así que un diálogo cuyo contenido no cuelgue de uno
       de estos elementos NO SE PUEDE DESPLAZAR: se corta por abajo y no hay
       manera de llegar al final. Pasó con «todos sus apellidos», que son cinco
       generaciones de casillas. Cualquier modal nuevo con contenido largo debe
       envolverlo en `.modal-cuerpo`. */
    .modal > .modal-cuerpo,
    .modal > .propagacion-cuerpo,
    .modal > #diagrama-cuerpo,
    .modal > #ramas-cuerpo,
    .modal > #persona-cuerpo,
    .modal > form {
        flex: 1; min-height: 0; overflow-y: auto;
        overscroll-behavior: contain;
        padding-bottom: 8px;
    }
    /* El botón Cerrar se montaba encima del contenido: ahora es una barra
       propia, pegada abajo y con su propio fondo. */
    .modal-acciones {
        flex-shrink: 0;
        margin: 0 -16px;
        padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
        border-top: 1px solid var(--borde);
        background: var(--papel);
        box-shadow: 0 -4px 14px rgba(23, 34, 46, .06);
    }
}

/* En escritorio, las acciones del modal tampoco deben pisar el contenido. */
@media (min-width: 861px) {
    .modal { display: flex; flex-direction: column; }
    .modal > .modal-cuerpo,
    .modal > .propagacion-cuerpo,
    .modal > #diagrama-cuerpo,
    .modal > #ramas-cuerpo,
    .modal > #persona-cuerpo,
    .modal > form { overflow-y: auto; min-height: 0; }
    .modal-acciones {
        flex-shrink: 0;
        margin: 18px -28px 0;
        padding: 16px 28px 0;
        border-top: 1px solid var(--borde);
    }
}

/* Acciones destructivas: se distinguen sin gritar. */
.menu-opcion.peligro { color: var(--rojo); }
.menu-opcion.peligro:hover { background: var(--rojo-velo); color: var(--rojo); }
.boton.secundario.peligro-suave { color: var(--rojo); border-color: color-mix(in srgb, var(--rojo) 32%, var(--borde-fuerte)); }
.boton.secundario.peligro-suave:hover { background: var(--rojo-velo); border-color: var(--rojo); color: var(--rojo); }

/* Diálogo de confirmación propio (nada de confirm() del navegador) */
.modal-confirmar { max-width: 420px; }
.modal-confirmar h3 { margin-bottom: 8px; }
.confirmar-detalle {
    margin: 4px 0 0; padding: 11px 14px;
    background: var(--rojo-velo); border-radius: var(--radio-s);
    font-size: .88rem; color: var(--tinta);
}
.confirmar-detalle p { margin: 0; }
.modal-confirmar .modal-acciones { border-top: none; }

.brindis.saliendo { opacity: 0; transform: translateX(-50%) translateY(8px); transition: opacity .35s, transform .35s; }
.brindis.error { background: var(--rojo); }

@media (max-width: 860px) {
    .modal-confirmar { border-radius: 18px; margin: 0 12px 12px; }
    .modal-fondo:has(.modal-confirmar) { align-items: center; padding: 16px; }
}

/* La única pareja del diagrama: la política, colgando del pariente de sangre */
.dt-envoltura { width: 100%; min-width: 0; display: flex; flex-direction: column; align-items: stretch; }

.dt-union {
    align-self: center;
    color: var(--ambar); font-size: 1rem; line-height: 1;
    padding: 2px 0;
}

.dt-pareja.politica {
    /* En columna: antes heredaba una regla flex en fila de cuando el ∞ vivía
       dentro de la tarjeta, y el nombre salía truncado con el rol al lado. */
    display: flex; flex-direction: column; justify-content: center;
    padding: 8px 12px;
    background: var(--ambar-velo);
    border: 1.5px dashed color-mix(in srgb, var(--ambar) 55%, transparent);
    border-left: 4px solid var(--neutro);
    border-radius: 10px;
    cursor: pointer; min-width: 0;
    transition: background .16s, border-color .16s;
}
.dt-pareja.politica:hover { background: var(--acento-velo); border-color: var(--acento); }
.dt-pareja.politica.sexo-H { border-left-color: var(--varon); }
.dt-pareja.politica.sexo-M { border-left-color: var(--mujer); }
.dt-pareja.politica .dt-nombre {
    font-size: .9rem; font-weight: 600;
    white-space: normal; overflow: visible; text-overflow: clip;
}
.dt-rol {
    margin-top: 2px; font-size: .7rem; font-weight: 700;
    color: #b45309; text-transform: uppercase; letter-spacing: .04em;
}

/* Diálogo de confirmación propio (nada de confirm() del navegador) */
.modal-confirmar { max-width: 420px; }
.modal-confirmar h3 { margin-bottom: 8px; }
.confirmar-detalle {
    margin: 4px 0 0; padding: 11px 14px;
    background: var(--rojo-velo); border-radius: var(--radio-s);
    font-size: .88rem; color: var(--tinta);
}
.confirmar-detalle p { margin: 0; }
.modal-confirmar .modal-acciones { border-top: none; }

.brindis.saliendo { opacity: 0; transform: translateX(-50%) translateY(8px); transition: opacity .35s, transform .35s; }
.brindis.error { background: var(--rojo); }

@media (max-width: 860px) {
    .modal-confirmar { border-radius: 18px; margin: 0 12px 12px; }
    .modal-fondo:has(.modal-confirmar) { align-items: center; padding: 16px; }
}

/* Parejas dentro del diagrama de relaciones */
.dt-envoltura { width: 100%; display: flex; flex-direction: column; gap: 3px; }

.dt-pareja {
    display: flex; align-items: center; gap: 7px;
    margin-left: 14px;
    padding: 5px 10px;
    background: var(--papel-2);
    border: 1px dashed var(--borde-fuerte);
    border-left: 3px solid var(--neutro);
    border-radius: 8px;
    cursor: pointer;
    transition: background .16s, border-color .16s;
}
.dt-pareja:hover { background: var(--acento-velo); border-color: var(--acento); }
.dt-pareja.sexo-H { border-left-color: var(--varon); }
.dt-pareja.sexo-M { border-left-color: var(--mujer); }
/* Si además es de la familia, línea continua: la sangre sí pasa por ahí. */
.dt-pareja.de-sangre { border-style: solid; background: var(--acento-velo); }

.dt-lazo { color: var(--ambar); font-size: .9rem; line-height: 1; flex-shrink: 0; }
.dt-pareja-texto { min-width: 0; }
.dt-pareja .dt-nombre {
    font-size: .8rem; font-weight: 500; color: var(--tinta-suave);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dt-rol { font-size: .68rem; color: var(--tinta-tenue); }

@media (max-width: 860px) {
    .dt-pareja { margin-left: 8px; padding: 4px 7px; gap: 5px; }
    .dt-pareja .dt-nombre { font-size: .72rem; }
    .dt-rol { font-size: .62rem; }
}

/* Propagación de apellidos a la descendencia */
.propagacion-cuerpo { max-height: 52vh; overflow-y: auto; margin-top: 6px; }

.propagacion-bloque { margin-bottom: 18px; }
.propagacion-cabecera { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.propagacion-cabecera h4 {
    margin: 0; font-family: var(--fuente-ui);
    font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--tinta-tenue);
}
.propagacion-bloque.huecos .propagacion-cabecera h4 { color: var(--acento-hondo); }
.propagacion-bloque.discrepancias .propagacion-cabecera h4 { color: #b45309; }
.propagacion-cabecera .mini-boton { margin-left: auto; background: var(--papel-2); }

.propagacion-nota {
    margin: 0 0 8px; padding: 8px 12px;
    background: var(--papel-2); border-radius: var(--radio-s);
    font-size: .82rem; color: var(--tinta-suave);
}
.propagacion-bloque.discrepancias .propagacion-nota {
    background: var(--ambar-velo); color: #7c4a06;
}

.propagacion-fila {
    display: flex; align-items: flex-start; gap: 11px;
    padding: 9px 12px; margin-bottom: 5px;
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: var(--radio-s); cursor: pointer;
    transition: border-color .14s, background .14s;
}
.propagacion-fila:hover { border-color: var(--acento); background: var(--acento-velo); }
.propagacion-fila input { width: 18px; height: 18px; margin-top: 2px; accent-color: var(--acento); flex-shrink: 0; }
.propagacion-texto { min-width: 0; }

.pg-nombre { font-weight: 600; font-size: .9rem; }
.pg-cambio { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 3px; font-size: .84rem; }
.pg-campo { color: var(--tinta-tenue); font-size: .74rem; text-transform: uppercase; letter-spacing: .04em; }
.pg-antes {
    padding: 1px 8px; border-radius: 6px;
    background: var(--rojo-velo); color: #9f1239;
    text-decoration: line-through;
}
.pg-vacio { padding: 1px 8px; border-radius: 6px; background: var(--papel-2); color: var(--tinta-tenue); font-style: italic; }
.pg-flecha { color: var(--tinta-tenue); }
.pg-despues { padding: 1px 8px; border-radius: 6px; background: var(--acento-velo); color: var(--acento-hondo); font-weight: 650; }
.pg-via { font-size: .74rem; color: var(--tinta-tenue); margin-top: 2px; }

@media (max-width: 860px) {
    .propagacion-cuerpo { max-height: none; }
    .pg-cambio { font-size: .8rem; }
}

/* Huecos rellenables en Ascendencia y Abanico */
.casilla.rellenable {
    cursor: pointer;
    border-color: color-mix(in srgb, var(--acento) 45%, var(--borde-fuerte));
}
.casilla.rellenable:hover {
    background: var(--acento-velo);
    border-color: var(--acento); border-style: solid;
    transform: translateX(3px);
}
.casilla.rellenable .casilla-vacia { color: var(--acento); }

.sector.rellenable:hover path { fill: var(--acento-velo) !important; }
.sector-mas {
    font-size: 15px; font-weight: 700; fill: var(--acento);
    text-anchor: middle; dominant-baseline: middle; pointer-events: none; opacity: .55;
}
.sector.rellenable:hover .sector-mas { opacity: 1; }


/* ==========================================================================
   Ficha de persona: cabecera compacta para dejar sitio al contenido
   ========================================================================== */

.ficha-cabecera { margin-bottom: 2px; }

.fc-linea1 { display: flex; align-items: flex-start; gap: 10px; }
.fc-linea1 h2 {
    flex: 1; min-width: 0; margin: 0;
    font-size: 1.22rem; line-height: 1.2;
}
.fc-cerrar {
    flex-shrink: 0;
    width: 30px; height: 30px; margin-top: -2px;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--borde); border-radius: 50%;
    background: var(--papel); color: var(--tinta-suave);
    font-size: .8rem; cursor: pointer;
    transition: background .14s, color .14s, border-color .14s;
}
.fc-cerrar:hover { background: var(--fondo-2); color: var(--tinta); border-color: var(--borde-fuerte); }

.fc-linea2 {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin-top: 3px;
}
.fc-anios { font-size: .84rem; color: var(--tinta-tenue); font-variant-numeric: tabular-nums; }

/* El parentesco es ahora un botón: al pulsarlo se abre el diagrama, así que
   la explicación larga ya no necesita ocupar una línea propia. */
.fc-chip {
    padding: 3px 11px; border: none; border-radius: 20px;
    background: var(--acento); color: #fff;
    font-family: var(--fuente-ui); font-size: .78rem; font-weight: 650;
    cursor: pointer; transition: transform .14s var(--curva), box-shadow .16s;
}
.fc-chip:hover:not(:disabled) { transform: translateY(-1px); box-shadow: var(--sombra-acento); }
.fc-chip.yo { background: var(--ambar); cursor: default; }
.fc-chip:disabled { opacity: 1; }

/* En escritorio el panel también reparte el alto: el contenido crece y las
   acciones se quedan abajo, en vez de dejar medio panel vacío. */
@media (min-width: 861px) {
    .panel-lateral { display: flex; flex-direction: column; }
    .panel-lateral > .ficha-cabecera,
    .panel-lateral > .pestañas,
    .panel-lateral > .acciones-ficha { flex-shrink: 0; }
    .panel-lateral > .paneles {
        flex: 1; min-height: 0; overflow-y: auto;
        padding-right: 2px;
    }
    .panel-lateral > .acciones-ficha {
        display: grid; grid-template-columns: 1fr auto; gap: 8px;
        margin: 12px -24px 0; padding: 12px 24px 0;
        border-top: 1px solid var(--borde);
    }
}


/* El diagrama nunca debe desbordar el modal */
.diagrama, .diagrama-rejilla { max-width: 100%; }
.dg-celda { min-width: 0; }
.diagrama-tarjeta { min-width: 0; overflow-wrap: anywhere; }
.dt-nombre, .dt-anios { overflow-wrap: anywhere; }
#diagrama-cuerpo { overflow-x: hidden; }

/* ==========================================================================
   Vista de lista
   ========================================================================== */

.lista-cabecera {
    display: flex; align-items: flex-end; gap: 18px; flex-wrap: wrap;
    margin-bottom: 16px;
}
.lista-buscador { display: flex; gap: 7px; margin-left: auto; }
.lista-buscador input {
    padding: 7px 13px; min-width: 220px;
    border: 1px solid var(--borde-fuerte); border-radius: 20px;
    background: var(--papel); color: var(--tinta); font-size: .87rem;
}
.lista-buscador input:focus { outline: none; border-color: var(--acento); box-shadow: 0 0 0 4px var(--acento-velo); }

.lista-filtros { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 13px; }
.filtro-pastilla {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 11px; border-radius: 20px;
    border: 1px solid var(--borde); background: var(--papel);
    color: var(--tinta-suave); font-size: .79rem; font-weight: 550;
    text-decoration: none; transition: all .14s var(--curva);
}
.filtro-pastilla:hover { border-color: var(--acento); color: var(--acento-hondo); text-decoration: none; }
.filtro-pastilla.activo { background: var(--acento); border-color: var(--acento); color: #fff; }
.filtro-cuenta {
    padding: 0 6px; border-radius: 20px;
    background: var(--fondo-2); color: var(--tinta-tenue);
    font-size: .7rem; font-variant-numeric: tabular-nums;
}
.filtro-pastilla.activo .filtro-cuenta { background: rgba(255,255,255,.25); color: #fff; }

/* La lista es para RECORRERLA con la vista, no para leerla renglón a renglón:
   con la tipografía de párrafo y el relleno de una tabla normal, cada fila
   pesaba tanto que en pantalla cabían pocas y todo se veía apretujado. Aquí
   todo baja un punto —tipo, relleno y marcas— y la última columna deja de
   llevar un botón de texto por fila. */
.tabla-lista { font-size: .85rem; }
.tabla-lista th, .tabla-lista td { padding: 7px 9px; }
.tabla-lista th { font-size: .68rem; letter-spacing: .06em; }
.tabla-lista th a { color: var(--tinta-tenue); text-decoration: none; }
.tabla-lista th a:hover { color: var(--acento-hondo); }
.tabla-lista th a.orden-activo { color: var(--acento-hondo); font-weight: 700; }
.tabla-lista tr.fila-ego { background: var(--acento-velo); }

.lista-nombre {
    display: inline-flex; align-items: center; gap: 7px;
    font-weight: 600; color: var(--tinta);
}
.punto-sexo { width: 7px; height: 7px; border-radius: 50%; background: var(--neutro); flex-shrink: 0; }
.punto-sexo.sexo-H { background: var(--varon); }
.punto-sexo.sexo-M { background: var(--mujer); }

.marca-lista {
    display: inline-block; margin-left: 5px;
    padding: 0 6px; border-radius: 20px;
    font-size: .61rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}
.marca-lista.tu { background: var(--ambar); color: #fff; }
/* La marca de duplicado es un ENLACE para quien puede resolverlo: lleva a
   Coincidencias, que es donde se decide. */
.marca-lista.repe { background: var(--ambar-velo); color: #b45309; text-decoration: none; }
a.marca-lista.repe:hover { background: var(--ambar); color: #fff; text-decoration: none; }
.marca-lista.suelto { background: var(--neutro-velo); color: var(--tinta-tenue); }

.tabla-lista .etiqueta-estado { padding: 2px 8px; font-size: .7rem; }

/* «Ver» era la palabra más repetida de la pantalla —una por fila— y se comía
   una columna entera para decir siempre lo mismo. Ahora es el mismo icono del
   árbol que hay en el menú, con su rótulo accesible: la columna se encoge a lo
   que ocupa el círculo y la fila respira. */
.lista-ver {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; padding: 0;
    border: 1px solid var(--borde-fuerte); border-radius: 50%;
    background: var(--papel); color: var(--tinta-suave);
    transition: border-color .14s, color .14s, background .14s;
}
.lista-ver svg { width: 15px; height: 15px; }
.lista-ver:hover {
    background: var(--papel-2); border-color: var(--acento); color: var(--acento-hondo);
    text-decoration: none;
}
.tabla-lista td.lista-acciones {
    width: 1%; padding-left: 0; white-space: nowrap; text-align: right;
}

/* Las columnas de la lista, por clase. Iban con `style=` en cada celda, así que
   cada persona pintada arrastraba cinco estilos en línea: en un árbol de 300
   son mil quinientos, imposibles de cambiar de una vez y que ninguna regla de
   la hoja podía tocar. */
.lista-cabecera h1 { margin-bottom: 2px; }
.lista-resumen { color: var(--tinta-tenue); font-size: .9rem; margin: 0; }
.tabla-lista .lista-anios { color: var(--tinta-tenue); white-space: nowrap; }
.tabla-lista .lista-lugar { color: var(--tinta-suave); }
.tabla-lista .lista-familia {
    color: var(--tinta-tenue); white-space: nowrap; font-size: .82rem;
}

.paginacion {
    display: flex; align-items: center; justify-content: center; gap: 14px;
    margin: 20px 0 40px; color: var(--tinta-tenue); font-size: .88rem;
}

@media (max-width: 860px) {
    .ocultar-movil { display: none; }
    .tabla-lista { font-size: .82rem; }
    .tabla-lista th, .tabla-lista td { padding: 6px 7px; }
    .lista-buscador { margin-left: 0; width: 100%; }
    .lista-buscador input { min-width: 0; flex: 1; }
    .lista-filtros { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 4px; scrollbar-width: none; }
    .lista-filtros::-webkit-scrollbar { display: none; }
    .filtro-pastilla { flex-shrink: 0; }
}

/* ==========================================================================
   Antepasados comunes: la PAREJA de la que desciende todo
   ========================================================================== */

/* El enlace ∞ ocupa la columna central, a la misma altura que las dos
   tarjetas, con la barra que las une y el tramo que baja hacia los hijos. */
.dg-enlace-raiz { position: relative; }
.dg-enlace-raiz::before {
    content: ""; position: absolute; left: -2px; right: -2px; top: 50%;
    height: 2px; margin-top: -1px; background: var(--ambar);
}
.dg-raiz-simbolo {
    position: relative; z-index: 1;
    display: flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 50%;
    background: var(--ambar-velo);
    border: 1.5px solid color-mix(in srgb, var(--ambar) 45%, transparent);
    color: var(--ambar); font-size: .95rem; line-height: 1;
}

/* Tramo vertical bajo la unión, antes de repartirse en las dos ramas */
.dg-puente-raiz { position: relative; min-height: 20px; }
.dg-puente-raiz::before {
    content: ""; position: absolute; left: 50%; top: 0; bottom: 0;
    width: 2px; margin-left: -1px; background: var(--ambar);
}

/* Fila propia de la pareja política */
.dg-celda-pareja { flex-direction: column; align-items: stretch; }
.dt-union { align-self: center; color: var(--ambar); font-size: 1rem; line-height: 1; padding: 3px 0; }

/* ── Diagrama en pantallas estrechas ──────────────────────────────────── */
@media (max-width: 860px) {
    /* Los nombres largos rompían en tres líneas y disparaban la altura de la
       tarjeta. Se ajusta el cuerpo y se permite partir por sílabas. */
    .diagrama-tarjeta { padding: 7px 9px; border-left-width: 4px; }
    .dt-nombre { font-size: .8rem; line-height: 1.2; hyphens: auto; }
    .dt-anios { font-size: .68rem; }

    /* OJO: aquí había `align-items: flex-start`, que anulaba el `stretch` y
       dejaba a cada tarjeta con su propia altura según le faltara el año o
       tuviera el nombre más corto. Los niveles deben leerse en línea. */
    .dg-conector { min-height: 24px; }
    .dg-medio.con-diagonal { min-height: 44px; }
    .dg-etiqueta { padding: 0 5px; font-size: .66rem; }
    .dg-medio { min-height: 36px; }

    .dt-pareja.politica { padding: 6px 9px; }
    .dt-pareja.politica .dt-nombre { font-size: .78rem; }
    .dt-rol { font-size: .62rem; }
    .dt-union { font-size: .85rem; padding: 1px 0; }

    /* El modal del diagrama aprovecha todo el ancho disponible. */
    #modal-diagrama .modal { padding-left: 10px; padding-right: 10px; }
    #modal-diagrama .modal > h3 { font-size: 1.05rem; }
    #modal-diagrama .diagrama-explica { padding: 9px 11px; font-size: .82rem; }

    /* Los dos campos, uno encima del otro: en 360 px, en fila no cabe un
       nombre con dos apellidos y el intercambio deja de entenderse. */
    .dg-comparar { flex-direction: column; align-items: stretch; gap: 8px; padding: 10px; margin-bottom: 14px; }
    .dg-intercambiar { align-self: center; margin: 0; }
}

/* La pareja política, ya en su fila: se estira al ancho de su columna */
.dt-pareja.politica { width: 100%; }

/* En vertical, el enlace de la pareja raíz mantiene su disco pero sin barra */
@media (max-width: 860px) {
    .dg-enlace-raiz::before { left: 0; right: 0; }
    .dg-raiz-simbolo { width: 22px; height: 22px; font-size: .85rem; }
    .dg-puente-raiz { min-height: 16px; }
}

/* ==========================================================================
   Marco de aplicación: menú lateral fijo en PC, deslizante en móvil
   ========================================================================== */

.app-marco { display: flex; min-height: 100vh; min-height: 100dvh; }

.menu-lateral {
    flex-shrink: 0;
    width: 248px;
    display: flex; flex-direction: column;
    background: var(--papel);
    border-right: 1px solid var(--borde);
    padding: 16px 12px 12px;
    position: sticky; top: 0;
    height: 100vh; height: 100dvh;
    z-index: 50;
}

.ml-marca { display: flex; align-items: center; gap: 8px; padding: 0 6px 14px; }
.ml-marca .marca { font-size: 1.18rem; }
.ml-cerrar {
    display: none;
    margin-left: auto; width: 32px; height: 32px;
    border: 1px solid var(--borde); border-radius: 50%;
    background: var(--papel); color: var(--tinta-suave);
    font-size: .8rem; cursor: pointer;
}

/* ── Selector de árbol ─────────────────────────────────────────────── */

.selector-arbol { position: relative; margin-bottom: 14px; }

.sa-actual {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 10px 12px;
    background: var(--acento-velo);
    border: 1px solid color-mix(in srgb, var(--acento) 28%, transparent);
    border-radius: var(--radio-s);
    cursor: pointer; text-align: left;
    font-family: var(--fuente-ui);
    transition: background .16s, border-color .16s;
}
.sa-actual:hover, .sa-actual.desplegado { border-color: var(--acento); }
.sa-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sa-nombre {
    font-size: .9rem; font-weight: 650; color: var(--tinta); line-height: 1.25;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sa-detalle { font-size: .74rem; color: var(--tinta-tenue); }
.sa-flecha { color: var(--acento-hondo); font-size: .8rem; flex-shrink: 0; }
.sa-actual.desplegado .sa-flecha { transform: rotate(180deg); }

.sa-lista {
    position: absolute; left: 0; right: 0; top: calc(100% + 5px); z-index: 60;
    padding: 5px;
    background: var(--papel);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-3);
    max-height: 320px; overflow-y: auto;
    animation: subir .16s var(--curva) both;
}
.sa-opcion {
    display: flex; align-items: center; gap: 9px;
    padding: 8px 10px; border-radius: var(--radio-s);
    color: var(--tinta); text-decoration: none;
    transition: background .14s;
}
.sa-opcion:hover { background: var(--acento-velo); text-decoration: none; }
.sa-opcion.activo { background: var(--acento-velo); }
.sa-punto {
    width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
    background: var(--borde-fuerte);
}
.sa-opcion.activo .sa-punto { background: var(--acento); }
.sa-opcion.nuevo {
    margin-top: 4px; border-top: 1px solid var(--borde); border-radius: 0 0 var(--radio-s) var(--radio-s);
    color: var(--acento-hondo); font-size: .85rem; font-weight: 600;
    padding-top: 10px;
}

/* ── Navegación ────────────────────────────────────────────────────── */

.ml-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; overflow-y: auto; }
.ml-enlace {
    display: flex; align-items: center; gap: 11px;
    padding: 9px 12px; border-radius: var(--radio-s);
    color: var(--tinta-suave); font-size: .92rem; font-weight: 550;
    text-decoration: none;
    transition: background .14s, color .14s;
}
.ml-enlace svg { width: 18px; height: 18px; flex-shrink: 0; }
.ml-enlace:hover { background: var(--fondo-2); color: var(--tinta); text-decoration: none; }
.ml-enlace.activo { background: var(--acento-velo); color: var(--acento-hondo); font-weight: 650; }

/* ── Bloques plegables del menú ─────────────────────────────────────────
   «Otras vistas» y «Gestión» van en <details>, así que se abren y se cierran
   sin una línea de JS. La cabecera se pinta como un enlace más —mismo alto,
   mismo icono, misma sangría— porque en una lista de enlaces cualquier cosa
   con otra forma parece un error; lo que la distingue es el chevron. */

/* Nada de `display: contents` aquí: el ocultar/mostrar de <details> lo hace el
   navegador sobre sus propios hijos y con `contents` no todos se portan igual. */
.ml-grupo { display: flex; flex-direction: column; gap: 2px; }
.ml-grupo-cabecera {
    cursor: pointer;
    list-style: none;          /* fuera el triángulo del navegador */
    user-select: none;
}
.ml-grupo-cabecera::-webkit-details-marker { display: none; }
.ml-grupo-titulo { flex: 1; min-width: 0; }
.ml-chevron { display: flex; flex-shrink: 0; color: var(--tinta-tenue); }
.ml-chevron svg { width: 14px; height: 14px; transition: transform .18s var(--curva); }
.ml-grupo[open] > .ml-grupo-cabecera .ml-chevron svg { transform: rotate(90deg); }

/* Estás DENTRO del bloque: aunque se pliegue a mano, la cabecera lo dice. */
.ml-grupo-cabecera.dentro { color: var(--acento-hondo); }

/* Plegado, el número de dentro sube aquí; desplegado sobraría, porque ya se
   ve en su propio enlace. */
.ml-grupo[open] > .ml-grupo-cabecera .ml-grupo-avisos { display: none; }

/* Los hijos, con una guía a la izquierda: es lo que dice de un vistazo dónde
   empieza y dónde acaba el bloque. */
.ml-grupo-cuerpo {
    display: flex; flex-direction: column; gap: 2px;
    margin: 2px 0 4px 21px;
    padding-left: 8px;
    border-left: 1px solid var(--borde);
    animation: desplegar .16s var(--curva) both;
}
@keyframes desplegar { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.ml-grupo-cuerpo .ml-enlace { padding-top: 7px; padding-bottom: 7px; font-size: .89rem; }
.ml-grupo-cuerpo .ml-enlace svg { width: 16px; height: 16px; }

/* Ajustes se separa del resto: no es una sección del árbol. */
.ml-nav-separador {
    height: 1px; background: var(--borde);
    margin: 8px 12px 6px;
}

.ml-pie { padding: 12px 6px 0; border-top: 1px solid var(--borde); }
.ml-usuario {
    font-size: .82rem; color: var(--tinta-tenue); margin-bottom: 8px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ml-pie .boton { width: 100%; }

/* ── Contenido ─────────────────────────────────────────────────────── */

.app-contenido { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ⚠️ NINGUNA pantalla se estira más que la ventana.
   `.app-contenido` es un flex en columna, y ahí un hijo con contenido que no
   comprime —una tabla de cinco columnas con un correo largo— se lleva por
   delante todo el marco: el hijo se estiraba a su ancho natural y la PÁGINA
   ENTERA se desplazaba de lado, menú incluido. Medido en un móvil de 360 px:
   /lista pedía 745 px y /ajustes 581. En la aplicación instalada eso es lo que
   más delata que debajo hay una web, porque las aplicaciones no se mueven de
   lado; y el desplazamiento horizontal de la tabla, que ya estaba puesto, no
   llegaba a funcionar nunca —su marco crecía con ella—.
   Con este tope, lo ancho se desplaza DENTRO de su marco, que es lo suyo.
   Se comprueba con `node scripts/probar_anchos.js`. */
/* Con `.app-marco` delante a propósito: hay pantallas que declaran su propio
   ancho máximo más abajo en esta hoja, y a igualdad de peso ganaría la última.
   Este tope tiene que ganar siempre. */
.app-marco .app-contenido > * { min-width: 0; max-width: 100%; }
.barra-movil { display: none; }
.franja-aviso { padding: 14px 20px 0; }
.franja-aviso .aviso { margin-bottom: 0; }

.menu-fondo {
    position: fixed; inset: 0; z-index: 45;
    background: rgba(23, 34, 46, .42); backdrop-filter: blur(2px);
}

/* La pantalla del árbol ocupa el alto del marco, ya sin barra superior. */
body.pantalla-arbol .app-contenido { height: 100vh; height: 100dvh; overflow: hidden; }
body.pantalla-arbol .arbol-pantalla { height: 100%; flex: 1; min-height: 0; }

/* ── Móvil: el panel se desliza ────────────────────────────────────── */

@media (max-width: 900px) {
    .menu-lateral {
        position: fixed; left: 0; top: 0; bottom: 0;
        width: 270px; max-width: 84vw;
        transform: translateX(-100%);
        transition: transform .26s var(--curva);
        box-shadow: 6px 0 26px rgba(23, 34, 46, .16);
        padding-top: calc(16px + env(safe-area-inset-top));
    }
    .menu-lateral.abierto { transform: none; }
    .ml-cerrar { display: flex; align-items: center; justify-content: center; }

    body.menu-abierto { overflow: hidden; }

    /* Barra superior mínima: solo el botón del menú y el árbol activo. */
    .barra-movil {
        display: flex; align-items: center; gap: 12px;
        padding: 10px 14px; padding-top: calc(10px + env(safe-area-inset-top));
        background: color-mix(in srgb, var(--papel) 92%, transparent);
        backdrop-filter: saturate(1.6) blur(12px);
        border-bottom: 1px solid var(--borde);
        position: sticky; top: 0; z-index: 40;
        flex-shrink: 0;
    }
    .bm-menu {
        display: flex; flex-direction: column; justify-content: center; gap: 4px;
        width: 38px; height: 38px; padding: 0 8px;
        background: transparent; border: none; cursor: pointer;
    }
    .bm-menu span { display: block; height: 2px; background: var(--tinta); border-radius: 2px; }
    .bm-titulo {
        font-family: var(--fuente); font-size: 1rem; font-weight: 600;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }

    body.pantalla-arbol .arbol-pantalla { height: calc(100dvh - 59px); }
    .franja-aviso { padding: 12px 14px 0; }
}

/* ── Mis árboles ───────────────────────────────────────────────────── */

.rejilla-arboles {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px; margin-top: 22px;
}

.tarjeta-arbol {
    position: relative;
    display: flex; flex-direction: column;
    padding: 20px; background: var(--papel);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-1);
    transition: box-shadow .2s var(--curva), border-color .2s;
}
.tarjeta-arbol:hover { box-shadow: var(--sombra-2); }
.tarjeta-arbol.activo { border-color: var(--acento); box-shadow: 0 0 0 3px var(--acento-velo), var(--sombra-1); }
.tarjeta-arbol h3 { margin-bottom: 8px; font-size: 1.1rem; }

.ta-marca {
    position: absolute; top: 14px; right: 14px;
    padding: 2px 9px; border-radius: 20px;
    background: var(--acento); color: #fff;
    font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}

.ta-datos { display: flex; flex-direction: column; gap: 2px; margin-bottom: 14px; font-size: .85rem; color: var(--tinta-suave); }

.ta-acciones { margin-top: auto; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }

/* Pedir permiso desde «Mis árboles»: la caja va abajo del todo y con menos
   peso visual que las acciones, porque es lo que se hace UNA vez. */
.ta-pedir {
    margin-top: 12px; padding-top: 12px;
    border-top: 1px dashed var(--borde);
    display: flex; flex-direction: column; gap: 7px; align-items: flex-start;
}
.ta-pedir input {
    width: 100%; padding: 7px 10px;
    border: 1px solid var(--borde); border-radius: 8px;
    font: inherit; font-size: .88rem; background: var(--papel);
}
.ta-pedir input:focus {
    outline: none; border-color: var(--acento); box-shadow: 0 0 0 3px var(--acento-velo);
}
.ta-pedido {
    margin: 12px 0 0; padding-top: 12px;
    border-top: 1px dashed var(--borde);
    color: var(--tinta-suave); font-size: .87rem; line-height: 1.5;
}
.ta-acciones form { width: 100%; }

/* Eliminar el árbol. Va plegado y en gris: es lo único irreversible de la
   pantalla, así que no compite con «Abrir» ni con «Renombrar». Al desplegarlo
   sí se pone en rojo, que es cuando toca avisar. */
.ta-eliminar {
    margin-top: 12px; padding-top: 12px;
    border-top: 1px dashed var(--borde);
}
.ta-eliminar > summary {
    font-size: .84rem; color: var(--tinta-tenue); cursor: pointer;
    list-style: none;
}
.ta-eliminar > summary::-webkit-details-marker { display: none; }
.ta-eliminar > summary::before { content: '⌫ '; }
.ta-eliminar > summary:hover { color: var(--rojo); }
.ta-eliminar[open] > summary { color: var(--rojo); font-weight: 600; margin-bottom: 10px; }
.ta-eliminar-que {
    margin: 0 0 9px; font-size: .84rem; line-height: 1.5; color: var(--tinta-suave);
}
.ta-eliminar form { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; }
.ta-eliminar label { font-size: .84rem; color: var(--tinta-suave); }
.ta-eliminar input {
    width: 100%; padding: 7px 10px;
    border: 1px solid color-mix(in srgb, var(--rojo) 30%, var(--borde)); border-radius: 8px;
    font: inherit; font-size: .88rem; background: var(--papel);
}
.ta-eliminar input:focus {
    outline: none; border-color: var(--rojo); box-shadow: 0 0 0 3px var(--rojo-velo);
}
/* Renombrar, plegado y discreto: se hace una vez en la vida, y el campo
   siempre abierto con el nombre dentro se leía como un dato por rellenar. */
.ta-renombrar-caja { width: 100%; }
.ta-renombrar-caja > summary {
    font-size: .84rem; color: var(--tinta-tenue); cursor: pointer;
    list-style: none; padding: 2px 0;
}
.ta-renombrar-caja > summary::-webkit-details-marker { display: none; }
.ta-renombrar-caja > summary::before { content: "✎ "; }
.ta-renombrar-caja > summary:hover { color: var(--acento-hondo); }
.ta-renombrar-caja[open] > summary { color: var(--tinta-suave); margin-bottom: 8px; }

.ta-renombrar { display: flex; gap: 6px; }
.ta-renombrar input {
    flex: 1; min-width: 0; padding: 6px 10px;
    border: 1px solid var(--borde-fuerte); border-radius: var(--radio-s);
    background: var(--papel); color: var(--tinta); font-size: .85rem;
}
.ta-renombrar input:focus { outline: none; border-color: var(--acento); }

.tarjeta-arbol.nuevo { border-style: dashed; background: var(--papel-2); box-shadow: none; }
.tarjeta-arbol.nuevo .campo { margin-bottom: 10px; }

/* La diagonal que llega hasta quien consulta: es la respuesta a la pregunta,
   así que se ve distinta de los escalones intermedios. */
.diagrama-relacion.diagonal.final {
    background: var(--ambar);
    color: #fff;
    border-color: var(--ambar);
    border-style: solid;
    box-shadow: 0 2px 8px rgba(245, 158, 11, .35);
}


/* ==========================================================================
   Cabecera móvil y desplegables: que sigan la marca
   ========================================================================== */

@media (max-width: 900px) {
    .barra-movil {
        gap: 10px;
        background: linear-gradient(180deg,
                    color-mix(in srgb, var(--acento-velo) 70%, var(--papel)) 0%,
                    var(--papel) 100%);
        border-bottom: 1px solid color-mix(in srgb, var(--acento) 18%, var(--borde));
    }
    .bm-menu span { background: var(--acento-hondo); }

    .bm-marca {
        display: flex; align-items: center;
        color: var(--acento); flex-shrink: 0;
    }
    .bm-marca svg { width: 24px; height: 24px; }

    .bm-texto { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
    .bm-arbol {
        font-family: var(--fuente); font-size: 1rem; font-weight: 600; color: var(--tinta);
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .bm-detalle { font-size: .72rem; color: var(--tinta-tenue); }
}

/* ── Desplegables con la marca ─────────────────────────────────────── */
/* Los <select> nativos ignoran casi todo el estilo del sistema: se les quita
   la apariencia por defecto y se les pinta la flecha con un fondo SVG. */
select,
.campo select,
.selector-gen select,
.lista-buscador select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 34px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1.5 6 6.5l5-5' fill='none' stroke='%230b7f7e' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    font-family: var(--fuente-ui);
    color: var(--tinta);
    cursor: pointer;
}
select:hover { border-color: color-mix(in srgb, var(--acento) 45%, var(--borde-fuerte)); }

/* El selector de generaciones de Ascendencia y Abanico */
.selector-gen {
    padding: 4px 4px 4px 12px;
    background: var(--acento-velo);
    border: 1px solid color-mix(in srgb, var(--acento) 24%, transparent);
    border-radius: 22px;
    color: var(--acento-hondo);
}
.selector-gen select {
    border: none; background-color: var(--papel);
    border-radius: 18px; padding: 5px 30px 5px 12px;
    font-weight: 600; color: var(--acento-hondo);
}
.selector-gen select:focus { outline: none; box-shadow: 0 0 0 3px var(--acento-velo); }

/* La barra de las vistas también lleva la marca */
.barra-vista { border-color: color-mix(in srgb, var(--acento) 15%, var(--borde)); }
.barra-titulo strong { color: var(--tinta); }

/* ==========================================================================
   Instalar la aplicación
   --------------------------------------------------------------------------
   Tres piezas:
     · `.pwa-abrir`  — barra de arriba para quien YA la tiene instalada.
     · `.pwa-hoja`   — la invitación grande, anclada abajo.
     · `.pg-*`       — la guía paso a paso (iPhone, y navegadores sin botón).

   La invitación es grande a propósito. La barrita de una línea que había
   antes se confundía con un aviso de galletas y no la pulsaba nadie: si la
   aplicación es la forma buena de usar esto, hay que enseñarla como tal.
   ========================================================================== */

/* ── Ya instalada: abrir ────────────────────────────────────────────── */

.pwa-abrir {
    position: fixed; top: 0; left: 0; right: 0; z-index: 130;
    display: flex; align-items: center; gap: 11px;
    padding: 9px 12px;
    padding-top: calc(9px + env(safe-area-inset-top));
    background: linear-gradient(100deg, var(--acento-hondo), var(--acento));
    color: #fff;
    box-shadow: 0 2px 12px rgba(23, 34, 46, .18);
    animation: pwa-bajar .3s var(--curva) both;
}
@keyframes pwa-bajar { from { transform: translateY(-100%); } to { transform: none; } }

.pa-icono {
    flex-shrink: 0;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border-radius: 8px;
    background: rgba(255, 255, 255, .18);
}
.pa-icono svg { width: 17px; height: 17px; }

.pa-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.pa-texto strong { font-family: var(--fuente-ui); font-size: .86rem; }
/* Los dos textos en una línea cada uno: si envuelven, la barra crece hasta el
   doble y se come la cabecera de debajo. Lo que sobra se recorta. */
.pa-texto strong, .pa-texto span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pa-texto span { font-size: .74rem; opacity: .82; }

.pa-boton {
    flex-shrink: 0;
    white-space: nowrap;
    background: #fff !important;
    color: var(--acento-hondo) !important;
    box-shadow: none;
}
.pa-boton:hover { background: var(--acento-velo) !important; }

.pa-cerrar {
    flex-shrink: 0;
    width: 26px; height: 26px;
    border: none; border-radius: 50%;
    background: transparent; color: rgba(255, 255, 255, .8);
    font-size: .76rem; cursor: pointer;
}
.pa-cerrar:hover { background: rgba(255, 255, 255, .16); color: #fff; }

/* El rótulo largo del botón solo cabe con sitio de sobra. */
.pa-corto { display: none; }
@media (max-width: 480px) {
    .pa-largo { display: none; }
    .pa-corto { display: inline; }
    .pwa-abrir { gap: 9px; padding-left: 10px; padding-right: 10px; }
}

/* La barra empuja la página: si se superpone, tapa la cabecera fija. */
/* La barra empuja la página en vez de superponerse, y la cabecera pegajosa
   del escaparate baja con ella: si no, al desplazarse se metía por debajo.
   El hueco lo MIDE el JS (`--barra-abrir`) en vez de fijarlo aquí: entre el
   recorte de la pantalla del móvil y un texto más largo de la cuenta, la barra
   no mide siempre lo mismo, y con un número a ojo tapaba la cabecera. */
body.con-barra-abrir { padding-top: var(--barra-abrir, 52px); }
body.con-barra-abrir .cabecera { top: var(--barra-abrir, 52px); }

/* ── La invitación ──────────────────────────────────────────────────── */

.pwa-hoja {
    position: fixed; z-index: 140;
    left: 14px; right: 14px; bottom: 14px;
    max-width: 430px; margin: 0 auto;
    padding: 22px 22px 18px;
    padding-bottom: calc(18px + env(safe-area-inset-bottom));
    background: var(--papel);
    border: 1px solid color-mix(in srgb, var(--acento) 26%, var(--borde));
    border-radius: 20px;
    box-shadow: var(--sombra-3), 0 0 0 4px rgba(14, 165, 164, .07);
    opacity: 0; transform: translateY(22px) scale(.985);
    transition: opacity .26s var(--curva), transform .26s var(--curva);
}
.pwa-hoja.visible { opacity: 1; transform: none; }

/* Cinta de marca arriba: es lo que la distingue de un aviso del sistema. */
.pwa-hoja::before {
    content: '';
    position: absolute; top: 0; left: 22px; right: 22px; height: 3px;
    border-radius: 0 0 3px 3px;
    background: linear-gradient(90deg, var(--acento), var(--ambar));
}

.pwa-cerrar {
    position: absolute; top: 10px; right: 10px;
    width: 30px; height: 30px;
    border: none; border-radius: 50%;
    background: transparent; color: var(--tinta-tenue);
    font-size: .82rem; cursor: pointer;
    transition: background .15s, color .15s;
}
.pwa-cerrar:hover { background: var(--fondo-2); color: var(--tinta); }

.pwa-cabecera { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }

.pwa-icono {
    width: 60px; height: 60px; flex-shrink: 0;
    border-radius: 14px;
    box-shadow: var(--sombra-2);
}
.pwa-titulos h2 { font-size: 1.24rem; margin: 0 0 2px; line-height: 1.15; }
.pwa-titulos p { margin: 0; font-size: .85rem; color: var(--tinta-suave); }

.pwa-ventajas { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 11px; }
.pwa-ventajas li { display: flex; align-items: flex-start; gap: 11px; }

.pv-icono {
    flex-shrink: 0;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border-radius: 9px;
    background: var(--acento-velo); color: var(--acento-hondo);
}
.pv-icono svg { width: 16px; height: 16px; }

.pv-texto { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.pv-texto strong { font-family: var(--fuente-ui); font-size: .85rem; }
.pv-texto span { font-size: .78rem; color: var(--tinta-suave); }

.pwa-acciones { display: grid; gap: 8px; }
.pwa-acciones.fila { grid-template-columns: auto 1fr; align-items: center; gap: 10px; }

/* Botón ancho de verdad: es la acción de toda la hoja. */
.pwa-principal {
    width: 100%;
    justify-content: center;
    padding: 13px 18px;
    font-size: 1rem;
    border-radius: 12px;
    box-shadow: var(--sombra-acento);
}

.pwa-luego {
    border: none; background: transparent;
    color: var(--tinta-tenue);
    font-family: var(--fuente-ui); font-size: .84rem;
    padding: 9px; border-radius: 9px; cursor: pointer;
}
.pwa-luego:hover { background: var(--fondo-2); color: var(--tinta); }

/* ── Guía paso a paso ───────────────────────────────────────────────── */

.pwa-hoja.pwa-guia { text-align: center; }

.pg-puntos { display: flex; justify-content: center; gap: 6px; margin-bottom: 9px; }
.pg-punto {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--borde-fuerte);
    transition: background .2s, width .2s;
}
.pg-punto.hecho { background: var(--acento); }
.pg-punto.activo { width: 20px; border-radius: 4px; background: var(--acento); }

.pg-numero {
    display: block;
    font-family: var(--fuente-ui); font-size: .7rem; letter-spacing: .06em;
    text-transform: uppercase; color: var(--tinta-tenue);
    margin-bottom: 14px;
}

.pg-ilustracion {
    width: 74px; height: 74px; margin: 0 auto 14px;
    display: grid; place-items: center;
    border-radius: 20px;
    background: var(--acento-velo); color: var(--acento-hondo);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--acento) 22%, transparent);
}
.pg-icono { width: 36px; height: 36px; }

.pg-titulo { font-size: 1.14rem; margin: 0 0 6px; line-height: 1.2; }
.pg-texto { margin: 0 0 16px; font-size: .87rem; color: var(--tinta-suave); line-height: 1.45; }

/* Señala la barra de Safari, que está justo debajo de la hoja. */
.pg-flecha {
    margin: -6px 0 12px;
    color: var(--acento);
    font-size: 1.1rem;
    animation: pg-señalar 1.3s ease-in-out infinite;
}
@keyframes pg-señalar {
    0%, 100% { transform: translateY(0); opacity: .55; }
    50%      { transform: translateY(6px); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .pwa-hoja, .pwa-abrir { animation: none; transition: none; }
    .pg-flecha { animation: none; }
}

/* En pantallas anchas la hoja se centra: abajo del todo, en un monitor
   grande, queda en una esquina que no mira nadie. */
@media (min-width: 780px) {
    .pwa-hoja {
        left: 50%; right: auto; bottom: auto; top: 50%;
        transform: translate(-50%, calc(-50% + 18px)) scale(.985);
        width: 400px;
    }
    .pwa-hoja.visible { transform: translate(-50%, -50%); }
}

/* ── Enlace permanente del pie y del menú ───────────────────────────── */

.enlace-instalar {
    display: inline-flex; align-items: center; gap: 6px;
    border: none; background: transparent;
    color: inherit; font: inherit; cursor: pointer;
    padding: 0; text-decoration: none;
}
.enlace-instalar:hover { color: var(--acento); }

.ml-instalar {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    width: 100%;
    margin-bottom: 9px; padding: 9px 10px;
    border: 1px solid color-mix(in srgb, var(--acento) 34%, var(--borde));
    border-radius: var(--radio-s);
    background: var(--acento-velo); color: var(--acento-hondo);
    font-family: var(--fuente-ui); font-size: .8rem; font-weight: 600;
    cursor: pointer;
}
.ml-instalar:hover { background: color-mix(in srgb, var(--acento) 16%, var(--papel)); }

/* El mismo botón, cuando lo que se ofrece es ABRIR la aplicación ya instalada
   en vez de instalarla: dentro de la sesión no cabe la barra de arriba, que
   descuadraría el alto del lienzo. */
.ml-instalar.ml-abrir {
    background: var(--acento); color: #fff;
    border-color: var(--acento-hondo);
}
.ml-instalar.ml-abrir:hover { background: var(--acento-hondo); }

/* Instalada: se aprovecha el hueco de la barra de estado del sistema. */
@media (display-mode: standalone) {
    .barra-movil { padding-top: calc(10px + env(safe-area-inset-top)); }
    .menu-lateral { padding-top: calc(16px + env(safe-area-inset-top)); }
}

/* ==========================================================================
   Cabecera pública en móvil y modo aplicación
   ========================================================================== */

.solo-estrecho { display: none; }

@media (max-width: 640px) {
    /* La barra deja de desplazarse: con marca, «Entrar» y «Crear cuenta»
       hay de sobra, y «Cómo funciona» baja al pie y al botón de la portada. */
    .cabecera-publica { padding: 10px 12px; gap: 6px; }
    .cabecera-publica .marca { font-size: 1.02rem; gap: 6px; }
    .cabecera-publica .marca svg { width: 22px; height: 22px; }
    .cabecera-publica .nav { gap: 2px; flex-shrink: 0; }
    .cabecera-publica .nav a { padding: 7px 8px; font-size: .84rem; }
    /* Sin translate al pasar el dedo: en el borde derecho el botón se salía. */
    .cabecera-publica .nav .boton { padding: 8px 13px; font-size: .84rem; }
    .cabecera-publica .nav .boton:hover { transform: none; }
    .solo-ancho { display: none; }
    .solo-estrecho { display: inline; }

    .heroe { padding: 36px 0 30px; }
    .heroe h1 { font-size: 1.9rem; }
    .heroe .entradilla { font-size: .98rem; margin-bottom: 24px; }
    .heroe .acciones { flex-direction: column; align-items: center; gap: 10px; }
    .heroe .acciones .boton { width: 100%; max-width: 300px; }

    /* Los tres datos, en fila: apilados se comían media pantalla. */
    .franja-datos {
        display: grid; grid-template-columns: repeat(3, 1fr);
        gap: 10px; padding: 18px 0; margin: 26px 0;
    }
    .dato .cifra { font-size: 1.02rem; line-height: 1.25; }
    .dato .etiqueta { font-size: .62rem; letter-spacing: .04em; }

    .rejilla-3 { gap: 14px; margin: 34px 0; }
    .caracteristica { padding: 20px; }

    .pie { margin-top: 44px; }
    .pie .contenedor { justify-content: center; text-align: center; gap: 14px; }
}

/* Instalada como aplicación: fuera el escaparate, pero «Crear cuenta» se
   queda: alguien puede instalarla primero y registrarse después. */
.como-app .cabecera-publica .nav .solo-ancho,
.como-app .pie .solo-estrecho { display: none; }
.como-app .pie { margin-top: 28px; }

/* ==========================================================================
   Barras de desplazamiento ocultas
   --------------------------------------------------------------------------
   Se puede desplazar igual —rueda, dedo, teclado—, pero la barra no se pinta:
   en una aplicación de pantalla completa ensucia, sobre todo en los paneles
   estrechos y en las listas dentro de los diálogos.
   ========================================================================== */

* { scrollbar-width: none; -ms-overflow-style: none; }
*::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ==========================================================================
   Acceso dentro de la aplicación instalada
   --------------------------------------------------------------------------
   Aquí no hay nada que vender: quien abre la aplicación quiere entrar. Se
   quita la cabecera de escaparate y la pantalla se ocupa entera, sin
   desplazamiento vertical.
   ========================================================================== */

.como-app.pantalla-acceso .cabecera-publica,
.como-app.pantalla-acceso .pie { display: none; }

.como-app.pantalla-acceso {
    min-height: 100dvh;
    background: linear-gradient(170deg, var(--acento-velo) 0%, var(--fondo) 46%);
}
.como-app.pantalla-acceso main {
    min-height: 100dvh;
    display: flex; flex-direction: column; justify-content: center;
    padding: 20px 18px calc(20px + env(safe-area-inset-bottom));
    padding-top: calc(20px + env(safe-area-inset-top));
}

/* La marca preside la pantalla, en lugar de la barra de navegación. */
.como-app.pantalla-acceso main::before {
    content: "";
    display: block;
    width: 76px; height: 76px;
    margin: 0 auto 10px;
    background: var(--acento);
    /* La máscara recorta el color con la forma del logo: se ve el árbol en
       turquesa, sin depender de que cargue ninguna imagen de color. */
    -webkit-mask: url("/assets/img/miorigo.svg") center / 62px 62px no-repeat;
    mask: url("/assets/img/miorigo.svg") center / 62px 62px no-repeat;
}
.como-app.pantalla-acceso main::after {
    content: "MiOrigo";
    display: block; order: -1;              /* el nombre, bajo el icono */
    margin: 0 auto 22px;
    font-family: var(--fuente); font-size: 1.45rem; font-weight: 600;
    color: var(--tinta); letter-spacing: -.02em; text-align: center;
}

.como-app.pantalla-acceso .panel-acceso {
    margin: 0 auto;
    width: 100%; max-width: 400px;
    padding: 26px 22px;
    border-radius: 18px;
    box-shadow: var(--sombra-2);
    animation: none;
}
.como-app.pantalla-acceso .panel-acceso h1 { font-size: 1.42rem; text-align: center; }
.como-app.pantalla-acceso .panel-acceso .sub { text-align: center; margin-bottom: 20px; }

/* Formulario más compacto para que quepa sin desplazar. */
.como-app.pantalla-acceso .campo { margin-bottom: 13px; }
.como-app.pantalla-acceso .campo label { margin-bottom: 4px; font-size: .82rem; }
.como-app.pantalla-acceso .campo input { padding: 11px 13px; }
.como-app.pantalla-acceso .campos-fila { gap: 10px; }
.como-app.pantalla-acceso .aviso { padding: 10px 13px; font-size: .88rem; }

/* El icono de la marca no debe verse dos veces. */
.como-app.pantalla-acceso .panel-acceso .marca { display: none; }

/* Pantallas bajas: la marca y los espacios ceden para que el acceso quepa
   entero. El registro tiene cinco campos y en un móvil pequeño acabará
   desplazándose de todos modos; al menos la barra no se ve. */
@media (max-height: 720px) {
    .como-app.pantalla-acceso main { padding-top: calc(12px + env(safe-area-inset-top)); }
    .como-app.pantalla-acceso main::before { width: 56px; height: 56px; margin-bottom: 6px;
        -webkit-mask-size: 46px 46px; mask-size: 46px 46px; }
    .como-app.pantalla-acceso main::after { font-size: 1.2rem; margin-bottom: 14px; }
    .como-app.pantalla-acceso .panel-acceso { padding: 20px 18px; }
    .como-app.pantalla-acceso .panel-acceso h1 { font-size: 1.28rem; margin-bottom: 4px; }
    .como-app.pantalla-acceso .panel-acceso .sub { margin-bottom: 15px; font-size: .88rem; }
    .como-app.pantalla-acceso .campo { margin-bottom: 11px; }
}

@media (max-height: 620px) {
    .como-app.pantalla-acceso main::before { width: 44px; height: 44px; margin-bottom: 4px;
        -webkit-mask-size: 36px 36px; mask-size: 36px 36px; }
    .como-app.pantalla-acceso main::after { font-size: 1.05rem; margin-bottom: 10px; }
    .como-app.pantalla-acceso .panel-acceso { padding: 16px 16px; }
    .como-app.pantalla-acceso .panel-acceso .sub { margin-bottom: 12px; }
    .como-app.pantalla-acceso .campo { margin-bottom: 9px; }
    .como-app.pantalla-acceso .campo label { margin-bottom: 3px; }
    .como-app.pantalla-acceso .campo input { padding: 9px 12px; }
    .como-app.pantalla-acceso .campo .ayuda { display: none; }
}

/* ── Participantes del árbol ──────────────────────────────────────────── */

.pagina-participantes { padding: 28px 24px 48px; max-width: 940px; }
.pp-entradilla { color: var(--tinta-suave); margin-top: -6px; max-width: 62ch; }

.pp-titulo {
    display: flex; align-items: center; gap: 10px;
    margin: 34px 0 14px; font-size: 1.12rem;
}
.pp-cuenta {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 26px; height: 22px; padding: 0 7px;
    background: var(--acento-velo); color: var(--acento-hondo);
    border-radius: 20px; font-size: .78rem; font-weight: 700;
}

/* ⚠️ Los participantes van en TABLA y no en tarjetas. Con una ficha grande por
   cabeza, comparar quién aporta qué obligaba a recorrer la pantalla entera; en
   filas, cada columna se lee en vertical de un vistazo. La tabla es ancha, así
   que se desplaza dentro de su marco: la página nunca se mueve en horizontal. */

.pp-tabla-marco { overflow-x: auto; border-radius: var(--radio); }
.pp-tabla {
    width: 100%; border-collapse: collapse;
    background: var(--papel);
    border: 1px solid var(--borde); border-radius: var(--radio);
    font-size: .9rem;
}
.pp-tabla thead th {
    padding: 10px 12px; text-align: left; vertical-align: bottom;
    background: var(--fondo);
    border-bottom: 1px solid var(--borde);
    font-size: .74rem; font-weight: 700; color: var(--tinta-suave);
    text-transform: uppercase; letter-spacing: .04em; white-space: nowrap;
}
.pp-tabla tbody td {
    padding: 11px 12px; vertical-align: middle;
    border-bottom: 1px solid var(--borde);
}
.pp-tabla tbody tr:last-child td { border-bottom: 0; }
.pp-tabla tbody tr:hover td { background: var(--fondo); }
.pp-tabla tbody tr.soy-yo td { background: color-mix(in srgb, var(--acento-velo) 45%, transparent); }

/* Quién: el nombre manda y el correo va debajo, en pequeño. Es la columna que
   se lee primero, así que es la única que puede partirse en varias líneas. */
.pp-tabla .pt-quien { min-width: 210px; }
.pt-nombre {
    display: flex; align-items: center; gap: 7px;
    font-weight: 700; color: var(--tinta);
}
.pt-email { display: block; font-size: .8rem; color: var(--tinta-tenue); }
.pt-sitio { display: block; margin-top: 2px; font-size: .78rem; color: var(--tinta-suave); }

/* Las columnas de aportaciones: número grande, y un punto gris cuando es cero.
   Un «0» repetido en toda la fila pesa lo mismo que un dato y no lo es. */
.pp-tabla .pt-n { text-align: center; width: 54px; }
.pt-icono, .pt-rotulo { display: none; }
.pp-tabla tbody .pt-n { font-variant-numeric: tabular-nums; font-weight: 600; }
.pp-tabla tbody .pt-n.cero { color: var(--borde-fuerte); font-weight: 400; }
.pp-tabla thead .pt-n svg { width: 18px; height: 18px; display: block; margin: 0 auto; }
.pp-tabla .pt-total { font-weight: 800; color: var(--acento-hondo); }
.pp-tabla .pt-total-cab { color: var(--acento-hondo); }
.pp-tabla .pt-cuando { white-space: nowrap; font-size: .82rem; color: var(--tinta-tenue); }

/* El rótulo del texto de cada icono: lo leen los lectores de pantalla, y en la
   pantalla lo dice el `title`.
   ⚠️ Su celda va `relative` para que el rótulo se ancle A ELLA. Sin eso, al ser
   `absolute`, se colocaba respecto a la página entera y ESCAPABA del marco de
   desplazamiento de la tabla: la tabla se desplazaba bien dentro de su caja,
   pero el rótulo invisible del último encabezado seguía estando a 1053 px y
   arrastraba a toda la página en horizontal. Un elemento de un píxel movía la
   pantalla entera. */
.pp-tabla th, .pp-tabla td { position: relative; }
.pt-oculto {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
}

/* ⚠️ **La columna de acciones va FIJA a la derecha.** Es lo único con lo que
   se actúa en esta pantalla —cambiar el permiso, retirar el acceso, reenviar
   una invitación— y se quedaba fuera del marco: la tabla pide 1039 px y a
   1280 el marco tiene 984, así que el selector de permiso NO SE VEÍA. Y en un
   portátil de 900 sobraban 187 px. Entre los 760 en que la tabla se apila y
   los ~1550 en que cabe entera —o sea, en casi cualquier portátil— la acción
   principal estaba escondida detrás de un desplazamiento que nada anunciaba.
   Fijándola, las columnas de aportación se desplazan por debajo y lo que se
   pulsa está siempre a la vista.

   El fondo tiene que ser OPACO: una celda fija es lo único que se queda
   quieto, y con fondo transparente se le pintan encima las columnas que pasan
   por debajo. Por eso el resalte de la fila propia se mezcla aquí contra
   `--papel` en vez de contra `transparent`. */
.pp-tabla .pt-acciones {
    width: 1%; white-space: nowrap; text-align: right;
    position: sticky; right: 0; z-index: 2;
    background: var(--papel);
    box-shadow: -12px 0 14px -12px rgba(23, 34, 46, .28);
}
.pp-tabla thead .pt-acciones { background: var(--fondo); z-index: 3; }
.pp-tabla tbody tr:hover .pt-acciones { background: var(--fondo); }
.pp-tabla tbody tr.soy-yo .pt-acciones {
    background: color-mix(in srgb, var(--acento-velo) 45%, var(--papel));
}
.pt-acciones select {
    padding: 6px 9px; font: inherit; font-size: .82rem;
    color: var(--tinta); background: var(--papel);
    border: 1px solid var(--borde-fuerte); border-radius: var(--radio-s);
}
.pt-quitar {
    width: 30px; height: 30px; margin-left: 6px;
    border: 1px solid var(--borde); border-radius: 50%;
    background: var(--papel); color: var(--tinta-tenue);
    font-size: 1.1rem; line-height: 1; cursor: pointer;
    transition: all .16s var(--curva);
}
.pt-quitar:hover { border-color: var(--rojo); background: var(--rojo-velo); color: var(--rojo); }

.pp-tu {
    padding: 1px 8px; border-radius: 20px;
    background: var(--acento); color: #fff;
    font-family: var(--fuente-texto); font-size: .68rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em;
}
.pp-suelto { color: #b45309; }

/* El permiso, siempre en la misma columna. */
.pp-rol {
    display: inline-block;
    padding: 4px 11px; border-radius: 20px;
    font-size: .74rem; font-weight: 700; white-space: nowrap;
    background: var(--fondo); color: var(--tinta-suave);
    border: 1px solid var(--borde);
}
.pp-rol.rol-propietario   { background: var(--ambar-velo); color: #b45309; border-color: transparent; }
.pp-rol.rol-administrador { background: var(--acento-velo); color: var(--acento-hondo); border-color: transparent; }

/* ⚠️ EN EL MÓVIL EN VERTICAL NO CABEN DIEZ COLUMNAS, por mucho que la tabla se
   pueda desplazar: se probó con la columna de quién pegada a la izquierda y
   seguía siendo ilegible en 360 px. Aquí la tabla se APILA —cada participante
   es una tarjeta— y los números pasan a ser chips con su icono delante, que es
   lo que los explica cuando no hay cabecera que mirar. Los ceros desaparecen:
   en una pantalla pequeña, lo que no hay no debe ocupar sitio. */
@media (max-width: 760px) {
    .pp-tabla-marco { overflow-x: visible; }
    .pp-tabla, .pp-tabla tbody, .pp-tabla tr, .pp-tabla td { display: block; }
    .pp-tabla { border: 0; background: none; }
    .pp-tabla thead { display: none; }

    .pp-tabla tbody tr {
        position: relative;
        margin-bottom: 10px; padding: 14px 15px;
        background: var(--papel);
        border: 1px solid var(--borde); border-radius: var(--radio);
        box-shadow: var(--sombra-1);
    }
    .pp-tabla tbody tr:hover td,
    .pp-tabla tbody tr.soy-yo td { background: none; }
    .pp-tabla tbody tr.soy-yo { border-color: var(--acento); }
    .pp-tabla tbody td { padding: 0; border: 0; }

    /* Permiso y estado, juntos y debajo del nombre. Se probó con el permiso
       fijo arriba a la derecha y el estado se le montaba encima. */
    .pp-tabla .pt-rol { display: inline-block; margin: 8px 6px 0 0; }
    .pp-tabla .pt-quien { min-width: 0; }

    /* Los números, en línea y con su icono delante. */
    .pp-tabla tbody .pt-n {
        display: inline-flex; align-items: center; gap: 5px;
        width: auto; margin: 10px 6px 0 0; padding: 4px 10px 4px 8px;
        background: var(--fondo); border-radius: 20px;
        font-size: .84rem;
    }
    .pp-tabla tbody .pt-n.cero { display: none; }
    /* Lo mismo con quien todavía no ha entrado: cinco rayas seguidas no dicen
       nada que no diga ya su estado. El total sí se queda, con su raya. */
    .pp-tabla tbody .pt-n.no-aplica:not(.pt-total) { display: none; }
    .pt-icono { display: block; width: 15px; height: 15px; color: var(--tinta-tenue); }
    .pp-tabla tbody .pt-total {
        background: var(--acento-velo);
        padding-left: 10px;
    }
    .pt-rotulo { display: inline; font-size: .74rem; font-weight: 600; color: var(--tinta-suave); }

    .pp-tabla .pt-cuando { margin-top: 10px; display: flex; gap: 5px; }

    /* Apilada en tarjetas no hay desplazamiento del que salvarse, y una celda
       fija dentro de una tarjeta se pega donde no debe. */
    .pp-tabla .pt-acciones {
        display: flex; gap: 8px; align-items: center;
        width: auto; margin-top: 12px; text-align: left;
        position: static; box-shadow: none; background: none;
    }
    .pt-acciones select { flex: 1; }
    /* A uno mismo y al propietario no se les toca el permiso: esa celda no
       existe para ellos, y con `:empty` no bastaba —los espacios en blanco del
       HTML cuentan como contenido—. */
    .pp-tabla .pt-acciones.vacia { display: none; }
}

/* ── Invitaciones ─────────────────────────────────────────────────────── */
/* Van en la MISMA tabla que los participantes: es la misma pregunta —quién
   entra, con qué permiso y en qué estado—, y verla en dos formatos distintos
   hacía la pantalla el doble de larga. Lo único suyo es el color del estado en
   el borde de la fila y el motivo del rebote. */

.pp-vacio { color: var(--tinta-suave); max-width: 62ch; }

/* La fila de quien todavía no ha entrado: se distingue por el color del estado
   en el borde izquierdo, sin sacarla de la lista. */
.pp-tabla tbody tr.es-invitacion { border-left: 4px solid var(--borde-fuerte); }
.pp-tabla tbody tr.es-invitacion.estado-espera { border-left-color: var(--acento); }
.pp-tabla tbody tr.es-invitacion.estado-bien   { border-left-color: #16a34a; }
.pp-tabla tbody tr.es-invitacion.estado-aviso  { border-left-color: var(--ambar); }
/* Una invitación que ha rebotado no es un aviso: es un correo que no existe y
   hay que corregir. Va en rojo para que se distinga de la que falta enviar. */
.pp-tabla tbody tr.es-invitacion.estado-mal    { border-left-color: var(--rojo); }
/* Lo caducado y lo anulado se queda como registro, sin llamar la atención. */
.pp-tabla tbody tr.es-invitacion.estado-apagado { opacity: .62; }

/* Las casillas de aportación de quien aún no ha entrado llevan una raya: no es
   lo mismo «no ha hecho nada» que «todavía no ha podido hacer nada». */
.pp-tabla .pt-n.no-aplica { color: var(--borde-fuerte); font-weight: 400; }

.pp-estado {
    display: inline-block;
    padding: 3px 11px; border-radius: 20px; white-space: nowrap;
    font-size: .74rem; font-weight: 700;
    background: var(--fondo); color: var(--tinta-suave);
}
.pp-estado.espera { background: var(--acento-velo); color: var(--acento-hondo); }
.pp-estado.bien   { background: #dcfce7; color: #15803d; }
.pp-estado.aviso  { background: var(--ambar-velo); color: #b45309; }
.pp-estado.mal    { background: var(--rojo-velo); color: var(--rojo); }

/* Lo que dijo el servidor del destinatario, en castellano. Sin esto, «No
   llegó» deja a quien invitó sin saber si escribió mal la dirección o si es
   que el buzón estaba lleno un martes. */
.pt-rebote { display: block; margin-top: 3px; font-size: .78rem; color: var(--rojo); }

.pp-tabla tbody tr.es-invitacion .pt-acciones { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }

@media (max-width: 760px) {
    .pagina-participantes { padding: 20px 16px 40px; }
    .pp-tabla tbody tr.es-invitacion .pt-acciones { justify-content: flex-start; }
}

/* ── Todos sus apellidos en orden ─────────────────────────────────────────
   Arriba la línea de corrido, que es la que se lee y se copia; debajo el
   desglose con las CASILLAS ENTERAS de cada generación —padres y madres—,
   partidas en rama paterna y materna. Las casillas vacías se dibujan a
   propósito: son las que dicen por dónde falta investigar. */
.ap-linea {
    font-size: 1.05rem; line-height: 1.45; margin: 4px 0 14px;
    padding: 12px 14px; border-radius: var(--radio);
    background: var(--acento-velo); color: var(--acento-hondo); font-weight: 600;
}
.ap-bloque {
    margin-bottom: 14px; padding-top: 10px; border-top: 1px solid var(--borde);
}
.ap-cabecera {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px; margin-bottom: 8px;
}
/* De la quinta generación en adelante el bloque va plegado, y el summary
   necesita comportarse como la cabecera de los demás. */
summary.ap-cabecera { cursor: pointer; list-style-position: outside; }
.ap-titulo { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.ap-titulo strong { font-size: .95rem; }
.ap-cuenta { font-size: .78rem; color: var(--tinta-tenue); white-space: nowrap; }
/* Lo que aporta cada generación: los apellidos que entran por vía materna. */
.ap-aporta { font-size: .78rem; color: var(--tinta-tenue); }

.ap-rama { margin-bottom: 10px; }
.ap-rama-titulo {
    margin: 0 0 5px; font-size: .74rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--tinta-tenue);
}
/* La rama se marca con una raya lateral: es lo que hace que las dos mitades
   de la generación se distingan de un vistazo sin leer el rótulo. */
.ap-rama { border-left: 3px solid var(--borde); padding-left: 10px; }
.ap-paterna { border-left-color: var(--varon); }
.ap-materna { border-left-color: var(--mujer); }

.ap-rejilla {
    display: grid; gap: 6px;
    grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
}
.ap-casilla {
    display: flex; flex-direction: column; gap: 1px; min-width: 0;
    padding: 6px 10px; border-radius: var(--radio-s);
    background: var(--papel-2); border: 1px solid var(--borde);
}
.ap-fila { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.ap-apellido {
    font-size: .88rem; font-weight: 600;
    overflow-wrap: anywhere; min-width: 0;
}
/* El número que ocupa en la línea de arriba: el desglose va por ramas y la
   línea alterna las dos, así que es lo que casa una cosa con la otra. */
.ap-orden {
    flex: none; font-size: .68rem; font-variant-numeric: tabular-nums;
    color: var(--tinta-tenue); background: var(--fondo-2);
    border-radius: 20px; padding: 1px 6px; line-height: 1.5;
}
/* La vía exacta hasta la casilla: «padre › madre › madre». Es lo que dice de
   qué posición del árbol viene el apellido, y lo único que sigue valiendo en
   la décima generación, donde ya no hay palabra castellana que la nombre. */
.ap-via {
    font-size: .7rem; color: var(--tinta-tenue); line-height: 1.3;
    overflow-wrap: anywhere;
}
/* Los huecos se enseñan a propósito: son los que dicen dónde investigar. */
.ap-hueco { border-style: dashed; background: transparent; }
.ap-hueco .ap-apellido { color: var(--tinta-tenue); }
/* La casilla de varón repite un apellido que ya está puesto más abajo, así que
   no entra en la línea de arriba. Se enseña —es lo que hace que la estructura
   se vea simétrica— pero atenuada, para que no parezca que se cuenta dos. */
/* ⚠️ Atenuar la casilla ENTERA con `opacity` no vale: la que es hueco Y
   repetida a la vez —un varón del que no se sabe el apellido— acumulaba las
   dos atenuaciones y su «?» dejaba de leerse, que es justo el signo que tiene
   que verse siempre. Se atenúa solo el apellido, no la casilla. */
.ap-repetido { background: transparent; }
.ap-repetido .ap-apellido { color: var(--tinta-suave); font-weight: 500; }
.ap-repetido.ap-hueco .ap-apellido { color: var(--tinta-tenue); }
/* ⚠️ El apellido DEDUCIDO se marca. No sale de la ficha de esa persona —que a
   veces ni existe— sino del segundo apellido de su hijo, y presentarlo igual
   que un dato registrado sería afirmar más de lo que se sabe. El «·» va por
   CSS y no en el texto para que no se cuele en lo que se copia. */
.ap-deducido { border-style: dashed; }
.ap-deducido .ap-apellido::after {
    content: ' ·'; color: var(--acento); font-weight: 700;
}
.ap-clicable { cursor: pointer; }
.ap-clicable:hover { border-color: var(--acento); background: var(--acento-velo); }

/* ── Sacar una rama a un árbol nuevo ──────────────────────────────────────
   El número de personas de cada alcance va DELANTE de la explicación: en un
   árbol de pueblo la diferencia entre uno y otro son cientos de fichas, y sin
   la cifra se elige a ciegas. */
.rama-modo {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 10px 12px; margin-bottom: 8px;
    border: 1px solid var(--borde); border-radius: var(--radio);
    cursor: pointer;
}
.rama-modo:hover { border-color: var(--acento); background: var(--fondo-2); }
.rama-modo input { margin-top: 3px; flex-shrink: 0; }
.rama-modo-titulo { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.rama-cuenta {
    font-size: .78rem; font-weight: 650; color: var(--acento-hondo);
    background: var(--acento-velo); border-radius: 20px; padding: 1px 9px;
}
.rama-modo .ayuda { margin: 4px 0 0; }
.linea-check { display: flex; align-items: center; gap: 8px; margin: 12px 0 4px; font-size: .88rem; }

/* ── «Esta persona ya está en el árbol» ───────────────────────────────────
   Sale al crear una ficha parecida a otra. Lo que decide no es el nombre
   —dos «José García» son indistinguibles— sino el ENTORNO, así que los
   familiares tienen que leerse de un vistazo. */
.dup-ficha {
    border: 1px solid var(--borde);
    border-left: 4px solid var(--acento);
    border-radius: var(--radio);
    padding: 12px 14px;
    margin-bottom: 10px;
    background: var(--papel);
}
.dup-cabecera { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.dup-anios { font-size: .82rem; color: var(--tinta-tenue); }
.dup-datos { margin-top: 6px; display: flex; flex-direction: column; gap: 2px; }
.dup-linea { font-size: .85rem; }
.dup-rotulo { display: inline-block; min-width: 62px; color: var(--tinta-tenue); }
.dup-motivos { margin: 7px 0 0; font-size: .8rem; color: var(--tinta-tenue); font-style: italic; }
.dup-acciones { margin-top: 10px; }

/* ── Participantes: un bloque por árbol ───────────────────────────────── */
/* Quien tiene tres árboles los ve los tres seguidos, así que cada uno necesita
   una cabecera que se distinga a simple vista al bajar por la página. */

.pp-arbol { margin-top: 34px; }
.pp-arbol-cabecera {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding-bottom: 9px; margin-bottom: 14px;
    border-bottom: 2px solid var(--acento-velo);
}
.pp-arbol-cabecera h2 { margin: 0; font-size: 1.32rem; }
.pp-arbol-detalle { font-size: .84rem; color: var(--tinta-tenue); }

.pp-invitar {
    margin-top: 18px; padding: 14px 18px;
    background: var(--papel); border: 1px dashed var(--borde-fuerte);
    border-radius: var(--radio);
}
.pp-invitar > summary {
    cursor: pointer; font-weight: 600; color: var(--acento-hondo);
    list-style: none;
}
.pp-invitar > summary::before { content: '+ '; font-weight: 700; }
.pp-invitar[open] > summary::before { content: '– '; }
.pp-invitar-nota { font-size: .88rem; color: var(--tinta-suave); max-width: 68ch; }

.pp-form-invitar { display: grid; gap: 12px; margin-top: 6px; }
.pp-campos { display: flex; gap: 12px; flex-wrap: wrap; }
.pp-campos label, .pp-mensaje { display: flex; flex-direction: column; gap: 4px; flex: 1 1 190px; }
.pp-campos span, .pp-mensaje span { font-size: .78rem; font-weight: 600; color: var(--tinta-tenue); }
.pp-form-invitar input, .pp-form-invitar select, .pp-form-invitar textarea {
    padding: 9px 11px; border: 1px solid var(--borde-fuerte);
    border-radius: var(--radio-s); background: var(--papel);
    color: var(--tinta); font-size: .9rem; font-family: inherit; width: 100%;
}
.pp-form-invitar button { justify-self: start; }

.pp-nueva-rama {
    padding: 1px 8px; border-radius: 20px;
    background: var(--ambar-velo); color: #b45309;
    font-size: .72rem; font-weight: 700;
}

/* ── Coincidencias ────────────────────────────────────────────────────── */
/* Las dos fichas se pintan del mismo tamaño y con el mismo detalle: en cuanto
   una de las dos se ve «más importante» que la otra, la decisión deja de
   tomarse mirando los datos. */

.pagina-coincidencias { padding: 28px 24px 48px; max-width: 940px; }
.pc-cabecera { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.pc-cabecera h1 { margin: 0; }
.pc-entradilla { color: var(--tinta-suave); max-width: 66ch; margin: 8px 0 0; }
.pc-sello { font-size: .82rem; color: var(--tinta-tenue); margin: 10px 0 0; }

.pc-titulo { margin: 32px 0 12px; font-size: 1.16rem; display: flex; align-items: center; gap: 9px; }
.pc-cuenta {
    padding: 2px 10px; border-radius: 20px;
    background: var(--acento-velo); color: var(--acento-hondo);
    font-size: .8rem; font-weight: 700;
}
.pc-vacio { color: var(--tinta-suave); max-width: 66ch; }

.pc-caso {
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: var(--radio); padding: 16px 18px;
    margin-bottom: 14px; box-shadow: var(--sombra-1);
}
.pc-caso.externo { border-left: 4px solid var(--ambar); }
.pc-caso.resuelto { opacity: .6; }

.pc-marca { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.pc-puntos {
    padding: 3px 11px; border-radius: 20px;
    background: var(--acento-velo); color: var(--acento-hondo);
    font-size: .78rem; font-weight: 700;
}
.pc-arbol-ajeno { font-size: .84rem; color: var(--tinta-suave); }
.pc-estado {
    padding: 3px 11px; border-radius: 20px; font-size: .74rem; font-weight: 700;
    background: var(--fondo-suave); color: var(--tinta-suave);
}
.pc-estado.bien   { background: #dcfce7; color: #15803d; }
.pc-estado.espera { background: var(--acento-velo); color: var(--acento-hondo); }
.pc-estado.aviso  { background: var(--ambar-velo); color: #b45309; }

/* Las dos fichas y el signo de interrogación en medio. `align-items: stretch`
   para que midan igual aunque una tenga más vínculos que la otra. */
.pc-par { display: grid; grid-template-columns: 1fr auto 1fr; gap: 14px; align-items: stretch; }
.pc-persona {
    background: var(--papel-2); border: 1px solid var(--borde);
    border-radius: var(--radio-s); padding: 12px 14px;
}
.pc-rotulo {
    display: block; font-size: .7rem; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--tinta-tenue); margin-bottom: 4px;
}
.pc-persona h4 { margin: 0; font-size: 1rem; }
.pc-datos { margin: 4px 0 8px; font-size: .85rem; color: var(--tinta-suave); }
.pc-linea { margin: 3px 0; font-size: .83rem; color: var(--tinta-suave); }
.pc-linea span { font-weight: 600; color: var(--tinta-tenue); }
.pc-suelta { color: var(--ambar-hondo, #b45309); font-style: italic; }
.pc-union {
    display: flex; align-items: center; justify-content: center;
    font-size: 1.5rem; color: var(--tinta-tenue);
}

.pc-motivos {
    list-style: none; margin: 12px 0 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: 6px 8px;
}
.pc-motivos li {
    padding: 3px 10px; border-radius: 20px;
    background: var(--fondo-suave); color: var(--tinta-suave); font-size: .8rem;
}

/* Enlace para abrir la ficha entera cuando el resumen no basta. */
.pc-persona h4 a { color: inherit; }
.pc-abrir {
    font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--acento-hondo); vertical-align: middle;
}

/* El aviso de que ya están emparentadas manda sobre todo lo demás: si B es
   hijo de A, no hay nada que fundir por mucho que se parezcan. */
.pc-parentesco {
    margin: 12px 0 0; padding: 9px 12px;
    background: var(--ambar-velo); border-left: 3px solid var(--ambar);
    border-radius: var(--radio-s); color: #b45309; font-size: .87rem;
}

/* A favor y en contra, uno al lado del otro. Enseñar solo los parecidos hacía
   que cualquier par pareciera la misma persona. */
.pc-balanza { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 12px; }
.pc-lado {
    padding: 10px 12px; border-radius: var(--radio-s);
    background: var(--papel-2); border: 1px solid var(--borde);
}
.pc-lado h5 {
    margin: 0 0 6px; font-size: .7rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em; color: var(--tinta-tenue);
}
.pc-lado ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.pc-lado li { font-size: .82rem; color: var(--tinta-suave); line-height: 1.35; }
.pc-lado li::before { content: '· '; color: var(--tinta-tenue); }
.pc-favor  { border-left: 3px solid var(--acento); }
.pc-contra { border-left: 3px solid var(--ambar); }

.pc-acciones {
    margin-top: 14px; padding-top: 13px; border-top: 1px dashed var(--borde);
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
}
.pc-conservar { display: flex; flex-direction: column; gap: 4px; flex: 1 1 260px; }
.pc-conservar span { font-size: .78rem; font-weight: 600; color: var(--tinta-tenue); }
.pc-conservar select {
    padding: 8px 11px; border: 1px solid var(--borde-fuerte);
    border-radius: var(--radio-s); background: var(--papel);
    color: var(--tinta); font-size: .88rem; width: 100%;
}
.pc-botones { display: flex; gap: 8px; flex-wrap: wrap; }
.pc-nota { margin: 0; font-size: .85rem; color: var(--tinta-suave); flex: 1 1 320px; max-width: 62ch; }
.pc-injertado {
    margin: 12px 0 0; padding: 9px 12px;
    background: var(--acento-velo); border-radius: var(--radio-s);
    font-size: .85rem; color: var(--acento-hondo);
}

@media (max-width: 720px) {
    .pagina-coincidencias { padding: 20px 16px 40px; }
    /* En vertical las dos fichas van una encima de otra, con el signo entre
       ellas: en tres columnas de 100 px no se lee ni un apellido. */
    .pc-par { grid-template-columns: 1fr; }
    .pc-union { padding: 2px 0; }
    .pc-balanza { grid-template-columns: 1fr; }
}

/* ── Avisos del menú ──────────────────────────────────────────────────── */

.ml-marca-avisos {
    margin-left: auto;
    min-width: 20px; padding: 1px 6px; border-radius: 20px;
    background: var(--ambar); color: #fff;
    font-size: .72rem; font-weight: 700; text-align: center;
}
/* El número de solicitudes se refresca solo (`menu.js`); cuando no queda
   ninguna se esconde en vez de quedarse enseñando un cero. */
.ml-marca-avisos.oculto { display: none; }
.ml-avisos {
    margin: 14px 12px 0; padding-top: 12px;
    border-top: 1px solid var(--borde);
}
.ml-avisos-cabecera {
    display: flex; justify-content: space-between; align-items: baseline;
    font-size: .72rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .05em; color: var(--tinta-tenue); margin-bottom: 6px;
}
.ml-avisos-leer {
    background: none; border: 0; cursor: pointer; padding: 0;
    color: var(--acento-hondo); font-size: .72rem; font-weight: 600;
    text-transform: none; letter-spacing: 0;
}
.ml-aviso {
    display: block; padding: 7px 9px; margin-bottom: 4px;
    border-radius: var(--radio-s); border-left: 3px solid transparent;
    font-size: .82rem; line-height: 1.35; color: var(--tinta-suave);
}
.ml-aviso:hover { background: var(--fondo-suave); text-decoration: none; }
.ml-aviso.nuevo {
    border-left-color: var(--ambar);
    background: var(--ambar-velo); color: var(--tinta);
}

/* ── Novedades ────────────────────────────────────────────────────────── */

/* Tres zonas: cabecera y botón quietos, y el cuerpo desplazándose entre los
   dos. Con `overflow-y` en el modal entero, al bajar por una lista larga el
   botón de cerrar se iba fuera de la pantalla —en un móvil, un modal del que
   no se sabe salir—. `overscroll-behavior: contain` evita además que al llegar
   al final el gesto siga y arrastre la página de debajo. */
.modal-novedades {
    max-width: 540px; text-align: left;
    display: flex; flex-direction: column;
    max-height: 86vh; max-height: 86dvh;
    padding: 0; overflow: hidden;
}
.nv-cabecera { padding: 24px 28px 12px; flex: none; }
.nv-cuerpo {
    flex: 1 1 auto; min-height: 0;
    padding: 0 28px 4px;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
.modal-novedades .modal-acciones {
    flex: none; margin: 0;
    padding: 14px 28px calc(20px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--borde);
    background: var(--papel);
}

/* En móvil los modales son una hoja pegada abajo, a todo el ancho. Estas
   reglas van aquí y no arriba porque el bloque general está en un `@media`
   anterior en el fichero, y `.modal-novedades` lo pisaría al ir después. */
@media (max-width: 860px) {
    .modal-novedades { max-width: none; max-height: 92dvh; }
    .nv-cabecera { padding: 18px 16px 10px; }
    .nv-cuerpo { padding: 0 16px 4px; }
    .modal-novedades .modal-acciones { padding: 12px 16px calc(12px + env(safe-area-inset-bottom)); }
    .modal-novedades .modal-acciones .boton { flex: 1; }
}
.nv-etiqueta {
    display: inline-block; padding: 3px 11px; border-radius: 20px;
    background: var(--acento-velo); color: var(--acento-hondo);
    font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
}
.modal-novedades h3 { margin: 14px 0 2px; font-size: 1.2rem; }
.nv-fecha { margin: 0 0 12px; font-size: .8rem; color: var(--tinta-tenue); }
.nv-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.nv-lista li {
    display: flex; gap: 10px; align-items: flex-start;
    font-size: .9rem; color: var(--tinta-suave); line-height: 1.45;
}
/* La etiqueta va a ancho fijo para que los textos empiecen todos en la misma
   columna: en cuanto bailan, la lista se lee como un revoltijo. */
.nv-tipo {
    flex: none; width: 74px; text-align: center;
    padding: 2px 0; border-radius: 20px;
    font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    background: var(--fondo-suave); color: var(--tinta-suave);
}
.nv-nuevo   .nv-tipo { background: var(--acento-velo); color: var(--acento-hondo); }
.nv-mejora  .nv-tipo { background: var(--ambar-velo);  color: #b45309; }
.nv-arreglo .nv-tipo { background: #dcfce7; color: #15803d; }

/* ===========================================================================
   PROPUESTAS DE ELIMINACIÓN
   ---------------------------------------------------------------------------
   Quien edita propone, quien administra decide. La tarjeta tiene que enseñar
   las tres cosas que hacen falta para decidir sin abrir nada más: a quién,
   por qué, y QUÉ SE LLEVA POR DELANTE.
   ========================================================================= */

.pagina-propuestas { max-width: 900px; }

/* Lengüetas de Solicitudes. Son enlaces con `?ver=`, no pestañas de JS: así un
   aviso de la campana entra directamente en la que toca y el navegador guarda
   en el historial dónde estaba uno. */
.sol-lenguetas {
    display: flex; gap: 4px; margin: 18px 0 6px;
    border-bottom: 1px solid var(--borde);
}
.sol-lengueta {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 16px; margin-bottom: -1px;
    border: 1px solid transparent; border-bottom: none;
    border-radius: 10px 10px 0 0;
    color: var(--tinta-suave); font-weight: 600; font-size: .94rem;
    text-decoration: none;
}
.sol-lengueta:hover { color: var(--tinta); background: var(--fondo-2); }
.sol-lengueta.activa {
    background: var(--papel); border-color: var(--borde);
    color: var(--tinta); box-shadow: inset 0 2px 0 var(--acento);
}
.sol-num {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 20px; height: 20px; padding: 0 6px;
    border-radius: 20px; background: var(--ambar); color: #fff;
    font-size: .72rem; font-weight: 700;
}
.sol-panel.oculto { display: none; }
.sol-nota {
    margin: 16px 0 0; color: var(--tinta-suave);
    font-size: .93rem; line-height: 1.6;
}
.pr-bloque { margin-top: 30px; }
.pr-bloque h2 {
    display: flex; align-items: center; gap: 10px;
    margin: 0 0 14px; font-size: 1.12rem;
}
.pr-cuenta {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 26px; height: 22px; padding: 0 7px;
    border-radius: 20px; background: var(--ambar-velo); color: #b45309;
    font-size: .76rem; font-weight: 700;
}

.pr-ficha {
    margin-bottom: 14px; padding: 16px 18px;
    background: var(--papel); border: 1px solid var(--borde);
    border-radius: var(--radio); box-shadow: var(--sombra-1);
}
.pr-cabecera {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
}
.pr-cabecera h3 { margin: 0 0 3px; font-size: 1.04rem; }
.pr-anios { margin-left: 7px; color: var(--tinta-tenue); font-weight: 400; font-size: .86rem; }
.pr-quien { margin: 0; color: var(--tinta-suave); font-size: .86rem; }

.pr-marca {
    display: inline-flex; align-items: center;
    padding: 3px 10px; border-radius: 20px;
    font-size: .76rem; font-weight: 600; white-space: nowrap;
}
.pr-marca.bien    { background: #dcfce7; color: #15803d; }
.pr-marca.aviso   { background: var(--ambar-velo); color: #b45309; }
.pr-marca.mal     { background: var(--rojo-velo); color: var(--rojo); }
.pr-marca.apagado { background: var(--fondo-2); color: var(--tinta-tenue); }

.pr-motivo {
    margin: 12px 0 0; padding: 10px 14px;
    border-left: 3px solid var(--acento); border-radius: 0 8px 8px 0;
    background: var(--papel-2); color: var(--tinta);
    font-size: .92rem;
}
.pr-motivo.vacio { border-left-color: var(--borde-fuerte); color: var(--tinta-tenue); }

.pr-acciones {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin-top: 14px;
}
.pr-respuesta {
    flex: 1 1 220px; min-width: 0;
    padding: 9px 12px; font-size: .9rem;
    background: var(--papel); color: var(--tinta);
    border: 1px solid var(--borde); border-radius: 9px;
}
.pr-respuesta:focus { outline: none; border-color: var(--acento); box-shadow: 0 0 0 3px var(--acento-velo); }

.pr-historial { display: flex; flex-direction: column; gap: 7px; }
.pr-linea {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 9px 13px;
    background: var(--papel); border: 1px solid var(--borde); border-radius: 10px;
    font-size: .87rem;
}
.pr-l-nombre { font-weight: 600; }
.pr-l-detalle { color: var(--tinta-suave); }
.pr-l-respuesta { color: var(--tinta-tenue); font-style: italic; }

@media (max-width: 620px) {
    .pr-acciones .boton { flex: 1 1 auto; }
}

/* ==========================================================================
   El mapa de la familia
   --------------------------------------------------------------------------
   Los contornos son SVG servido por nosotros, así que todo el color va aquí y
   cambia solo con el tema claro/oscuro. El zoom lo aplica el JS al grupo raíz;
   por eso los trazos llevan `non-scaling-stroke` y las etiquetas se reescalan
   a mano: si no, al acercarse las fronteras engordan hasta taparlo todo.
   ========================================================================== */

.mapa-envoltorio { background: var(--fondo-2); }
.mapa-lienzo { position: absolute; inset: 0; }
#mapa-svg { width: 100%; height: 100%; display: block; touch-action: none; }

.mapa-mar { fill: var(--fondo-2); }
/* ⚠️ Los países extranjeros van de un tono INTERMEDIO entre el mar y España, y
   no blancos como ella. Dos motivos, y el segundo es el importante:

   1. España es el sujeto del mapa —el árbol es de una familia española— y
      destaca en blanco sobre lo demás.
   2. La frontera de Portugal y la de nuestras provincias vienen de dos
      cartografías distintas y no encajan al milímetro: entre ambas quedan
      cuñas de unos pocos kilómetros. Coserlas exigiría conflar las dos
      geometrías; con el país vecino casi del color del mar, esas cuñas dejan
      de verse. */
.mapa-pais {
    fill: var(--fondo); stroke: var(--borde-fuerte); stroke-width: .8;
    stroke-linejoin: round; transition: fill .3s var(--curva);
}
/* El país se tiñe cuando hay gente de fuera de España: si solo se pintaran las
   provincias, quien nació en la India no aparecería en ninguna parte. */
.capa-paises.con-tinte .mapa-pais.con-gente { stroke: var(--acento-hondo); stroke-width: 1; }
/* ⚠️ LAS PROVINCIAS SON EL MAPA DE ESPAÑA. El contorno del país no se dibuja
   —el de Natural Earth tiene 37 puntos en total y se deja fuera Canarias, así
   que al ampliar unas provincias se salían de él y otras se quedaban cortas—:
   España es exactamente la unión de sus 52 provincias, así que encaja por
   construcción. Por eso su relleno de partida es el de TIERRA y no
   transparente. Se dibujan siempre, tengan gente o no: las vacías son las que
   dicen dónde falta investigar. */
.mapa-provincia {
    fill: var(--papel); stroke: var(--borde-fuerte); stroke-width: .6;
    transition: fill .3s var(--curva);
}
.mapa-provincia.con-gente { stroke: var(--acento-hondo); stroke-width: .7; }

.mapa-punto {
    fill: var(--ambar); fill-opacity: .95;
    stroke: var(--papel); stroke-width: var(--grosor, 1.4px);
    cursor: pointer; transition: opacity .25s var(--curva);
    /* ⚠️ `pointer-events: all` y no el valor por defecto: los puntos de lo que
       solo se sabe por el país van HUECOS (`fill: none`), y en SVG un relleno
       vacío no recibe pulsaciones. Se pulsaba el círculo de Brasil, el clic
       pasaba de largo al mar y la ficha ni se abría. */
    pointer-events: all;
}
.mapa-punto:hover { fill: #d97706; }
/* Mientras se sigue un recorrido, los demás pueblos se apagan: con todos
   encendidos por detrás, el camino se pierde entre ellos. */
.capa-puntos.atenuada .mapa-punto { opacity: .22; }
.capa-puntos.atenuada .mapa-punto:hover { opacity: .7; }
/* Lo que solo se sabe por el país o la provincia va hueco y a rayas. Un punto
   macizo en mitad de Brasil afirmaría que sabemos dónde nació esa persona. */
.mapa-punto.aproximado {
    fill: none; stroke: var(--ambar); stroke-dasharray: 3 2;
    stroke-width: calc(var(--grosor, 1.2px) * 1.6);
}
.mapa-punto.aproximado:hover { fill: var(--ambar-velo); }

/* El rótulo que sale al pasar por encima de un punto. Es un div HTML colocado
   sobre el punto, y NO el `<title>` del SVG: el tooltip del navegador sale
   donde esté el cursor —descolocado respecto al punto y bastante más grande
   que él—, y encima tarda un segundo en aparecer. */
.mapa-globo {
    position: absolute; z-index: 16; transform: translate(-50%, -100%);
    padding: 5px 10px; border-radius: 999px;
    background: var(--tinta); color: var(--papel);
    font-size: .76rem; font-weight: 600; white-space: nowrap;
    pointer-events: none; box-shadow: var(--sombra-1);
}
.mapa-globo.oculto { display: none; }
.mapa-globo .mg-sub { opacity: .72; font-weight: 500; }

/* ⚠️ Solo la usan los nombres de las PARADAS del recorrido. Los puntos de los
   pueblos NO llevan rótulo: con su halo blanco tapaban las provincias y los
   puntos vecinos, y el mapa se leía peor con los nombres que sin ellos. El
   nombre del sitio sale al pulsarlo, de cabecera en su ficha. */
.mapa-etiqueta {
    fill: var(--tinta); text-anchor: middle; font-weight: 600;
    paint-order: stroke; stroke: var(--papel); stroke-width: 2px;
    stroke-linejoin: round; pointer-events: none;
}

/* El viaje de una rama: una cadena numerada del antepasado más lejano hasta la
   persona. La flecha marca el sentido —hacia el presente— y el color es uno
   solo: con un color por generación parecían caminos distintos. */
.mapa-salto {
    fill: none; stroke: var(--acento-hondo); stroke-width: 2.4px;
    stroke-linecap: round; opacity: .9;
}
.mapa-flecha { fill: var(--acento-hondo); }

/* Cada parada del recorrido lleva DENTRO su número, el mismo de la lista. El
   nombre del pueblo escrito al lado se probó dos veces y las dos tapaba el
   mapa; el número ocupa nada y remite a donde sí cabe todo. */
.mapa-parada {
    fill: var(--acento); stroke: var(--papel);
    stroke-width: var(--grosor, 1.8px);
}
/* La última parada es la persona desde la que se mira: va en ámbar, como el
   foco del lienzo del árbol. */
.mapa-parada.final { fill: var(--ambar); }
.mapa-parada-numero {
    fill: #fff; text-anchor: middle; font-weight: 700;
    pointer-events: none; paint-order: stroke;
}
.mapa-parada-grupo { cursor: default; }
.mapa-parada-grupo.elegida .mapa-parada {
    stroke: var(--ambar); stroke-width: calc(var(--grosor, 1.8px) * 2.2);
}

/* ── Barra de capas ────────────────────────────────────────────────────── */

.barra-mapa { gap: 10px; }
.mapa-capas { display: flex; gap: 6px; flex-wrap: wrap; }
.mapa-capas .capa {
    padding: 6px 12px; font-size: .82rem; font-weight: 600;
    color: var(--tinta-suave); background: var(--fondo);
    border: 1px solid var(--borde); border-radius: 999px;
    cursor: pointer; transition: all .18s var(--curva);
}
.mapa-capas .capa:hover { border-color: var(--acento); color: var(--acento-hondo); }
.mapa-rama select {
    padding: 6px 10px; font: inherit; font-size: .8rem; font-weight: 600;
    color: var(--tinta); background: var(--papel);
    border: 1px solid var(--borde-fuerte); border-radius: 999px;
}
.mapa-rama.oculto { display: none; }

.mapa-capas .capa.activa {
    background: var(--acento); border-color: var(--acento); color: #fff;
}

/* Lo que no se ha podido situar. Va abajo a la izquierda y no en la barra
   porque no es un mando: es un aviso de que el mapa está incompleto. */
.mapa-pendientes {
    position: absolute; left: 14px; bottom: 14px; z-index: 15;
    padding: 9px 15px; font-size: .84rem; font-weight: 600;
    color: var(--tinta); background: color-mix(in srgb, var(--papel) 94%, transparent);
    backdrop-filter: blur(10px);
    border: 1px solid var(--ambar); border-radius: 999px;
    box-shadow: var(--sombra-1); cursor: pointer;
}
.mapa-pendientes:hover { background: var(--papel); border-color: var(--acento); }

/* ── Ficha de un sitio ─────────────────────────────────────────────────── */

.mapa-ficha {
    position: absolute; right: 14px; top: 84px; z-index: 18;
    width: 250px; max-height: 46vh; overflow-y: auto;
    padding: 14px 16px;
    background: color-mix(in srgb, var(--papel) 96%, transparent);
    backdrop-filter: blur(10px);
    border: 1px solid var(--borde); border-radius: var(--radio);
    box-shadow: var(--sombra-2);
    animation: subir .22s var(--curva) both;
}
.mapa-ficha-cabecera { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.mapa-ficha-titulo { display: flex; flex-direction: column; }
.mapa-ficha-titulo strong { font-family: var(--fuente); font-size: 1.02rem; line-height: 1.2; }
.mapa-ficha-titulo .sub { font-size: .78rem; color: var(--tinta-suave); }
.mapa-ficha-cerrar {
    background: none; border: 0; font-size: 1.3rem; line-height: 1;
    color: var(--tinta-tenue); cursor: pointer;
}
.mapa-ficha-lista { list-style: none; display: flex; flex-direction: column; gap: 6px; font-size: .87rem; }
.mapa-ficha-lista li { display: flex; justify-content: space-between; gap: 8px; padding-left: 8px; border-left: 3px solid var(--borde); }
.mapa-ficha-lista li.sexo-H { border-left-color: var(--varon); }
.mapa-ficha-lista li.sexo-M { border-left-color: var(--mujer); }
.mapa-ficha-lista .sub { white-space: nowrap; font-size: .78rem; }

.leyenda-mapa { width: 246px; max-height: 60vh; overflow-y: auto; }
.leyenda-mapa .leyenda-titulo { font-size: .74rem; font-weight: 700; color: var(--tinta-suave); margin-bottom: 8px; }
.leyenda-mapa .leyenda-titulo.separada { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--borde); }
.leyenda-mapa .leyenda-gen { width: auto; flex: 0 0 84px; font-weight: 600; color: var(--tinta-suave); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leyenda-mas { margin-top: 6px; font-size: .7rem; color: var(--tinta-tenue); }

/* Los pasos del viaje, con el mismo número que llevan en el mapa. Se pulsan:
   la lista es el mando, y es lo que permite seguirlo paso a paso en vez de
   descifrar una maraña de líneas. */
.leyenda-paso {
    display: flex; align-items: center; gap: 9px; margin-bottom: 5px;
    padding: 4px 6px; border-radius: var(--radio-s);
    cursor: pointer; transition: background .16s var(--curva);
}
.leyenda-paso:hover { background: var(--acento-velo); }
.lp-numero {
    flex: 0 0 20px; height: 20px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--acento); color: #fff;
    font-size: .7rem; font-weight: 700;
}
.leyenda-paso:last-child .lp-numero { background: var(--ambar); }
.lp-texto { display: flex; flex-direction: column; min-width: 0; }
.lp-lugar { font-size: .78rem; font-weight: 700; color: var(--tinta); }
.lp-quien { font-size: .7rem; color: var(--tinta-suave); }

/* Qué significa cada símbolo. Sin esto, un punto grande y otro pequeño
   parecen dos adornos y el círculo a rayas parece un fallo de dibujo. */
.leyenda-simbolo {
    display: flex; align-items: center; gap: 8px; margin-bottom: 7px;
    font-size: .73rem; color: var(--tinta-suave); line-height: 1.3;
}
.ley-dibujo { flex: 0 0 34px; width: 34px; height: 16px; overflow: visible; }
/* Dentro de la leyenda los símbolos no dependen del zoom del mapa. */
.ley-dibujo .mapa-punto { stroke-width: 1px; cursor: default; }
.ley-dibujo .mapa-punto.aproximado { stroke-width: 1.6px; }
.ley-dibujo .mapa-salto { stroke-width: 2px; }

/* ── Lugares por situar ────────────────────────────────────────────────── */

.modal.ancho { max-width: 640px; }
.lugar-pendiente { padding: 14px 0; border-top: 1px solid var(--borde); }
.lugar-pendiente:first-child { border-top: 0; }
.lugar-pendiente.resuelto { opacity: .55; }
.lugar-cabecera { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.lugar-opciones, .lugar-sugerencias { display: flex; gap: 6px; flex-wrap: wrap; }
.lugar-busqueda { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.lugar-busqueda input {
    width: 100%; padding: 9px 12px; font: inherit; font-size: .9rem;
    color: var(--tinta); background: var(--papel);
    border: 1px solid var(--borde-fuerte); border-radius: var(--radio-s);
}
/* Mismo ámbar que la marca de varias ramas del lienzo: en toda la aplicación
   ese color quiere decir «esto pide que lo mires», no «esto está mal». */
.etiqueta-aviso {
    padding: 2px 8px; font-size: .72rem; font-weight: 600;
    color: #b45309; background: var(--ambar-velo);
    border: 1px solid color-mix(in srgb, var(--ambar) 40%, transparent);
    border-radius: 999px;
}

@media (max-width: 600px) {
    .mapa-ficha { right: 10px; left: 10px; width: auto; top: auto; bottom: 76px; max-height: 38vh; }
    .mapa-pendientes { left: 10px; bottom: 14px; font-size: .78rem; padding: 8px 12px; }
    .leyenda-mapa { display: none; }
    .mapa-capas .capa { padding: 5px 10px; font-size: .76rem; }
}

/* ── Autocompletado de lugares ─────────────────────────────────────────────
   Se usa en los campos de lugar de la ficha. Elegir de la lista escribe el
   nombre CON su provincia o su país («Lucena, Córdoba»), que es lo que hace
   que el mapa sepa cuál de las cinco Lucenas es. Escribir a mano sigue
   valiendo: el lugar es texto libre y tiene que seguir siéndolo. */

.autocompletar { position: relative; }
.autocompletar-lista {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 60;
    margin-top: 4px; padding: 4px;
    max-height: 232px; overflow-y: auto;
    background: var(--papel);
    border: 1px solid var(--borde-fuerte); border-radius: var(--radio-s);
    box-shadow: var(--sombra-2);
}
.autocompletar-lista.oculto { display: none; }
.autocompletar-opcion {
    display: flex; align-items: baseline; gap: 8px; width: 100%;
    padding: 7px 10px; border: 0; border-radius: 7px;
    background: none; font: inherit; text-align: left; cursor: pointer;
}
.autocompletar-opcion:hover,
.autocompletar-opcion.elegida { background: var(--acento-velo); }
.ac-nombre { font-size: .9rem; font-weight: 600; color: var(--tinta); }
.ac-donde  { font-size: .78rem; color: var(--tinta-suave); }

/* ── Mi cuenta ─────────────────────────────────────────────────────── */
.zona-peligro { border-color: color-mix(in srgb, var(--rojo) 45%, var(--borde)); }
.zona-peligro h3 { color: var(--rojo); }
.lista-cuenta { margin: 0 0 12px; padding-left: 20px; }
.lista-cuenta li { margin: 4px 0; }
.casilla-cuenta { display: flex; gap: 10px; align-items: flex-start; margin: 4px 0 16px; font-size: .92rem; }
.casilla-cuenta input { width: auto; margin-top: 3px; flex: none; }

/* ── Textos legales (privacidad y condiciones) ─────────────────────── */
.texto-legal { max-width: 720px; padding-top: 56px; color: var(--tinta-suave); line-height: 1.7; }
.texto-legal h1 { color: var(--tinta); }
.texto-legal h2 { color: var(--tinta); font-size: 1.15rem; margin: 28px 0 8px; }
.texto-legal ul { padding-left: 22px; }
.texto-legal li { margin: 6px 0; }
.legal-fecha, .legal-nota { color: var(--tinta-tenue); font-size: .88rem; }
.legal-nota { margin-top: 28px; }

/* Páginas públicas abiertas DENTRO de la aplicación (privacidad, condiciones,
   invitación): sin esto la cabecera queda debajo de la hora y la batería. Va
   al final para ganar a la regla de móvil, que pone el relleno a pelo. */
.como-app .cabecera-publica { padding-top: calc(10px + env(safe-area-inset-top)); }

/* Atribución de los datos del mapa (GeoNames la exige). Discreta, abajo a la
   derecha, sin tapar los controles, que van a la izquierda. */
.mapa-atribucion {
    position: absolute; right: 8px; bottom: calc(6px + env(safe-area-inset-bottom)); z-index: 5;
    margin: 0; padding: 2px 7px; border-radius: 6px;
    background: color-mix(in srgb, var(--papel) 80%, transparent);
    font-size: .68rem; line-height: 1.35; color: var(--tinta-tenue); pointer-events: auto;
    white-space: nowrap; text-align: right;
}
.mapa-atribucion a { color: inherit; }
/* En los iPhone más estrechos (SE, mini) no cabe al lado de los controles: encima. */
@media (max-width: 389px) {
    .mapa-atribucion { bottom: calc(66px + env(safe-area-inset-bottom)); }
}
