/* ================================================================
   TJSX MOTION v2 — Capa de movimiento y acabado premium
   Universo TJSX · tema "Gabinete de Curiosidades" v7
   ----------------------------------------------------------------
   · Progresiva: sin JavaScript la página se ve y funciona como antes.
     Todo estado "oculto" cuelga de html.js / .is-ready / .visible,
     y el script de cabecera retira html.js si este módulo no carga.
   · Solo transform y opacity en las piezas grandes; filter únicamente
     en las letras del título (elementos diminutos).
   · Dos niveles, como clase en <html>:
       tm-full  animación completa.
       tm-soft  animación suave: todo sigue animado con fundidos, trazos
                y escalonados, pero sin desplazamientos amplios, parallax,
                inclinación ni luces que sigan al cursor.
     El nivel sale de lo elegido en el engranaje (localStorage
     "tjsx-motion") y, si no se ha elegido, de prefers-reduced-motion.
   · La entrada (preloader) se anima siempre, en los dos niveles.
   · Sin librerías: CSS + Intersection Observer (assets/tjsx-motion.js).
   ================================================================ */

:root {
    --tm-ease: cubic-bezier(.16, 1, .3, 1);     /* salida suave: entradas y reveals */
    --tm-ease-io: cubic-bezier(.4, 0, .2, 1);   /* respuesta rápida: hover y foco */
    --tm-fast: .22s;
    --tm-reveal: .65s;                         /* < 800 ms: el verificador del repo mide la opacidad a los 800 ms */
    --tm-ivory: linear-gradient(180deg, #f7f0de 8%, #e7ddc7 48%, #b3a37d 96%);
    --tm-metal: linear-gradient(180deg, #eeda9f 8%, #cfae6d 52%, #93764a 96%);
    --tm-sheen: linear-gradient(105deg, rgba(255, 255, 255, 0) 38%, rgba(255, 252, 240, .72) 50%, rgba(255, 255, 255, 0) 62%);
}

/* Nivel de movimiento: las entradas usan var(--tm-enter) y las letras var(--tm-letter), así el
   nivel suave cambia los desplazamientos por fundidos sin duplicar reglas. */
html.tm-full { --tm-enter: tm-rise; --tm-letter: tm-letter; scroll-behavior: smooth; }
html.tm-soft { --tm-enter: tm-in; --tm-enter-down: tm-in; --tm-letter: tm-in; scroll-behavior: auto; }

/* ---------- Fotogramas compartidos ---------- */
@keyframes tm-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes tm-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes tm-fade { to { opacity: 1; } }
@keyframes tm-letter {
    from { opacity: 0; transform: translateY(.5em) rotate(2deg); filter: blur(9px); }
    55%  { filter: blur(0); }
    to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes tm-sheen {
    0%   { background-position: 200% 0, 0 0; }
    13%  { background-position: -100% 0, 0 0; }
    100% { background-position: -100% 0, 0 0; }
}
@keyframes tm-latido { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes tm-fog { from { transform: translate3d(0, 0, 0) scale(1); } to { transform: translate3d(-4vw, 3vh, 0) scale(1.08); } }
@keyframes tm-marquee { to { transform: translate3d(-50%, 0, 0); } }
@keyframes tm-scrollcue { 0% { transform: translateY(0); } 100% { transform: translateY(60px); } }
@keyframes tm-bump { 0% { transform: scale(1); } 35% { transform: scale(1.09); color: var(--gold-up, #c4a568); } 100% { transform: scale(1); } }

/* ---------- Entrada (preloader de la portada) ----------
   Se anima sola desde el primer pintado, solo con CSS, igual en los dos niveles de movimiento
   (son trazos y fundidos pequeños; el nivel suave solo quita el flotar y el vuelo final).
   El guion «ENTRADA» de index.html decide cuándo se retira: nunca antes de que la animación
   termine. Las medidas van con clamp() y vmin para que se vea proporcionada en teléfono,
   tableta y escritorio, también con el teléfono en horizontal.
   Todas las apariciones usan «backwards»: el estado de reposo es el visible, así nada queda
   oculto si el navegador no reproduce animaciones. */
@keyframes pre-failsafe { to { opacity: 0; visibility: hidden; } }
@keyframes pre-draw { from { stroke-dashoffset: 100; } }
@keyframes pre-fill { from { fill-opacity: 0; } }
@keyframes pre-pop { from { opacity: 0; transform: scale(0); } }
@keyframes pre-in { from { opacity: 0; } }
@keyframes pre-blink { 0%, 86%, 100% { transform: scaleY(1); } 92% { transform: scaleY(.12); } }
@keyframes pre-twinkle { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.7); } }
@keyframes pre-float { from { transform: translateY(1.5px); } to { transform: translateY(-4.5px); } }
@keyframes pre-letter { from { opacity: 0; transform: translateY(.5em); filter: blur(5px); } }
@keyframes pre-line { from { transform: scaleX(0); } }
@keyframes pre-halo { from { opacity: 0; transform: translate(-50%, -50%) scale(.55); } }
@keyframes pre-breathe { 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 1; } 50% { transform: translate(-50%, -50%) scale(1.08); opacity: .72; } }
@keyframes pre-ring { from { opacity: .75; transform: translate(-50%, -50%) scale(.35); } to { opacity: 0; transform: translate(-50%, -50%) scale(3.4); } }
@keyframes pre-dot { 0%, 100% { opacity: .25; } 40% { opacity: 1; } }

#preloader {
    --ps: 1;                                     /* velocidad: 1 completa · .55 si ya se vio en esta sesión */
    --pre-ghost: clamp(104px, 17vmin, 176px);
    background: transparent; gap: 0; overflow: hidden;
    padding: max(1rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
    transition: none;
    /* Si el guion de la portada no llegara a ejecutarse, la entrada se retira sola */
    animation: pre-failsafe .6s ease 8s forwards;
}
html.intro-quick #preloader { --ps: .55; }
/* Pestaña abierta en segundo plano: la entrada espera en su primer fotograma */
html.intro-hold #preloader, html.intro-hold #preloader * { animation-play-state: paused !important; }
#preloader > * { position: relative; }
#preloader .pre-veil {
    position: absolute; inset: 0;
    background:
        radial-gradient(70% 55% at 50% 44%, rgba(169, 137, 78, .075), transparent 72%),
        var(--ink, #0d0b09);
}
/* Alturas calculadas (sin aspect-ratio) para que la entrada se vea igual en navegadores de hace años */
.pre-ghost-wrap { width: var(--pre-ghost); height: calc(var(--pre-ghost) * .7143); margin-bottom: clamp(.9rem, 2.6vmin, 1.7rem); }
.pre-aura, .pre-ring { position: absolute; left: 50%; top: 46%; pointer-events: none; }
.pre-aura { width: 0; height: 0; }
.pre-halo {
    position: absolute; left: 0; top: 0; width: calc(var(--pre-ghost) * 2.1); height: calc(var(--pre-ghost) * 2.1); border-radius: 50%;
    background: radial-gradient(circle, rgba(196, 165, 104, .17), rgba(196, 165, 104, .05) 42%, transparent 68%);
    transform: translate(-50%, -50%);
    animation: pre-halo calc(1.3s * var(--ps)) var(--tm-ease) calc(.15s * var(--ps)) backwards,
               pre-breathe 3.8s ease-in-out calc(1.5s * var(--ps)) infinite;
}
.pre-ring {
    width: var(--pre-ghost); height: var(--pre-ghost); border-radius: 50%;
    border: 1px solid rgba(196, 165, 104, .7);
    transform: translate(-50%, -50%) scale(.35); opacity: 0;
}
.pre-ghost { position: relative; display: block; width: 100%; height: 100%; overflow: visible; transform-origin: 50% 50%; }
.pre-body {
    stroke: #a9894e; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round;
    fill: #a9894e; fill-opacity: .08;
    stroke-dasharray: 100; stroke-dashoffset: 0;
    animation: pre-draw calc(1.25s * var(--ps)) var(--tm-ease-io) calc(.05s * var(--ps)) backwards,
               pre-fill calc(.7s * var(--ps)) ease calc(.95s * var(--ps)) backwards;
}
.pre-eye {
    fill: #a9894e; opacity: .9; transform-box: fill-box; transform-origin: center;
    animation: pre-pop calc(.42s * var(--ps)) var(--tm-ease) calc(1s * var(--ps)) backwards,
               pre-blink 4.4s ease-in-out calc(2.4s * var(--ps)) infinite;
}
.pre-mouth {
    fill: none; stroke: #a9894e; stroke-width: 1.2; transform-box: fill-box; transform-origin: center;
    animation: pre-pop calc(.42s * var(--ps)) var(--tm-ease) calc(1.12s * var(--ps)) backwards;
}
.pre-arm {
    fill: none; stroke: #a9894e; stroke-width: .9; stroke-linecap: round; opacity: .55;
    stroke-dasharray: 100; stroke-dashoffset: 0;
    animation: pre-draw calc(.5s * var(--ps)) ease calc(1.15s * var(--ps)) backwards;
}
.pre-spark {
    fill: rgba(169, 137, 78, .4); stroke: #a9894e; stroke-width: .8; transform-box: fill-box; transform-origin: center;
    animation: pre-pop calc(.45s * var(--ps)) var(--tm-ease) calc(1.2s * var(--ps)) backwards,
               pre-twinkle 2.6s ease-in-out calc(1.8s * var(--ps)) infinite;
}
.pre-spark + .pre-spark { animation-delay: calc(1.34s * var(--ps)), calc(2.5s * var(--ps)); }
html.tm-full .pre-float { animation: pre-float 3.2s ease-in-out calc(1.3s * var(--ps)) infinite alternate; }

.pre-copy { display: flex; flex-direction: column; align-items: center; max-width: 100%; }
.pre-marca {
    font-family: var(--serif, Georgia, serif); font-size: clamp(1.02rem, 2.7vmin, 1.5rem); font-weight: 600;
    letter-spacing: .42em; text-transform: uppercase; color: var(--bone, #e7ddc7);
    padding-left: .42em; white-space: nowrap;
}
.pre-marca span {
    display: inline-block;
    animation: pre-letter calc(.7s * var(--ps)) var(--tm-ease) backwards;
    animation-delay: calc((.4s + var(--i, 0) * 45ms) * var(--ps));
}
html.tm-soft .pre-marca span { animation-name: pre-in; }
.pre-line {
    width: clamp(150px, 27vmin, 250px); height: 1px; margin-top: clamp(.85rem, 2.2vmin, 1.3rem);
    background: rgba(169, 137, 78, .22); overflow: hidden;
}
.pre-line span {
    display: block; height: 100%; background: linear-gradient(90deg, #a9894e, #c4a568);
    transform-origin: left;
    animation: pre-line calc(1.7s * var(--ps)) var(--tm-ease-io) calc(.15s * var(--ps)) backwards;
}
#preloader .loader-text {
    margin-top: clamp(.8rem, 2vmin, 1.1rem);
    font-size: clamp(.58rem, 1.45vmin, .72rem); letter-spacing: .3em; white-space: nowrap;
    animation: pre-in calc(.8s * var(--ps)) ease calc(.7s * var(--ps)) backwards;
}
.pre-dots i { font-style: normal; animation: pre-dot 1.2s ease-in-out infinite; }
.pre-dots i:nth-child(2) { animation-delay: .18s; }
.pre-dots i:nth-child(3) { animation-delay: .36s; }

/* Salida: el velo se disuelve y deja ver la página; el texto se retira y el fantasma vuela a su
   sitio sobre el título (is-flying) o, con animación suave, se funde (is-fading). */
#preloader.is-flying, #preloader.is-fading { pointer-events: none; }
#preloader.is-flying .pre-veil, #preloader.is-fading .pre-veil { opacity: 0; transition: opacity .7s ease .1s; }
#preloader.is-flying .pre-copy, #preloader.is-fading .pre-copy { opacity: 0; transition: opacity .3s ease; }
#preloader.is-flying .pre-copy { transform: translateY(12px); transition: opacity .3s ease, transform .45s var(--tm-ease-io); }
#preloader.is-flying .pre-aura, #preloader.is-fading .pre-aura { opacity: 0; transition: opacity .45s ease; }
#preloader.is-flying .pre-ghost {
    transform: translate(var(--fly-x, 0), var(--fly-y, 0)) scale(var(--fly-s, 1));
    transition: transform .85s var(--tm-ease);
}
#preloader.is-flying .pre-float, #preloader.is-flying .pre-spark { animation: none; }
#preloader.is-flying .pre-ring { animation: pre-ring .9s var(--tm-ease) forwards; }
#preloader.is-fading .pre-ghost-wrap { opacity: 0; transition: opacity .5s ease; }
#preloader.is-done { visibility: hidden; animation: none; }

/* ---------- Niebla de fondo en deriva lenta ---------- */
html.tm-full .hero-bg-accent { animation: tm-fog 28s ease-in-out infinite alternate; }
html.tm-full .hero-bg-accent-2 { animation: tm-fog 34s ease-in-out infinite alternate-reverse; }

/* ---------- Hero · entrada escalonada ---------- */
.hero-content { position: relative; z-index: 1; }
.tjsx-motes { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; opacity: .9; }

html.js .hero-content > :not(h1),
html.js .hero-content > h1:not(.is-split),
html.js .hero-content .btn { opacity: 0; }
html.js.is-ready .hero-content > h1:not(.is-split) { opacity: 1; animation: var(--tm-enter, tm-rise) 1.1s var(--tm-ease) .05s backwards; }
html.js.is-ready .hero-content > .hero-subtitle { opacity: 1; animation: var(--tm-enter, tm-rise) 1s var(--tm-ease) .8s backwards; }
html.js.is-ready .hero-content > .hero-microcopy { opacity: 1; animation: var(--tm-enter, tm-rise) 1s var(--tm-ease) .95s backwards; }
html.js.is-ready .hero-content > div { opacity: 1; }
html.js.is-ready .hero-content .btn {
    opacity: 1;
    animation: var(--tm-enter, tm-rise) .8s var(--tm-ease) backwards;
    animation-delay: calc(1.1s + var(--i, 0) * 70ms);
}

/* Fantasma del título: el de la entrada vuela hasta aquí (html.ghost-landed) y se queda vivo:
   flota, parpadea, sigue al cursor con la mirada y se asusta si lo tocan. */
.hero-content.has-ghost h1::before { content: none; }
.hero-ghost { width: 104px; height: 74px; margin: 0 auto .9rem; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hero-ghost svg { display: block; width: 100%; height: 100%; overflow: visible; }
.hg-body { fill: rgba(169, 137, 78, .08); stroke: #a9894e; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }
.hg-eye { fill: #a9894e; opacity: .85; transform-box: fill-box; transform-origin: center; }
.hg-eyes { transition: transform .2s ease-out; }
.hg-mouth { fill: none; stroke: #a9894e; stroke-width: 1.2; transform-box: fill-box; transform-origin: center; transition: transform .25s var(--tm-ease); }
.hg-arm { fill: none; stroke: #a9894e; stroke-width: .9; stroke-linecap: round; opacity: .55; }
.hg-spark { fill: rgba(169, 137, 78, .4); stroke: #a9894e; stroke-width: .8; transform-box: fill-box; transform-origin: center; }
.hg-float { transform-box: fill-box; transform-origin: 50% 60%; }
@media (max-width: 560px) { .hero-ghost { width: 84px; height: 60px; } }
@keyframes hg-float { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-5px) rotate(-1.4deg); } }
@keyframes hg-boo {
    0%   { transform: none; }
    25%  { transform: translateY(3px) scale(1.14, .88); }
    55%  { transform: translateY(-11px) scale(.94, 1.1) rotate(3deg); }
    100% { transform: none; }
}
html.js .hero-content > .hero-ghost { opacity: 0; }
/* Respaldo: si el aterrizaje no llegara a avisar, el fantasma aparece igualmente */
html.js.is-ready .hero-content > .hero-ghost { opacity: 0; animation: tm-fade .5s ease 1.6s forwards; }
html.js.ghost-landed .hero-content > .hero-ghost { opacity: 1; animation: none; }
html.js.tm-soft.ghost-landed .hero-content > .hero-ghost { animation: tm-in .6s ease backwards; }
html.ghost-landed .hg-eye { animation: pre-blink 5.2s ease-in-out 1.6s infinite; }
html.ghost-landed .hg-spark { animation: pre-twinkle 2.8s ease-in-out infinite; }
html.ghost-landed .hg-spark + .hg-spark { animation-delay: .9s; }
html.tm-full.ghost-landed .hg-float { animation: hg-float 5.4s ease-in-out infinite; }
html.tm-full .hero-ghost.is-boo .hg-float { animation: hg-boo .7s var(--tm-ease); }
.hero-ghost.is-boo .hg-mouth { transform: scale(1.7, 1.9); }

/* Título partido en letras (solo si el h1 lleva translate="no") */
html.js .hero-content h1.is-split,
html.js .hero-content h1.is-split .gradient-text { background: none; color: transparent; }
.hero-content h1 .ch {
    display: inline-block;
    background-image: var(--tm-sheen), var(--tm-ivory);
    background-size: 200% 100%, 100% 100%;
    background-position: 200% 0, 0 0;
    background-repeat: no-repeat;
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
}
.hero-content h1 .gradient-text .ch { background-image: var(--tm-sheen), var(--tm-metal); }
html.js .hero-content h1.is-split .ch { opacity: 0; }
html.js.is-ready .hero-content h1.is-split .ch {
    opacity: 1;
    animation: var(--tm-letter, tm-letter) 1s var(--tm-ease) backwards, tm-sheen 9s linear infinite;
    animation-delay: calc(80ms + var(--i, 0) * 42ms), calc(2.6s + var(--i, 0) * 55ms);
}
/* Nivel suave: las letras aparecen una a una y el brillo las recorre una sola vez */
html.js.tm-soft.is-ready .hero-content h1.is-split .ch { animation-iteration-count: 1, 1; }

/* Indicador de scroll bajo el hero */
.hero-scroll {
    position: absolute; left: 50%; bottom: .9rem; transform: translateX(-50%);
    width: 44px; height: 44px; display: grid; place-items: center; z-index: 1;
    opacity: 0; color: var(--gold, #a9894e);
}
html.js.is-ready .hero-scroll { animation: tm-fade 1s ease 1.9s forwards; }
html:not(.js) .hero-scroll { opacity: 1; }
.hero-scroll span { display: block; width: 1px; height: 30px; background: rgba(169, 137, 78, .32); position: relative; overflow: hidden; }
.hero-scroll span::after {
    content: ""; position: absolute; left: 0; top: -30px; width: 100%; height: 30px;
    background: linear-gradient(180deg, transparent, #c4a568);
    animation: tm-scrollcue 2.2s var(--tm-ease-io) infinite;
}
.hero-scroll:hover span { background: rgba(196, 165, 104, .6); }
@media (max-height: 640px) { .hero-scroll { display: none; } }

/* ---------- Cinta (marquee) ---------- */
.tjsx-marquee {
    position: relative; z-index: 1; overflow: hidden;
    border-bottom: 1px solid var(--gold-soft, rgba(169, 137, 78, .16));
    background: rgba(13, 11, 9, .6);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.tjsx-marquee-track { display: flex; width: max-content; will-change: transform; }
html.js .tjsx-marquee-track { animation: tm-marquee 80s linear infinite; }
.tjsx-marquee:hover .tjsx-marquee-track,
.tjsx-marquee:focus-within .tjsx-marquee-track,
.tjsx-marquee.is-paused .tjsx-marquee-track { animation-play-state: paused; }
.tjsx-marquee-group {
    display: flex; align-items: center; gap: 2.2rem; padding: .72rem 1.1rem;
    font-family: var(--mono, Consolas, monospace); font-size: .6rem; letter-spacing: .3em; text-transform: uppercase;
    color: var(--bone-faint, #8b8069); white-space: nowrap;
}
.tjsx-marquee-group i { color: var(--gold, #a9894e); font-style: normal; font-size: .68rem; }
.tjsx-marquee-pause {
    position: absolute; right: .55rem; top: 50%; transform: translateY(-50%);
    width: 32px; height: 32px; display: grid; place-items: center; padding: 0;
    background: rgba(13, 11, 9, .9); border: 1px solid var(--gold-line, rgba(169, 137, 78, .32));
    color: var(--bone-faint, #8b8069); cursor: pointer; font-size: .62rem;
    opacity: 0; transition: opacity .3s, color .2s, border-color .2s;
}
.tjsx-marquee:hover .tjsx-marquee-pause, .tjsx-marquee-pause:focus-visible, .tjsx-marquee.is-paused .tjsx-marquee-pause { opacity: 1; }
.tjsx-marquee-pause:hover { color: var(--bone, #e7ddc7); border-color: var(--gold, #a9894e); }
html:not(.js) .tjsx-marquee-pause { display: none; }

/* ---------- Aparición al hacer scroll ---------- */
html.js .reveal {
    opacity: 0; transform: translateY(28px);
    transition: opacity var(--tm-reveal) var(--tm-ease), transform var(--tm-reveal) var(--tm-ease);
}
html.js .reveal.visible { opacity: 1; transform: none; }
/* Una sección aún sin revelar está 28 px más abajo: se compensa para que, al llegar desde
   el menú, quede a la misma altura que las demás cuando termina su aparición. */
html.js .reveal:not(.visible) { scroll-margin-top: calc(1rem + 28px); }

/* Hijos escalonados (contenedores con data-stagger) */
html.js [data-stagger] > * { opacity: 0; }
html.js .visible[data-stagger] > * {
    opacity: 1;
    animation: var(--tm-enter, tm-rise) .85s var(--tm-ease) backwards;
    animation-delay: calc(120ms + var(--i, 0) * 70ms);
}

/* Títulos de sección: emergen del desenfoque (elementos pequeños; el texto no se parte) */
html.js .section-title,
html.js #mission .mission-text h2,
html.js #collab-title,
html.js #visitor-counter-title,
html.js #support h2 {
    opacity: 0; transform: translateY(14px); filter: blur(7px);
    transition: opacity 1s var(--tm-ease), transform 1s var(--tm-ease), filter 1s var(--tm-ease);
}
html.js .section-title.visible,
html.js .visible .section-title,
html.js #collaborations.visible #collab-title,
html.js #visitas.visible #visitor-counter-title,
html.js #mission.visible .mission-text h2,
html.js #support.visible h2 { opacity: 1; transform: none; filter: none; }

/* Cabeceras de sección: ornamento que sube y filete que se traza */
html.js .section-title::before,
html.js #mission .mission-text h2::before,
html.js #collab-title::before,
html.js #visitor-counter-title::before,
html.js #support h2::before {
    opacity: 0; transform: translateY(10px);
    transition: opacity .9s var(--tm-ease) .15s, transform .9s var(--tm-ease) .15s;
}
html.js .section-title.visible::before,
html.js .visible .section-title::before,
html.js #collaborations.visible #collab-title::before,
html.js #visitas.visible #visitor-counter-title::before,
html.js #mission.visible .mission-text h2::before,
html.js #support.visible h2::before { opacity: 1; transform: none; }

html.js .section-title::after,
html.js #mission .mission-text h2::after,
html.js #support h2::after { transform: scaleX(0); transition: transform 1.2s var(--tm-ease) .4s; }
html.js .section-title.visible::after,
html.js .visible .section-title::after,
html.js #mission.visible .mission-text h2::after,
html.js #support.visible h2::after { transform: scaleX(1); }

/* ---------- Índice (nav): progreso, estado al desplazar, enlace activo ---------- */
.indice { transition: background .35s ease, box-shadow .35s ease; }
html.js .indice.is-scrolled {
    background: rgba(13, 11, 9, .84);
    -webkit-backdrop-filter: blur(12px) saturate(1.15);
    backdrop-filter: blur(12px) saturate(1.15);
    box-shadow: 0 12px 34px -20px rgba(0, 0, 0, .9);
}
.tjsx-progress {
    position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
    transform: scaleX(var(--p, 0)); transform-origin: left;
    background: linear-gradient(90deg, var(--gold, #a9894e), var(--gold-up, #c4a568));
    pointer-events: none; will-change: transform;
}
.indice ul:not(.rail-list) a { position: relative; transition: color var(--tm-fast) var(--tm-ease-io); }
.indice ul:not(.rail-list) a::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px;
    background: var(--gold-up, #c4a568);
    transform: scaleX(0); transform-origin: left;
    transition: transform .35s var(--tm-ease);
}
.indice ul:not(.rail-list) a:hover::after,
.indice ul:not(.rail-list) a[aria-current="location"]::after { transform: scaleX(1); }
.indice ul:not(.rail-list) a[aria-current="location"] { color: var(--bone, #e7ddc7); }
.nav-marca { transition: color var(--tm-fast), letter-spacing .4s var(--tm-ease); }
.nav-marca:hover { letter-spacing: .34em; }

/* La altura real del índice manda sobre el desplazamiento a las anclas */
html { scroll-padding-top: calc(var(--nav-h, 5rem) + .75rem); }
[id] { scroll-margin-top: 1rem; } /* se suma al scroll-padding: aire bajo el índice */

/* ---------- Índice deslizable único (rail de capítulos) ---------- */
.indice-inner:has(.rail) { flex-wrap: nowrap; align-items: center; gap: .4rem 1.4rem; padding: .45rem 0 .4rem; }
.rail { display: flex; align-items: center; gap: .1rem; flex: 1 1 auto; min-width: 0; }
.rail-viewport {
    position: relative; flex: 1 1 auto; min-width: 0;
    overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -ms-overflow-style: none;
    padding: .3rem 0 .45rem; cursor: grab;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 1.4rem, #000 calc(100% - 1.4rem), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 1.4rem, #000 calc(100% - 1.4rem), transparent);
}
.rail-viewport::-webkit-scrollbar { display: none; }
.rail-viewport.is-dragging { cursor: grabbing; }
.rail-viewport.is-dragging a { pointer-events: none; }
.indice .rail-list {
    list-style: none; margin: 0; padding: 0 1.2rem;
    display: flex; flex-wrap: nowrap; gap: .1rem; width: max-content;
}
.indice .rail-list a {
    display: inline-flex; align-items: baseline; gap: .45rem;
    padding: .42rem .7rem; min-height: 34px;
    font-family: var(--mono, Consolas, monospace); font-size: .64rem; letter-spacing: .18em; text-transform: uppercase;
    color: var(--bone-faint, #8b8069); white-space: nowrap;
    transition: color .25s var(--tm-ease-io);
}
.indice .rail-list a:hover, .indice .rail-list a.is-active { color: var(--bone, #e7ddc7); }
.indice .rail-list a:focus-visible { outline: 2px solid var(--gold-up, #c4a568); outline-offset: -2px; }
.rail-num { color: var(--gold, #a9894e); font-size: .58rem; letter-spacing: .1em; opacity: .85; transition: color .25s, opacity .25s; }
.indice .rail-list a.is-active .rail-num { color: var(--gold-up, #c4a568); opacity: 1; }
.rail-line {
    position: absolute; left: 0; bottom: .3rem; height: 1px; width: 100px;
    background: linear-gradient(90deg, var(--gold, #a9894e), var(--gold-up, #c4a568));
    transform-origin: left; transform: translateX(0) scaleX(0);
    transition: transform .55s var(--tm-ease), opacity .3s;
    opacity: 0; pointer-events: none;
}
.rail-arrow {
    flex: none; width: 30px; height: 30px; display: grid; place-items: center; padding: 0;
    background: transparent; border: 1px solid transparent; color: var(--bone-faint, #8b8069);
    cursor: pointer; font-size: .62rem;
    transition: color .2s, border-color .2s, opacity .25s, transform .25s var(--tm-ease);
}
.rail-arrow:hover { color: var(--bone, #e7ddc7); border-color: var(--gold-line, rgba(169, 137, 78, .32)); }
.rail-arrow:active { transform: scale(.92); }
.rail-arrow:focus-visible { outline: 2px solid var(--gold-up, #c4a568); outline-offset: 2px; }
.rail.at-start .rail-prev, .rail.at-end .rail-next { opacity: .22; pointer-events: none; }
.rail.no-overflow .rail-arrow { display: none; }
html:not(.js) .rail-arrow { display: none; }
html.js .rail-list li { opacity: 0; }
html.js.is-ready .rail-list li { opacity: 1; animation: var(--tm-enter-down, tm-rise-down) .6s var(--tm-ease) backwards; animation-delay: calc(.15s + var(--i, 0) * 40ms); }
@keyframes tm-rise-down { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@media (max-width: 760px) {
    .indice-inner:has(.rail) { flex-wrap: wrap; justify-content: center; gap: .1rem; padding: .5rem 0 .2rem; }
    .indice-inner:has(.rail) .nav-marca { width: 100%; text-align: center; font-size: .72rem; }
    .rail { width: 100%; }
    .rail-arrow { display: none; }
    .indice .rail-list { padding: 0 .6rem; }
    .indice .rail-list a { font-size: .6rem; letter-spacing: .14em; padding: .4rem .55rem; }
}

/* ---------- Menú desplegable del hero: un solo índice para toda la página ---------- */
.menu-launch { display: flex; justify-content: center; }
.menu-halo { position: relative; display: inline-block; }
.menu-halo::before {
    content: ""; position: absolute; inset: -7px; pointer-events: none;
    border: 1px solid rgba(196, 165, 104, .38); opacity: .3;
}
/* El halo aparece después del botón (antes se veía su marco vacío mientras el botón aún no llegaba) */
html.js .menu-halo::before { opacity: 0; }
html.js.is-ready .menu-halo::before { opacity: .22; transition: opacity .8s ease 1.7s; animation: tm-halo 3.4s ease-in-out 2.6s infinite; }
@keyframes tm-halo { 0%, 100% { opacity: .22; transform: scale(1); } 50% { opacity: .75; transform: scale(1.035); } }
.menu-trigger { display: inline-flex; align-items: center; gap: .6rem; font-size: .86rem; padding: .95rem 1.8rem; }
.menu-trigger i { margin: 0; }
.menu-trigger .menu-caret { font-size: .72em; transition: transform .35s var(--tm-ease); }
.menu-trigger[aria-expanded="true"] .menu-caret { transform: rotate(180deg); }

.indice-menu { position: fixed; inset: 0; z-index: 1400; display: grid; place-items: center; padding: 1rem; }
.indice-menu[hidden] { display: none; }
.indice-menu-backdrop {
    position: absolute; inset: 0; background: rgba(8, 7, 5, .68);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    opacity: 0; transition: opacity .35s ease;
}
.indice-menu.is-open .indice-menu-backdrop { opacity: 1; }
/* El panel no se desplaza (su marco interior queda fijo). Se desplaza .indice-menu-scroll, que ocupa todo
   el panel: el dedo puede empezar en cualquier punto, también sobre el título, que se queda fijo arriba
   mientras la lista pasa por debajo. */
.indice-menu-panel {
    --mp: clamp(1.2rem, 3vw, 2rem);
    position: relative; width: min(780px, 100%);
    max-height: 86vh; max-height: min(86dvh, 760px);
    display: flex; flex-direction: column; overflow: hidden;
    background: linear-gradient(180deg, var(--ink-panel, #16120c), var(--ink-2, #131009));
    border: 1px solid var(--gold-line, rgba(169, 137, 78, .32));
    box-shadow: 0 30px 80px rgba(0, 0, 0, .65);
    text-align: left;
    opacity: 0; transform: translateY(16px) scale(.97);
    transition: opacity .35s var(--tm-ease), transform .5s var(--tm-ease);
}
.indice-menu-panel::before { content: ""; position: absolute; inset: 7px; z-index: 2; border: 1px solid var(--gold-soft, rgba(169, 137, 78, .16)); pointer-events: none; }
.indice-menu.is-open .indice-menu-panel { opacity: 1; transform: none; }
.indice-menu-scroll {
    flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
    padding: 0 var(--mp) var(--mp);
}
.indice-menu-head {
    position: sticky; top: 0; z-index: 1;
    display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
    margin: 0 calc(-1 * var(--mp)) .9rem; padding: var(--mp) var(--mp) .5rem;
    background: var(--ink-panel, #16120c);
}
/* Desvanecido bajo la cabecera: ocupa solo el hueco que la separa de la lista, así en reposo no tapa
   nada y al desplazar la lista el texto se difumina antes de llegar al título. */
.indice-menu-head::after {
    content: ""; position: absolute; left: 0; right: 0; top: 100%; height: .9rem;
    background: linear-gradient(180deg, var(--ink-panel, #16120c), rgba(22, 18, 12, 0));
    pointer-events: none;
}
.indice-menu-kicker { display: block; margin-bottom: .35rem; font-family: var(--mono, Consolas, monospace); font-size: .62rem; letter-spacing: .3em; text-transform: uppercase; color: var(--gold, #a9894e); }
.indice-menu-head :is(h2, h3) { margin: 0; padding: 0; border: 0; font-size: clamp(1.3rem, 3vw, 1.7rem); }
.indice-menu-close {
    flex: none; width: 40px; height: 40px; display: grid; place-items: center; padding: 0;
    border: 1px solid var(--gold-line, rgba(169, 137, 78, .32)); background: transparent; color: var(--bone-faint, #8b8069);
    cursor: pointer; transition: color .2s, border-color .2s, transform .35s var(--tm-ease);
}
.indice-menu-close:hover { color: var(--bone, #e7ddc7); border-color: var(--gold, #a9894e); transform: rotate(90deg); }
.indice-menu-close:focus-visible { outline: 2px solid var(--gold-up, #c4a568); outline-offset: 2px; }
.indice-menu-aspa { font-size: 1.35rem; line-height: 1; }
.indice-menu-grid { display: grid; grid-template-columns: 1.45fr 1fr; gap: 1.2rem 2rem; align-content: start; }
/* Columna izquierda con varios grupos apilados (portada y páginas propias) */
.indice-menu-col { display: grid; gap: 1.2rem; align-content: start; min-width: 0; }
.indice-menu-group :is(h3, h4) {
    margin: 0 0 .55rem; padding-bottom: .45rem; border-bottom: 1px dotted var(--gold-line, rgba(169, 137, 78, .32));
    font-family: var(--mono, Consolas, monospace); font-size: .62rem; font-weight: 400; letter-spacing: .26em; text-transform: uppercase; color: var(--bone-faint, #8b8069);
}
.indice-menu-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: .1rem .8rem; }
.indice-menu-list--direct { grid-template-columns: 1fr; }
.indice-menu-list a {
    display: flex; align-items: baseline; gap: .7rem; padding: .5rem .55rem;
    color: var(--bone-dim, #b9ac91); text-decoration: none; border: 1px solid transparent;
    transition: border-color .25s, background .25s, transform .3s var(--tm-ease);
}
.indice-menu-list a:focus-visible { border-color: var(--gold-line, rgba(169, 137, 78, .32)); background: var(--gold-ghost, rgba(169, 137, 78, .07)); transform: translateX(3px); outline: none; }
/* En pantallas táctiles el «hover» se queda pegado tras tocar: solo se aplica con ratón */
@media (hover: hover) {
    .indice-menu-list a:hover { border-color: var(--gold-line, rgba(169, 137, 78, .32)); background: var(--gold-ghost, rgba(169, 137, 78, .07)); transform: translateX(3px); }
}
.im-num { flex: none; min-width: 2em; text-align: right; font-family: var(--mono, Consolas, monospace); font-size: .62rem; letter-spacing: .1em; color: var(--gold, #a9894e); }
.im-num i { font-size: .8rem; }
.im-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.im-name { font-family: var(--serif, Georgia, serif); font-weight: 600; font-size: 1.02rem; color: var(--bone, #e7ddc7); }
.im-name .im-ext { font-size: .6em; color: var(--gold, #a9894e); margin-left: .3em; }
.im-desc { font-size: .74rem; color: var(--bone-faint, #8b8069); }
.indice-menu-list a.is-current { border-color: rgba(196, 165, 104, .35); background: var(--gold-ghost, rgba(169, 137, 78, .07)); }
.indice-menu-list a.is-current .im-name { color: var(--gold-up, #c4a568); }
.indice-menu-list a.is-current .im-name::after { content: " · estás aquí"; font-family: var(--mono, Consolas, monospace); font-size: .56rem; font-weight: 400; letter-spacing: .14em; text-transform: uppercase; color: var(--gold, #a9894e); }
html[lang^="en"] .indice-menu-list a.is-current .im-name::after { content: " · you are here"; }
.indice-menu-note { margin: 1rem 0 0; font-family: var(--mono, Consolas, monospace); font-size: .64rem; letter-spacing: .06em; color: var(--bone-faint, #8b8069); }
.indice-menu-note i { color: var(--gold, #a9894e); margin-right: .2em; }
html.js .indice-menu li { opacity: 0; }
/* Escalonado corto: todas las opciones están visibles en menos de 1 s, aunque se deslice enseguida */
html.js .indice-menu.is-open li { opacity: 1; animation: var(--tm-enter, tm-rise) .45s var(--tm-ease) backwards; animation-delay: calc(60ms + min(var(--i, 0), 8) * 30ms); }
/* Con ratón se bloquea la página de fondo. En pantallas táctiles NO: los navegadores internos de algunas
   apps (Threads, Instagram, Facebook) recargan la página al deslizar hacia abajo cuando la página está en
   su posición 0, aunque el dedo esté dentro del menú. tjsx-motion.js la mantiene a 2 px mientras el menú
   está abierto y aquí se evita que los gestos fuera de la lista muevan la página. */
@media (hover: hover) and (pointer: fine) { html.menu-open, html.menu-open body { overflow: hidden; } }
@media not all and (hover: hover) and (pointer: fine) {
    .indice-menu, .indice-menu-panel { touch-action: pinch-zoom; }
    .indice-menu-scroll { touch-action: pan-y pinch-zoom; }
}

/* Índice flotante: aparece al dejar atrás el hero y abre el mismo menú */
.indice-fab {
    position: fixed; left: 50%; bottom: 1.5rem; z-index: 1190;
    display: inline-flex; align-items: center; gap: .5rem;
    min-height: 40px; padding: .6rem 1.05rem;
    background: rgba(22, 18, 12, .92); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border: 1px solid var(--gold-line, rgba(169, 137, 78, .32)); color: var(--bone, #e7ddc7);
    font-family: var(--mono, Consolas, monospace); font-size: .66rem; letter-spacing: .22em; text-transform: uppercase; cursor: pointer;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
    opacity: 0; transform: translate(-50%, 12px); pointer-events: none;
    transition: opacity .35s ease, transform .4s var(--tm-ease), border-color .25s;
}
.indice-fab[hidden] { display: none; }
.indice-fab span { color: var(--gold-up, #c4a568); }
.indice-fab.is-visible { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.indice-fab:hover { border-color: var(--gold, #a9894e); }
.indice-fab:focus-visible { outline: 2px solid var(--gold-up, #c4a568); outline-offset: 3px; }
html.menu-open .indice-fab { opacity: 0; pointer-events: none; }
/* Teléfono: el índice ocupa toda la pantalla (sin franja de fondo que se pueda tocar sin querer);
   la cabecera con la × queda fija arriba y todo el panel responde al dedo. */
@media (max-width: 720px) {
    .indice-menu { place-items: stretch; padding: 0; }
    .indice-menu-panel {
        --mp: 1.1rem;
        width: 100%; height: 100%; max-height: none; border: 0; box-shadow: none;
        transform: translateY(28px);
    }
    .indice-menu-head { padding-top: max(1.1rem, env(safe-area-inset-top)); }
    .indice-menu-close { width: 44px; height: 44px; }
    .indice-menu-scroll { padding-bottom: max(1.6rem, env(safe-area-inset-bottom)); }
    .indice-menu-grid, .indice-menu-list { grid-template-columns: 1fr; }
    .indice-fab { bottom: 1.35rem; }
}

/* Notita del índice (15): explica el botón «Índice». Asoma sobre él; se cierra con la × y se vuelve a
   abrir con el botón «?» que va a su derecha. */
.indice-nota {
    /* Por delante del traductor (1250) mientras está abierta; por detrás del índice (1400) */
    position: fixed; left: 50%; bottom: calc(1.5rem + 56px); z-index: 1252;
    width: min(340px, calc(100vw - 2rem));
    display: flex; align-items: flex-start; gap: .75rem;
    padding: .9rem .8rem .95rem 1rem;
    background: linear-gradient(180deg, rgba(28, 23, 15, .98), rgba(19, 16, 9, .98));
    border: 1px solid var(--gold-line, rgba(169, 137, 78, .32)); border-left: 3px solid var(--gold, #a9894e);
    box-shadow: 0 18px 44px rgba(0, 0, 0, .6);
    color: var(--bone-dim, #b9ac91); text-align: left;
    opacity: 0; transform: translate(-50%, 10px); pointer-events: none;
    transition: opacity .35s ease, transform .45s var(--tm-ease, cubic-bezier(.16, 1, .3, 1));
}
.indice-nota[hidden] { display: none; }
.indice-nota.is-in { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.indice-nota::after {
    content: ""; position: absolute; left: 50%; bottom: -7px; width: 12px; height: 12px; margin-left: -6px;
    background: #141009; border-right: 1px solid var(--gold-line, rgba(169, 137, 78, .32)); border-bottom: 1px solid var(--gold-line, rgba(169, 137, 78, .32));
    transform: rotate(45deg);
}
.indice-nota-sello { flex: none; color: var(--gold-up, #c4a568); font-size: 1rem; line-height: 1.4; }
.indice-nota-texto { display: flex; flex-direction: column; gap: .25rem; min-width: 0; flex: 1; }
.indice-nota-texto strong { font-family: var(--serif, Georgia, serif); font-size: 1.02rem; font-weight: 600; line-height: 1.25; color: var(--bone, #e7ddc7); }
.indice-nota-texto span { font-size: .84rem; line-height: 1.45; }
.indice-nota-cerrar {
    flex: none; width: 34px; height: 34px; margin: -.35rem -.25rem 0 0; display: grid; place-items: center; padding: 0;
    background: transparent; border: 1px solid transparent; color: var(--bone-faint, #8b8069);
    font-size: 1.25rem; line-height: 1; cursor: pointer; transition: color .2s, border-color .2s;
}
.indice-nota-cerrar:hover { color: var(--bone, #e7ddc7); border-color: var(--gold-line, rgba(169, 137, 78, .32)); }
.indice-ayuda {
    position: fixed; z-index: 1190; left: calc(50% + 72px); bottom: 1.5rem;
    width: 36px; height: 36px; padding: 0; display: grid; place-items: center; border-radius: 50%;
    background: rgba(22, 18, 12, .92); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border: 1px solid var(--gold-line, rgba(169, 137, 78, .32)); color: var(--gold-up, #c4a568);
    font-family: var(--serif, Georgia, serif); font-size: 1.05rem; font-weight: 700; line-height: 1; cursor: pointer;
    box-shadow: 0 8px 22px rgba(0, 0, 0, .45);
    opacity: 0; transform: scale(.85); pointer-events: none;
    transition: opacity .3s ease, transform .35s var(--tm-ease, cubic-bezier(.16, 1, .3, 1)), border-color .25s;
}
.indice-ayuda[hidden] { display: none; }
.indice-ayuda.is-visible { opacity: 1; transform: none; pointer-events: auto; }
.indice-ayuda:hover { border-color: var(--gold, #a9894e); }
.indice-nota-cerrar:focus-visible, .indice-ayuda:focus-visible { outline: 2px solid var(--gold-up, #c4a568); outline-offset: 2px; }
html.menu-open .indice-nota, html.menu-open .indice-ayuda,
html.chat-open .indice-nota, html.chat-open .indice-ayuda { opacity: 0; pointer-events: none; }
html.tm-soft .indice-nota, html.tm-soft .indice-nota.is-in { transform: translate(-50%, 0); transition: opacity .35s ease; }
html.tm-soft .indice-ayuda { transform: none; transition: opacity .3s ease, border-color .25s; }
@media (max-width: 720px) {
    .indice-nota { bottom: calc(1.35rem + 56px); }
}

/* El pie deja sitio a los botones flotantes (traductor, índice y asistente) para que no tapen su texto */
html.has-indice-fab footer { padding-bottom: 5.8rem; }
@media (max-width: 720px) { html.has-indice-fab footer { padding-bottom: 10rem; } }

/* Enlaces dentro de texto: subrayado fino para no depender solo del color */
.para-ti-note a, .embed-note a, .career-layer li > a, .career-layer p > a {
    text-decoration: underline; text-decoration-color: rgba(196, 165, 104, .55);
    text-decoration-thickness: 1px; text-underline-offset: .2em;
}

/* ---------- Botones: barrido dorado y leve elevación ---------- */
.btn {
    position: relative; overflow: hidden; isolation: isolate;
    transition: color var(--tm-fast) var(--tm-ease-io), border-color var(--tm-fast) var(--tm-ease-io),
                transform var(--tm-fast) var(--tm-ease-io), background var(--tm-fast) var(--tm-ease-io);
}
.btn::before {
    content: ""; position: absolute; inset: 0; z-index: -1;
    background: var(--gold-up, #c4a568);
    transform: translateX(-102%) skewX(-8deg); transform-origin: left;
    transition: transform .42s var(--tm-ease);
}
.btn:hover::before, .btn:focus-visible::before { transform: translateX(0) skewX(0); }
.btn:hover { background: transparent; transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(.985); }
.btn.btn-cyan, .btn.btn-cyan:hover { background: linear-gradient(180deg, #b3925a, #8f7440); }
.btn.btn-magenta::before { background: var(--garnet, #77302a); }
.btn.btn-magenta:hover { background: transparent; }
.btn.btn-linkedin i { color: #7fb0dd; transition: color var(--tm-fast); }
.btn.btn-linkedin:hover i { color: inherit; }

/* Botones de la capa profesional (perfil-profesional) */
.boton { transition: transform var(--tm-fast) var(--tm-ease-io), border-color var(--tm-fast), background var(--tm-fast), color var(--tm-fast); }
.boton:hover { transform: translateY(-1px); }

/* ---------- Enlaces del árbol (Conecta) ---------- */
.link-tree-btn { transition: border-color .3s var(--tm-ease-io), background .3s var(--tm-ease-io), transform .35s var(--tm-ease); }
.link-tree-btn:hover { transform: translateX(4px); }
.link-tree-btn > i:last-of-type { transition: transform .35s var(--tm-ease), opacity .3s; }
.link-tree-btn:hover > i:last-of-type { transform: translateX(4px); opacity: 1 !important; }

/* ---------- Paneles: foco de luz que sigue al cursor y elevación ---------- */
.glass-panel { isolation: isolate; }
.tjsx-spot {
    position: absolute !important; inset: 0 !important; margin: 0 !important; padding: 0 !important;
    z-index: -1; pointer-events: none; opacity: 0; font-size: 0; line-height: 0;
    transition: opacity .45s var(--tm-ease-io);
    background: radial-gradient(280px circle at var(--mx, 50%) var(--my, 50%), rgba(196, 165, 104, .11), transparent 60%);
}
.glass-panel:hover > .tjsx-spot { opacity: 1; }
a.glass-panel, .album-card, .para-ti-card, .project-card, .patreon-card, .stat-tile, .info-card {
    transition: border-color .35s var(--tm-ease-io), transform .5s var(--tm-ease);
}
a.glass-panel:hover, .album-card:hover, .para-ti-card:hover, .project-card:hover, .patreon-card:hover {
    border-color: rgba(196, 165, 104, .6) !important;
}
.album-card:hover, .para-ti-card:hover, .project-card:hover, .patreon-card:hover { transform: translateY(-4px); }
[data-tilt] { transition: transform .35s var(--tm-ease), border-color .35s var(--tm-ease-io); transform-style: preserve-3d; }
.badge, .tag { transition: border-color var(--tm-fast), color var(--tm-fast); }
.album-card { overflow: hidden; }
.album-cover { transition: transform .9s var(--tm-ease), filter .6s ease; }
.album-card:hover .album-cover { transform: scale(1.04); filter: sepia(.1) saturate(.95) brightness(1); }
.spotify-embed-wrap { transition: border-color .4s var(--tm-ease-io); }
.spotify-embed-wrap:hover { border-color: var(--gold, #a9894e); }
.social-links a { display: inline-block; transition: color var(--tm-fast), transform .3s var(--tm-ease); }
.social-links a:hover { transform: translateY(-3px); }

/* ---------- Contador: pequeño latido al cambiar la cifra ---------- */
.visitas-numero { display: inline-block; }
.visitas-numero.is-bump { animation: tm-bump .6s var(--tm-ease); }

/* ---------- Farol: luz suave que acompaña al cursor ---------- */
.tjsx-lantern {
    position: fixed; left: -340px; top: -340px; width: 680px; height: 680px;
    border-radius: 50%; pointer-events: none; z-index: 45;
    background: radial-gradient(circle, rgba(196, 165, 104, .085), rgba(196, 165, 104, .03) 40%, transparent 64%);
    opacity: 0; transition: opacity .8s ease; will-change: transform;
}
html.has-pointer .tjsx-lantern.is-on { opacity: 1; }

/* ---------- Volver arriba flotante ---------- */
.tjsx-top {
    position: fixed; right: 5.5rem; bottom: 1.75rem; z-index: 1190;
    width: 42px; height: 42px; border-radius: 50%; padding: 0;
    border: 1px solid var(--gold-line, rgba(169, 137, 78, .32));
    background: rgba(22, 18, 12, .92); color: var(--gold-up, #c4a568);
    display: grid; place-items: center; cursor: pointer;
    opacity: 0; transform: translateY(10px) scale(.9); pointer-events: none;
    transition: opacity .35s ease, transform .35s var(--tm-ease), border-color .25s;
}
.tjsx-top svg { width: 16px; height: 16px; }
.tjsx-top.is-visible { opacity: 1; transform: none; pointer-events: auto; }
.tjsx-top:hover { border-color: var(--gold, #a9894e); transform: translateY(-2px); }
.tjsx-top:focus-visible { outline: 2px solid var(--gold-up, #c4a568); outline-offset: 3px; }
html.chat-open .tjsx-top { opacity: 0; pointer-events: none; }
@media (max-width: 560px) { .tjsx-top { right: 5.1rem; bottom: 1.6rem; } }

/* ---------- Capa profesional: entrada del encabezado ---------- */
html.js:not(.is-ready) .encabezado > * { opacity: 0; }
html.js.is-ready .encabezado > * { animation: var(--tm-enter, tm-rise) .9s var(--tm-ease) backwards; }
html.js.is-ready .encabezado > :nth-child(2) { animation-delay: .08s; }
html.js.is-ready .encabezado > :nth-child(3) { animation-delay: .16s; }
html.js.is-ready .encabezado > :nth-child(4) { animation-delay: .24s; }
html.js.is-ready .encabezado > :nth-child(5) { animation-delay: .32s; }
html.js.is-ready .encabezado > :nth-child(n+6) { animation-delay: .4s; }

/* ---------- Marcos que se trazan al aparecer el panel (nivel completo) ---------- */
html.js.tm-full :is(#mission, #visitas, #collaborations).glass-panel.reveal::before {
    clip-path: inset(0 100% 100% 0);
    transition: clip-path 1.4s var(--tm-ease) .3s;
}
html.js.tm-full :is(#mission, #visitas, #collaborations).glass-panel.reveal.visible::before { clip-path: inset(0 0 0 0); }

/* ---------- Iconos de la misión: llegan uno a uno y quedan flotando ---------- */
@keyframes tm-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
html.js.tm-full .mission-icons.visible > i {
    animation: var(--tm-enter, tm-rise) .85s var(--tm-ease) backwards, tm-bob 4.8s ease-in-out infinite;
    animation-delay: calc(120ms + var(--i, 0) * 90ms), calc(1.3s + var(--i, 0) * .4s);
}

/* ---------- Botón con imán: el control principal se acerca al cursor ---------- */
[data-magnet] { transition: transform .5s var(--tm-ease); will-change: transform; }
[data-magnet].is-near { transition: transform .18s ease-out; }

/* ---------- Reposo: fuera de la vista se detienen las animaciones continuas ----------
   Solo las continuas: las de entrada siguen su curso para que nada se quede a medio aparecer.
   Donde un elemento lleva las dos (entrada, continua), se detiene solo la segunda. */
.tm-away .hg-float, .tm-away .hg-eye, .tm-away .hg-spark,
.tm-away .menu-halo::before, .tm-away .hero-scroll span::after { animation-play-state: paused !important; }
.tm-away .hero-content h1.is-split .ch, .mission-icons.tm-away > i { animation-play-state: running, paused !important; }

/* ---------- Barra de lectura: progreso de la página ---------- */
.tjsx-readbar {
    position: fixed; left: 0; top: 0; z-index: 1300; width: 100%; height: 2px;
    transform: scaleX(var(--p, 0)); transform-origin: left;
    background: linear-gradient(90deg, var(--gold, #a9894e), var(--gold-up, #c4a568));
    pointer-events: none; will-change: transform;
}
html.menu-open .tjsx-readbar, html.chat-open .tjsx-readbar { opacity: 0; }

/* ---------- Nivel de movimiento: selector del engranaje y aviso del hero ---------- */
/* La nota del engranaje no llegaba al contraste mínimo (4,09:1); con este tono supera 4,5:1 */
.tjsx-gear-panel .tjsx-gear-nota { color: #9a8f78; }
.tjsx-gear-motion { margin-top: 12px; padding-top: 11px; border-top: 1px dotted rgba(169, 137, 78, .35); }
.tm-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.tm-seg button {
    min-height: 36px; padding: 6px 4px; cursor: pointer;
    background: transparent; color: #b9ac91; border: 1px solid rgba(169, 137, 78, .35);
    font-family: Consolas, 'Cascadia Mono', 'Courier New', monospace; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
    transition: border-color var(--tm-fast), color var(--tm-fast), background var(--tm-fast);
}
.tm-seg button:hover { border-color: #a9894e; color: #e7ddc7; }
.tm-seg button[aria-pressed="true"] { border-color: #c4a568; color: #151009; background: linear-gradient(180deg, #b3925a, #8f7440); }
.tm-seg button:focus-visible { outline: 2px solid #c4a568; outline-offset: 2px; }
.tm-hint { margin-top: 1.1rem; margin-bottom: .7rem; }
.tm-hint button {
    min-height: 32px; padding: .35rem .2rem; cursor: pointer;
    background: none; border: 0; border-bottom: 1px dotted var(--gold-line, rgba(169, 137, 78, .32));
    font-family: var(--mono, Consolas, monospace); font-size: .62rem; letter-spacing: .16em; text-transform: uppercase;
    color: var(--bone-faint, #8b8069);
    transition: color var(--tm-fast), border-color var(--tm-fast);
}
.tm-hint button b { font-weight: 400; color: var(--gold-up, #c4a568); }
.tm-hint button:hover { color: var(--bone, #e7ddc7); border-bottom-color: var(--gold, #a9894e); }
.tm-hint button:focus-visible { outline: 2px solid var(--gold-up, #c4a568); outline-offset: 3px; }

/* ---------- Paso entre páginas del sitio (navegadores que lo admiten) ---------- */
@media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; }
    ::view-transition-old(root) { animation: tm-vt-out .26s ease both; }
    ::view-transition-new(root) { animation: tm-vt-in .4s ease both; }
}
@keyframes tm-vt-out { to { opacity: 0; } }
@keyframes tm-vt-in { from { opacity: 0; } }

/* ---------- Nivel suave (html.tm-soft) ----------
   Todo sigue animado, pero con fundidos, trazos y apariciones escalonadas: sin desplazamientos
   amplios, parallax, inclinación ni luces que sigan al cursor. Lo activa quien pide menos
   movimiento en su sistema o quien elige «Suave» en el engranaje. */
html.js.tm-soft .reveal { transform: none; transition: opacity var(--tm-reveal) ease; }
html.js.tm-soft .reveal:not(.visible) { scroll-margin-top: 1rem; }
html.js.tm-soft .section-title, html.js.tm-soft #mission .mission-text h2, html.js.tm-soft #collab-title,
html.js.tm-soft #visitor-counter-title, html.js.tm-soft #support h2 { transform: none; filter: none; transition: opacity .7s ease; }
html.js.tm-soft .section-title::before, html.js.tm-soft #mission .mission-text h2::before, html.js.tm-soft #collab-title::before,
html.js.tm-soft #visitor-counter-title::before, html.js.tm-soft #support h2::before { transform: none; transition: opacity .7s ease .12s; }
html.tm-soft .indice-menu-panel { transform: none; transition: opacity .3s ease; }
html.js.tm-soft.is-ready .menu-halo::before { animation-name: tm-halo-soft; }
@keyframes tm-halo-soft { 0%, 100% { opacity: .22; } 50% { opacity: .7; } }
html.tm-soft .indice-menu-list a:hover, html.tm-soft .indice-menu-list a:focus-visible, html.tm-soft .indice-menu-close:hover { transform: none; }
html.tm-soft .indice-fab { transform: translate(-50%, 0); }
html.tm-soft .rail-line { transition: opacity .3s; }
html.js.tm-soft .tjsx-marquee-track { animation: none; }
html.tm-soft .tjsx-marquee-pause { display: none; }
html.tm-soft .hero-scroll span::after { animation: tm-latido 2.6s ease-in-out infinite; top: 0; }
html.tm-soft .tjsx-lantern { display: none; }
html.tm-soft .hero-content, html.tm-soft .tjsx-motes { transform: none !important; }
html.tm-soft .btn::before { transform: none; opacity: 0; transition: opacity .3s ease; }
html.tm-soft .btn:hover::before, html.tm-soft .btn:focus-visible::before { opacity: 1; }
html.tm-soft :is(.btn, .link-tree-btn, .album-card, .para-ti-card, .project-card, .patreon-card, .social-links a, .tjsx-top, .chatbot-toggler):hover { transform: none; }
html.tm-soft .link-tree-btn:hover > i:last-of-type { transform: none; }
html.tm-soft .album-card:hover .album-cover { transform: none; }
html.tm-soft .visitas-numero.is-bump { animation-name: tm-bump-soft; }
@keyframes tm-bump-soft { 35% { color: var(--gold-up, #c4a568); } }

/* Animación completa elegida en un equipo que pide menos movimiento: vuelven las transiciones
   que las páginas apagan por preferencia del sistema */
html.tm-full .project-shot img { transition: transform .5s ease; }
html.tm-full .tjsx-gear svg { transition: transform .5s ease; }
html.tm-full .skip-link { transition: transform .2s ease; }

/* Pulso de los indicadores «en línea» (en la portada depende de la preferencia del sistema;
   aquí sigue el nivel elegido: es un simple cambio de opacidad) */
html.tm-full .dot, html.tm-soft .dot { animation: tm-latido 2.4s ease-in-out infinite; }

/* Sin JavaScript no hay clase de nivel: manda la preferencia del sistema */
@media (prefers-reduced-motion: reduce) {
    html:not(.tm-full):not(.tm-soft) .hero-scroll span::after { animation: none; }
}
