/*
Theme Name: Proyección
Version: 1.0
Author: Héctor Mora
Description: El mismo contenido y la misma navegación que Timeline —portada con destacados, Work con filtros y buscador, ficha con carrusel y metadatos, Info con bio y contacto— con piel de sala de proyección en vez de programa de edición: tipografía de cartel, imagen a sangre, grano de película y animación en todo lo que se mueve.
*/

/* ════════════════════════════════════════════════════════════════════════
   QUÉ ES
   Usa las plantillas de Timeline SIN tocar (themes/base/): las páginas, los
   bloques, los textos y los enlaces son exactamente los mismos. Cambia solo
   la forma. Lo que hacía que Timeline pareciera un programa —cuadrícula de
   fondo, regla de timecode, menú en pastillas, paneles con borde, etiquetas
   en cajitas, letra de máquina por todas partes— se sustituye por un
   lenguaje de cartel de cine: titulares condensados enormes, cursiva de
   serifa para los subtítulos, imagen sin marco y mucho aire.

   El movimiento está en proyeccion.js (GSAP, alojado en vendor/). Sin
   JavaScript, o con «reducir movimiento», la web se ve completa y quieta.

   Tema de carpeta SIN padre: themes/base/base.css carga antes que esta hoja.
   Todo lo que base fija y aquí se quiere distinto se redeclara.
   ════════════════════════════════════════════════════════════════════════ */

:root {
    --bg: #0b0b0a;
    --bg-2: #141413;
    --ink: #eeece6;
    --muted: #8f8c85;
    --line: rgba(238, 236, 230, .12);
    --line-2: rgba(238, 236, 230, .26);
    --rec: #ff3b2f;
    --ok: #3ddc84;

    --display: 'Archivo', 'Inter', system-ui, sans-serif;
    --serif: 'Instrument Serif', Georgia, serif;
    --sans: 'Inter', system-ui, sans-serif;
    --read: 'IBM Plex Sans', 'Inter', system-ui, sans-serif;

    --gutter: clamp(18px, 3.2vw, 56px);
    --ease: cubic-bezier(.76, 0, .24, 1);
    --ease-out: cubic-bezier(.16, 1, .3, 1);
    --header-h: 76px;

    /* Alias que usan los estilos en línea de las plantillas compartidas */
    --accent: var(--ink);
    --border: var(--line);
    --text-muted: var(--muted);
    --text-secondary: var(--muted);
    --bg-panel: var(--bg-2);
    --success: var(--ok);
}

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); }
body {
    margin: 0; min-height: 100vh;
    background: var(--bg); color: var(--ink);
    font-family: var(--sans); font-size: 16px; line-height: 1.6;
    -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
    overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img, video, iframe { max-width: 100%; display: block; }
::selection { background: var(--ink); color: var(--bg); }
:focus { outline: none; }
:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }
h1, h2, h3, h4 { color: var(--ink); margin: 0; }
.mono { font-family: var(--sans); }

/* Grano de película: una capa de ruido muy suave sobre todo. Se mueve a
   saltos (como el grano real); con «reducir movimiento» queda quieto. */
body::before {
    content: ''; position: fixed; inset: -50%; z-index: 9990; pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
    opacity: .07;
    animation: pr-grano 1s steps(6) infinite;
}
@keyframes pr-grano {
    0% { transform: translate(0, 0); } 20% { transform: translate(-3%, 2%); } 40% { transform: translate(2%, -3%); }
    60% { transform: translate(-2%, -1%); } 80% { transform: translate(3%, 3%); } 100% { transform: translate(0, 0); }
}

.skip-to-content { position: absolute; left: -9999px; top: 10px; z-index: 10001; background: var(--ink); color: var(--bg); padding: 10px 18px; }
.skip-to-content:focus { left: 16px; }

.container { width: 100%; max-width: 1640px; margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }
.section { padding-top: 0; padding-bottom: clamp(4rem, 10vh, 7rem); }
main { padding-top: var(--header-h); }

/* La regla de timecode y el cabezal eran la parte más «programa». Fuera.
   (El progreso de lectura lo dibuja proyeccion.js como una línea finísima.) */
#timeline-container { display: none !important; }
.pr-progreso { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 1001; background: var(--ink); transform-origin: 0 50%; transform: scaleX(0); pointer-events: none; }

/* ═══ CARGADOR (primera visita): «Plano a plano» (2026-10-27) ═══════════
   El nombre en grande, el timecode corriendo debajo y «Abriendo proyecto» con
   su piloto rojo. La secuencia (seis planos del nombre cada vez más cortos, la
   É que se estira y vuelve, el timecode que entra y el piloto que marca entrada
   y salida del subtítulo) la mueve el script que va justo detrás del cargador
   en header.php; aquí, la composición final y los estados de partida. */
#loader {
    position: fixed; inset: 0; z-index: 20000;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg); overflow: hidden;   /* los planos del nombre desbordan la pantalla: que no cuenten */
    transition: transform .9s var(--ease);
}
body.loaded #loader { display: flex; transform: translateY(-100%); pointer-events: none; }
html.pr-sin-carga #loader { display: none !important; }   /* ya visto: ni un fotograma de timecode (lo decide la cabecera antes de pintar) */
html:not(.pr-js) #loader { display: none; }                 /* sin JavaScript nadie lo retiraría */
.loader-ui { display: flex; flex-direction: column; align-items: center; position: relative; z-index: 2; }
.pr-in-nombre, .pr-in-plano {
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860;
    text-transform: uppercase; letter-spacing: -.02em; line-height: .82;
    color: var(--ink); text-align: center;
}
.pr-in-nombre { font-size: min(15.2vw, 30vh); max-width: calc(100vw - 2 * var(--gutter)); }
.pr-js .pr-in-nombre { opacity: 0; }   /* lo enseña el plano general */
/* Los planos: un clon del nombre que el script coloca en cada corte. El aire
   de arriba y abajo es para la tilde: Safari recorta la tinta que sale de la caja. */
.pr-in-plano { position: absolute; left: 0; top: 0; z-index: 1; padding: .4em 0; white-space: nowrap; pointer-events: none; }
.pr-in-plano > div { display: block; }
/* El timecode entra subiendo desde su máscara cuando el nombre ya está formado */
.pr-in-tcm { margin-top: clamp(18px, 3.4vh, 36px); overflow: hidden; padding: .06em .12em; }
.pr-in-tc {
    font-family: var(--display); font-variation-settings: 'wdth' 70, 'wght' 300;
    font-size: clamp(1.7rem, 3.3vw, 3.1rem); line-height: 1; letter-spacing: .01em;
    font-variant-numeric: tabular-nums; color: var(--ink);
}
.pr-js .pr-in-tc { opacity: 0; }
.pr-js .pr-in-dot { opacity: 0; }   /* el piloto se enciende al final */
.pr-in-sub {
    position: relative; margin-top: 16px; display: flex; align-items: center;
    font-family: var(--sans); font-size: .7rem; line-height: 1.2; letter-spacing: .3em; text-transform: uppercase;
    color: var(--muted);
}
.pr-in-dot {
    flex: none; width: 9px; height: 9px; margin-right: 10px; border-radius: 50%;
    background: var(--rec); color: var(--rec); box-shadow: 0 0 6px -1px currentColor;
    animation: pr-parpadeo 1s steps(1) infinite;
}
@keyframes pr-parpadeo { 50% { opacity: 0; } }
/* El texto lo destapa la marca de salida: la tapa es del color del fondo */
.pr-in-txt { position: relative; display: block; overflow: hidden; padding: .5em 0; margin: -.5em 0; }
.pr-in-tapa { position: absolute; inset: 0; background: var(--bg); }
.pr-in-out, .pr-in-banda { position: absolute; top: 50%; left: 0; pointer-events: none; opacity: 0; }
.pr-in-out { width: 2px; height: 1.9em; margin-top: -.95em; background: var(--rec); color: var(--rec); box-shadow: 0 0 6px -1px currentColor; }
.pr-in-banda { height: 1.9em; margin-top: -.95em; background: rgba(255, 59, 47, .2); transform-origin: 0 50%; }
@media (max-width: 640px) {
    .pr-in-nombre { font-size: 27vw; line-height: .84; }
    .pr-in-tc { font-size: 1.9rem; }
}

/* ═══ CABECERA ═══════════════════════════════════════════════════════════
   Transparente sobre la imagen; al bajar se vuelve sólida y se esconde,
   y reaparece al subir (proyeccion.js). */
header {
    position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
    height: var(--header-h);
    display: flex; align-items: center; justify-content: space-between; gap: 24px;
    padding: 0 var(--gutter);
    background: transparent;
    transition: background-color .5s var(--ease-out), transform .6s var(--ease), border-color .5s;
    border-bottom: 1px solid transparent;
}
header.pr-solido { background: rgba(11, 11, 10, .82); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); border-bottom-color: var(--line); }
header.pr-oculto { transform: translateY(-101%); }
.logo a { display: flex; align-items: center; gap: 12px; }
.logo img { height: 30px; width: auto; max-width: 120px; object-fit: contain; border-radius: 0; }
.logo-text {
    font-family: var(--display); font-variation-settings: 'wdth' 82, 'wght' 750;
    text-transform: uppercase; font-size: .98rem; letter-spacing: .02em; white-space: nowrap;
}
.logo-role { font-size: .64rem; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
nav.desktop-nav ul { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 38px); list-style: none; margin: 0; padding: 0; background: none; border: 0; }
nav.desktop-nav a {
    position: relative; display: inline-flex; align-items: center; gap: 8px;
    padding: 6px 0; background: none !important; border: 0 !important; border-radius: 0; box-shadow: none !important;
    font-size: .72rem; font-weight: 500; letter-spacing: .18em; text-transform: uppercase;
    color: var(--muted) !important;
    transition: color .3s;
}
nav.desktop-nav a i { display: none; }
nav.desktop-nav a::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: currentColor;
    transform: scaleX(0); transform-origin: right; transition: transform .5s var(--ease);
}
nav.desktop-nav a:hover, nav.desktop-nav a.active { color: var(--ink) !important; }
nav.desktop-nav a:hover::after { transform: scaleX(1); transform-origin: left; }
nav.desktop-nav a.active::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--rec); }

.mobile-menu-toggle { display: none; background: none; border: 0; color: var(--ink); font-size: 1.6rem; cursor: pointer; padding: 4px; }
@media (max-width: 1100px) { .logo-role { display: none; } }
@media (max-width: 768px) {
    :root { --header-h: 64px; }
    nav.desktop-nav { display: none; }
    .mobile-menu-toggle { display: inline-flex; }
}

/* Menú móvil: el mismo de Timeline (#mobileNav), a pantalla completa. */
.mobile-nav { display: none; }
@media (max-width: 768px) {
    .mobile-nav, .mobile-nav:not(.open) {
        display: flex; flex-direction: column; justify-content: center; gap: 4px;
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 990;
        padding: 0 var(--gutter) 10vh;
        background: var(--bg);
        clip-path: inset(0 0 100% 0); pointer-events: none;
        transition: clip-path .7s var(--ease);
    }
    .mobile-nav.open { clip-path: inset(0 0 0 0); pointer-events: auto; left: 0; right: 0; }
    .mobile-nav a {
        display: block; padding: 6px 0; border: 0 !important;
        font-family: var(--display); font-variation-settings: 'wdth' 64, 'wght' 820;
        text-transform: uppercase; font-size: 16vw; line-height: .95; color: var(--ink) !important;
    }
    .mobile-nav a i { display: none; }
    .mobile-nav a.active { color: var(--muted) !important; }
}

/* ═══ PORTADA ═══════════════════════════════════════════════════════════
   El titular de Timeline («EDIT / MOTION») a tamaño de cartel, sobre el
   vídeo del primer destacado, que proyeccion.js coloca detrás. */
body.home main > .container.section > div:first-child {
    position: relative; z-index: 1;
    min-height: calc(100svh - var(--header-h));
    display: flex; flex-direction: column; justify-content: flex-end;
    padding: 0 0 clamp(2.5rem, 7vh, 5rem) !important;
    text-align: left !important;
}
body.home main > .container.section > div:first-child h1 {
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860;
    text-transform: uppercase; letter-spacing: -.02em;
    font-size: clamp(4.2rem, 15vw, 17rem) !important; line-height: .82 !important;
    /* Alineación óptica: la E de Archivo (wdth 62 / wght 860) deja .042em de aire
       propio a la izquierda (medido en píxeles), que a este tamaño son 9 px; sin
       compensarlo, la tinta de EDIT quedaba a la derecha del lema y de las
       miniaturas, que empiezan justo en el borde del contenedor. */
    margin: 0 0 0 -.042em;
}
body.home main > .container.section > div:first-child p {
    margin: 22px 0 0 !important;
    font-size: .74rem; letter-spacing: .32em; text-transform: uppercase;
    color: var(--ink) !important; opacity: .75;
}
.pr-hero-media {
    position: absolute; left: 0; right: 0; top: 0; height: 100svh; z-index: 0;
    overflow: hidden; pointer-events: none; background: #000;
}
.pr-hero-media img, .pr-hero-media video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; max-width: none; }
.pr-hero-media video { opacity: 0; transition: opacity 1.2s; }
.pr-hero-media video.corre { opacity: 1; }
.pr-hero-media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(11,11,10,.6) 0%, rgba(11,11,10,.42) 40%, rgba(11,11,10,.62) 72%, var(--bg) 100%); }
body.home main { position: relative; padding-top: 0; }
body.home main > .container.section > div:first-child { padding-top: var(--header-h) !important; }

/* ═══ TARJETAS (portada, Work y relacionados) ══════════════════════════
   Sin caja, sin borde: la imagen manda. Numeradas como un índice. */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: clamp(40px, 6vh, 72px) clamp(16px, 2vw, 32px); counter-reset: pieza; }
.grid.fixed-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* En la portada, la columna central baja: ritmo de revista, no de rejilla */
body.home .grid.fixed-3 .card:nth-child(3n+2) { margin-top: clamp(40px, 9vh, 110px); }
@media (max-width: 1000px) {
    .grid.fixed-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    body.home .grid.fixed-3 .card:nth-child(3n+2) { margin-top: 0; }
    body.home .grid.fixed-3 .card:nth-child(2n) { margin-top: clamp(30px, 7vh, 80px); }
}
@media (max-width: 640px) {
    .grid, .grid.fixed-3 { grid-template-columns: 1fr; }
    body.home .grid.fixed-3 .card:nth-child(n) { margin-top: 0; }
}

.card {
    position: relative; display: flex; flex-direction: column;
    background: none !important; border: 0 !important; border-radius: 0 !important; box-shadow: none !important;
    overflow: visible; cursor: pointer; transform: none !important;
    counter-increment: pieza;
}
.card::after { display: none !important; }
.card-img { position: relative; height: auto !important; aspect-ratio: 16 / 9; overflow: hidden; background: var(--bg-2); border-radius: 0; }   /* 16:9 = el formato de las carátulas: no se recortan por los lados */
.card-img img, .card-video {
    position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 0; max-width: none;
    scale: 1; transition: scale 1.4s var(--ease-out), opacity .6s;
}
.card-img img { opacity: 1 !important; }
.card:hover .card-img img, .card:hover .card-video { scale: 1.06; }
.card-video, .card:hover .card-video { opacity: 0; }   /* el 2.º anula el :hover de base.css */
/* El vídeo se enciende cuando CORRE (proyeccion.js pone .pr-vid en «playing»),
   no al entrar el ratón: mientras carga se queda la portada con el indicador.
   Sin el script del tema, se vuelve al :hover de siempre. */
.card.pr-vid .card-video,
html:not(.pr-motor) .card.has-video:hover .card-video { opacity: 1; }
.card-video-loader { position: absolute; right: 14px; bottom: 14px; width: 18px; height: 18px; border: 1.5px solid rgba(255,255,255,.35); border-top-color: #fff; border-radius: 50%; opacity: 0; transition: opacity .3s; animation: pr-gira .8s linear infinite; z-index: 4; }
.card.is-loading .card-video-loader { opacity: 1; }
@keyframes pr-gira { to { transform: rotate(360deg); } }
.card-img.skeleton::after { display: none; }

.card-body { position: relative; padding: 18px 0 0; }
.card-body::before {
    content: counter(pieza, decimal-leading-zero);
    position: absolute; right: 0; top: 20px;
    font-size: .68rem; letter-spacing: .14em; color: var(--muted); font-variant-numeric: tabular-nums;
}
.tags-wrapper { display: flex; flex-wrap: wrap; gap: 0; margin: 0 0 10px; padding-right: 2.5em; }
.tag {
    padding: 0 !important; margin: 0; background: none !important; border: 0 !important; border-radius: 0 !important;
    font-family: var(--sans) !important; font-size: .66rem !important; font-weight: 500 !important;
    letter-spacing: .16em !important; text-transform: uppercase; color: var(--muted) !important;
}
.tag + .tag::before { content: '/'; margin: 0 .7em; opacity: .5; }
.card-body h3 {
    font-family: var(--display); font-variation-settings: 'wdth' 72, 'wght' 780;
    text-transform: uppercase; font-size: clamp(1.5rem, 2.1vw, 2.15rem); line-height: .95; letter-spacing: -.005em;
    margin: 0;
    background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
    transition: background-size .6s var(--ease);
    display: inline;
}
.card:hover .card-body h3 { background-size: 100% 1px; }
.card-subtitle { margin: 8px 0 0; font-family: var(--serif); font-style: italic; font-size: 1.12rem; line-height: 1.25; color: var(--muted); }
.stagger { opacity: 1; transform: none; }

/* Botón «BROWSE WORKSPACE» y el resto de botones de Timeline */
.btn-full, .btn-outline, .contact-submit, .btn {
    display: inline-flex !important; align-items: center; justify-content: center; gap: 10px;
    width: auto !important; margin: 0;
    padding: 17px 30px; border-radius: 999px;
    font-family: var(--sans); font-size: .72rem; font-weight: 500; letter-spacing: .18em; text-transform: uppercase;
    cursor: pointer; text-decoration: none;
    transition: background-color .4s var(--ease-out), color .4s var(--ease-out), border-color .4s;
}
.btn-full, .contact-submit { background: var(--ink) !important; color: var(--bg) !important; border: 1px solid var(--ink) !important; }
.btn-full:hover, .contact-submit:hover { background: transparent !important; color: var(--ink) !important; }
.btn-outline, .btn { background: transparent; color: var(--ink); border: 1px solid var(--line-2); }
.btn-outline:hover, .btn:hover { border-color: var(--ink); background: var(--ink); color: var(--bg); }
body.home main > .container.section > div[style*="margin-top:4rem"] { margin-top: clamp(4rem, 12vh, 8rem) !important; }
body.home main > .container.section > div[style*="margin-top:4rem"] .btn-full { padding: 22px 42px; font-size: .78rem; }

/* ═══ WORK: filtros y buscador ════════════════════════════════════════ */
body.work main > .container.section { padding-top: clamp(3rem, 9vh, 6rem); }
body.work main > .container.section::before {
    content: 'Work'; display: block;
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860;
    text-transform: uppercase; font-size: clamp(4rem, 14vw, 15rem); line-height: .82; letter-spacing: -.02em;
    margin-bottom: clamp(2rem, 6vh, 3.5rem);
}
.filter-bar { display: flex; flex-wrap: wrap; gap: 8px 26px; justify-content: flex-start; margin: 0 0 22px; padding: 0 0 22px; border-bottom: 1px solid var(--line); }
.filter-btn {
    padding: 4px 0; background: none !important; border: 0 !important; border-radius: 0;
    font-family: var(--sans); font-size: .74rem; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
    color: var(--muted); cursor: pointer; position: relative; transition: color .3s;
}
.filter-btn:hover, .filter-btn.active { color: var(--ink) !important; }
.filter-btn.active::after { content: ''; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px; background: var(--ink); }
.filter-count { font-size: .6rem; vertical-align: super; margin-left: 2px; }   /* sin opacity: con .7 el contraste era 3,4:1 (mínimo 4,5) */
.search-bar-container { display: block; max-width: 420px; margin: 0 0 clamp(2.5rem, 7vh, 4.5rem); }
.search-bar { display: flex; align-items: center; gap: 12px; max-width: none; padding: 10px 0; border: 0; border-bottom: 1px solid var(--line-2); border-radius: 0; background: none; box-shadow: none; }
.search-bar:focus-within { border-bottom-color: var(--ink); box-shadow: none; }
.search-bar i:first-child { color: var(--muted); font-size: 1.05rem; margin: 0; }
.search-bar input { flex: 1; border: 0; background: transparent; color: var(--ink); font: inherit; font-size: 1rem; padding: 4px 0; outline: none; }
.search-bar input::placeholder { color: var(--muted); }
.search-bar button { background: none; border: 0; color: var(--muted); cursor: pointer; padding: 2px; display: flex; }
.search-counter { text-align: left; font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); opacity: 1; margin: 12px 0 0; }
.no-results { text-align: left; padding: 3rem 0; color: var(--muted); }
.no-results i { display: none; }
.no-results p { font-family: var(--serif); font-style: italic; font-size: 1.6rem; margin: 0; }

/* ═══ FICHA DE PROYECTO ═════════════════════════════════════════════════ */
body.project main { padding-top: 0; }
.hero-project { position: relative; height: 92svh; min-height: 520px; margin: 0 0 clamp(3rem, 9vh, 6rem); overflow: hidden; border: 0; background: #000; }
.hero-project > img { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; object-fit: cover; opacity: .62; border-radius: 0; -webkit-mask-image: none; mask-image: none; }
.hero-project::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(11,11,10,.5) 0%, transparent 30%, rgba(11,11,10,.25) 60%, var(--bg) 100%); pointer-events: none; }
.hero-project .hero-text {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    max-width: 1640px; margin: 0 auto; padding: 0 var(--gutter) clamp(2.5rem, 7vh, 5rem);
    opacity: 1; transform: none; animation: none;
}
.hero-text h1 {
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860;
    text-transform: uppercase; letter-spacing: -.02em;
    font-size: clamp(3.4rem, 11vw, 12rem); line-height: .82; margin: 16px 0 0;
}
.project-subtitle {
    margin: 18px 0 0; font-family: var(--serif); font-style: italic; font-weight: 400;
    font-size: clamp(1.4rem, 2.8vw, 2.6rem); line-height: 1.05; color: var(--ink) !important; opacity: .9;
}
.hero-text .tags-wrapper { margin: 0; }

.project-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: clamp(32px, 6vw, 110px); align-items: start; }
.project-main { min-width: 0; opacity: 1; transform: none; animation: none; }
@media (max-width: 960px) { .project-layout { grid-template-columns: 1fr; } }

/* Ficha técnica: sin panel, líneas finas y aire */
.project-sidebar {
    position: sticky; top: calc(var(--header-h) + 24px);
    padding: 0; background: none; border: 0; border-radius: 0;
    opacity: 1; transform: none; animation: none;
}
.info-box { display: flex; flex-direction: column; gap: 0; padding: 0; background: none; border: 0; }
.info-header {
    display: flex; justify-content: space-between; padding: 0 0 14px; margin: 0; border-bottom: 1px solid var(--line-2);
    font-family: var(--sans); font-size: .68rem; font-weight: 500; letter-spacing: .2em; text-transform: uppercase; color: var(--muted);
}
.info-item { display: flex; flex-direction: row; justify-content: space-between; align-items: baseline; gap: 16px; padding: 15px 0; border-bottom: 1px solid var(--line); }
.info-item[style*="flex-direction:column"] { align-items: flex-start !important; }
.info-label { font-size: .66rem; font-weight: 500; letter-spacing: .18em; text-transform: uppercase; color: var(--muted); opacity: 1; }
/* Los datos que rellena él (año, cadena, productora): JetBrains Mono, como pidió en Montaje */
.info-val { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: .84rem; font-weight: 400; letter-spacing: .01em; text-align: right; color: var(--ink); }
.role-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.role-badge {
    display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px;
    background: none; border: 1px solid var(--line-2); color: var(--ink);
    font-family: var(--sans); font-size: .72rem; letter-spacing: .06em;
}
.role-badge i { font-size: .9rem; color: var(--muted); }
.project-sidebar .btn-full, .project-sidebar .btn-outline { width: 100% !important; margin-top: 12px !important; }
.project-sidebar .btn-full:first-of-type { margin-top: 26px !important; }
.project-sidebar a[href*="admin.php"] { background: transparent !important; color: var(--muted) !important; border: 1px dashed var(--line-2) !important; }

/* Carrusel de clips: el de Timeline, sin marcos de programa */
.scroll-wrapper { position: relative; display: block; overflow: visible; margin: 0 0 clamp(3rem, 8vh, 5rem); }
.scroll-wrapper > * { width: auto; flex: none; }
.video-scroll { display: flex; gap: clamp(14px, 1.6vw, 24px); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.video-scroll::-webkit-scrollbar { display: none; }
.video-scroll .video-item { flex: 0 0 86%; scroll-snap-align: start; }
.project-main > div:not(.scroll-wrapper):not(.project-content-section):not(.project-gallery):not(.project-embeds) > .video-item:only-child { margin-bottom: clamp(3rem, 8vh, 5rem); }
.video-item { position: relative; background: #000; border-radius: 0; overflow: hidden; }
.video-item video { width: 100%; display: block; border-radius: 0; background: #000; aspect-ratio: 16 / 9; object-fit: contain; }
.video-caption { padding: 12px 0 0; background: var(--bg); font-family: var(--serif); font-style: italic; font-size: 1.05rem; color: var(--muted); opacity: 1; }
.scroll-arrow {
    position: absolute; top: calc(50% - 22px); z-index: 5; transform: translateY(-50%);
    width: 56px; height: 56px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: rgba(11, 11, 10, .55); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    border: 1px solid var(--line-2); color: var(--ink); cursor: pointer; font-size: 1.1rem;
    transition: background-color .3s, color .3s, border-color .3s;
}
.scroll-arrow:hover { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.scroll-prev { left: 14px; } .scroll-next { right: 14px; }

/* Encabezados de sección («ABOUT THIS PROJECT», «GALLERY»…): rótulo fino */
.section-heading {
    display: flex; align-items: center; gap: 14px; margin: clamp(3.5rem, 9vh, 6rem) 0 clamp(1.4rem, 4vh, 2.2rem);
    font-family: var(--sans); font-size: .7rem; font-weight: 500; letter-spacing: .24em; text-transform: uppercase; color: var(--muted);
}
.section-heading i { display: none; }
.section-heading::before { content: ''; width: 34px; height: 1px; background: var(--line-2); }
.project-content-section .section-heading { margin-top: 0; }
.project-content { font-family: var(--read); font-weight: 300; font-size: 1.14rem; line-height: 1.8; text-align: justify; hyphens: auto; color: var(--ink); max-width: 72ch; }
.project-content p { margin: 0 0 1.3em; }
.project-content a { border-bottom: 1px solid var(--line-2); }
.project-content img { border-radius: 0; height: auto; }
.project-quote {
    position: relative; margin: clamp(3rem, 8vh, 5rem) 0; padding: 0 0 0 clamp(28px, 4vw, 64px);
    background: none; border: 0; border-radius: 0;
}
.project-quote::before { content: '“'; position: absolute; left: -6px; top: -.35em; font-family: var(--serif); font-size: clamp(5rem, 9vw, 8rem); line-height: 1; color: var(--muted); opacity: .6; }
.project-quote p { margin: 0; font-family: var(--serif); font-style: italic; font-size: clamp(1.3rem, 1.9vw, 1.7rem); line-height: 1.4; color: var(--ink); }
.project-quote cite { display: block; margin-top: 18px; font-family: var(--sans); font-style: normal; font-size: .68rem; letter-spacing: .2em; text-transform: uppercase; color: var(--muted); opacity: 1; }

.project-gallery { display: flex; flex-wrap: wrap; gap: 14px; }
.project-gallery .gallery-item { flex: 1 1 260px; }   /* las filas incompletas se estiran: nunca queda un hueco al final */
/* Como en Timeline, las fotos se reparten TODO el ancho —una sola foto ocupa
   la columna entera— y se recortan respetando el encuadre arriba/centro/abajo
   del panel (llega como object-position en línea). La primera versión dejaba
   columnas vacías y una foto suelta se veía como una miniatura. */
.gallery-item { margin: 0; aspect-ratio: auto !important; overflow: hidden; border-radius: 0; cursor: zoom-in; background: var(--bg-2); }
.gallery-item img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; max-height: clamp(260px, 30vw, 440px); object-fit: cover; border-radius: 0; scale: 1; transition: scale 1.2s var(--ease-out); }
/* La foto que se queda sola en una fila (o la única) se estira a todo el
   ancho: el tope de altura la convierte en franja recortada en vertical,
   como hacía Timeline, en vez de una imagen gigante. El ancho es 100 %
   explícito, así que el tope no lo encoge (la trampa de aspect-ratio +
   max-height solo muerde con ancho automático). */
.gallery-item:only-child img { aspect-ratio: auto; height: clamp(260px, 30vw, 440px); }
.gallery-item:hover img { scale: 1.06; }
.gallery-item figcaption { display: none; }
.project-embeds { display: flex; flex-direction: column; gap: 32px; }
.embed-item, .embed-video, .embed-social { border-radius: 0; overflow: hidden; }
/* Tuits, Instagram y TikTok tienen ancho máximo propio: centrados en la
   columna, como en Timeline (sin esto, el tuit quedaba pegado a la izquierda). */
.embed-social, .embed-iframe, .social-embed { display: flex; justify-content: center; }
.instagram-media, .twitter-tweet, .tiktok-embed, .twitter-tweet-rendered { margin-left: auto !important; margin-right: auto !important; }
.embed-social blockquote { margin-top: 0 !important; margin-bottom: 0 !important; }
.project-content img { display: block; margin: 2rem auto; max-width: 100%; height: auto; }
.project-content .social-embed, .project-content .embed-container { margin: 2rem 0; }
/* Vídeos de YouTube/Vimeo pegados en la bio o en el texto de una ficha
   (parseSmartEmbeds los envuelve en .embed-container): a todo el ancho y en
   16:9, como en Timeline. Sin esto el iframe salía a su tamaño por defecto
   del navegador, 300×150. */
.embed-container { position: relative; width: 100%; aspect-ratio: 16 / 9; height: auto; margin-bottom: 2rem; overflow: hidden; background: #000; }
.embed-container iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.bio-content .embed-container { border-radius: 14px; }   /* igual que las fotos de la bio */
.embed-video iframe, .embed-iframe iframe { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: 0; }
/* Código <iframe> pegado (p. ej. 3Cat, 500×281): a todo el ancho con SU
   proporción (--ar, calculada en la plantilla desde width/height). Antes se
   estiraba el ancho y se quedaba la altura del atributo: caja larga y bajita
   con el reproductor recortado. */
.embed-iframe iframe { height: auto !important; aspect-ratio: var(--ar, 16 / 9); }
/* Título de cada incrustado, igual que el de los clips */
.embed-block { min-width: 0; }
.embed-caption { padding: 12px 0 0; font-family: var(--serif); font-style: italic; font-size: 1.05rem; color: var(--muted); }

/* Relacionados: título grande */
.project-layout ~ .container.section { padding-top: clamp(5rem, 14vh, 9rem); }
.project-layout ~ .container.section > h3 {
    font-family: var(--display); font-variation-settings: 'wdth' 66, 'wght' 820; text-transform: uppercase;
    font-size: clamp(2.4rem, 6vw, 5.6rem) !important; line-height: .9; letter-spacing: -.015em;
    border-bottom: 0 !important; padding-bottom: 0 !important; margin-bottom: clamp(2rem, 6vh, 3.5rem) !important;
}

/* ═══ INFO ═════════════════════════════════════════════════════════════ */
.bio-wrapper { max-width: 1180px !important; margin: 0 auto !important; padding: clamp(3rem, 10vh, 7rem) 0 0 !important; background: none !important; border: 0 !important; border-radius: 0 !important; box-shadow: none !important; }
.container.section.fade-in-up, .fade-in-up { opacity: 1; transform: none; animation: none; }
.bio-avatar-container { display: flex; justify-content: center; margin: 0 0 30px; }
.bio-avatar { width: clamp(120px, 14vw, 190px); height: clamp(120px, 14vw, 190px); border-radius: 50%; object-fit: cover; border: 0; box-shadow: none; filter: grayscale(.15); }
.bio-header-name {
    text-align: center; margin: 0;
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860; text-transform: uppercase;
    font-size: clamp(3.6rem, 12vw, 12rem); line-height: .82; letter-spacing: -.02em;
}
.bio-header-role { text-align: center; margin: 22px 0 0; font-size: .72rem; letter-spacing: .3em; text-transform: uppercase; color: var(--muted) !important; font-family: var(--sans) !important; }
.bio-social-links { display: flex; justify-content: center; gap: 12px; margin: 22px 0 0; }
.social-link { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--line-2); color: var(--ink); background: none; font-size: 1.05rem; transition: background-color .3s, color .3s; }
.social-link:hover { background: var(--ink); color: var(--bg); }
.bio-content { margin-top: clamp(4rem, 12vh, 8rem) !important; font-family: var(--read); font-weight: 300; font-size: 1.1rem; line-height: 1.8; }
.bio-content strong, .bio-content b { font-weight: 500; }
/* Enlaces de la bio: algo más de peso que el texto (300) para que se vean, además del subrayado */
.bio-content a.bio-link, .bio-content button.email-reveal.bio-link { font-weight: 400 !important; }
.bio-content > div { gap: clamp(28px, 5vw, 80px) !important; margin-bottom: clamp(3rem, 10vh, 6rem) !important; }
.bio-content img { border-radius: 14px !important; }
.bio-content .bio-video video { border-radius: 14px !important; }   /* vídeo de la Media Library, como las fotos */
.bio-content h2, .bio-content h3 {
    font-family: var(--display); font-variation-settings: 'wdth' 70, 'wght' 800; text-transform: uppercase;
    font-size: clamp(1.8rem, 3.6vw, 3.2rem) !important; line-height: .92; letter-spacing: -.01em; color: var(--ink);
}
.bio-content p.mono { font-family: var(--sans) !important; color: var(--muted) !important; font-size: .68rem !important; letter-spacing: .24em !important; text-transform: uppercase; }
.bio-content figcaption { font-family: var(--serif) !important; font-style: italic; text-transform: none !important; letter-spacing: 0 !important; font-size: .98rem !important; color: var(--muted) !important; }
.bio-content hr { border: 0 !important; height: 1px !important; background: var(--line) !important; margin: clamp(3rem, 9vh, 6rem) 0 !important; }
.bio-content blockquote { border: 0 !important; background: none !important; padding: 0 !important; margin: 3rem 0 !important; font-family: var(--serif); font-size: clamp(1.6rem, 3vw, 2.6rem) !important; line-height: 1.2; color: var(--ink) !important; }

.contact-section { margin-top: clamp(5rem, 14vh, 9rem); padding-top: clamp(3rem, 8vh, 5rem); border-top: 1px solid var(--line); }
.contact-title {
    display: block; margin: 0 0 clamp(2rem, 6vh, 3rem);
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860; text-transform: uppercase;
    font-size: clamp(3.4rem, 10vw, 9rem); line-height: .82; letter-spacing: -.02em;
}
.contact-title i { display: none; }
.contact-direct { margin: 0 0 32px !important; }
.contact-form { max-width: 900px; margin: 0; }
.contact-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 32px; }
@media (max-width: 700px) { .contact-row { grid-template-columns: 1fr; } }
.contact-field { padding: 0; margin: 0 0 26px; border: 0; border-radius: 0; background: none; }
.contact-field label { display: block; margin-bottom: 6px; font-size: .66rem; font-weight: 500; letter-spacing: .2em; text-transform: uppercase; color: var(--muted); }
.contact-field input, .contact-field textarea {
    width: 100%; padding: 10px 0; border: 0; border-bottom: 1px solid var(--line-2); border-radius: 0;
    background: transparent; color: var(--ink); font: inherit; font-size: 1.1rem; transition: border-color .3s;
}
.contact-field input:focus, .contact-field textarea:focus { outline: 0; border-bottom-color: var(--ink); }
.contact-field textarea { resize: vertical; min-height: 130px; }
.contact-submit { margin-top: 8px; }
.contact-success, .contact-error { padding: 16px 0; border-radius: 0; background: none; border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2); font-family: var(--serif); font-style: italic; font-size: 1.3rem; }
.contact-privacy { color: var(--muted); opacity: 1; }

/* El correo público (botón de functions.php con estilos en línea) */
.email-reveal { border-color: var(--line-2) !important; color: var(--ink) !important; font-family: var(--sans) !important; letter-spacing: .06em; padding: 12px 20px !important; }
.email-reveal:hover { background: var(--ink) !important; color: var(--bg) !important; }

/* ═══ LEGAL Y 404 ══════════════════════════════════════════════════════ */
.legal-text { max-width: 760px !important; margin: 0 auto !important; padding: clamp(3rem, 10vh, 6rem) 0 0 !important; background: none !important; border: 0 !important; }
.legal-text h1, .legal-text h2 { font-family: var(--display); font-variation-settings: 'wdth' 70, 'wght' 800; text-transform: uppercase; letter-spacing: -.01em; }
.legal-text h1 { font-size: clamp(2.6rem, 7vw, 5.5rem); line-height: .9; margin-bottom: 2rem; }
.legal-text h2 { font-size: 1.4rem; margin: 2.6rem 0 .8rem; }
.legal-text p, .legal-text li { font-family: var(--read); font-weight: 300; color: #c9c6bf; line-height: 1.8; }
body:not(.home):not(.project):not(.work):not(.info):not(.legal):not(.photography) main .container h1 {   /* el titular gigante del 404 */
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860;
    font-size: clamp(6rem, 26vw, 22rem) !important; line-height: .8 !important; letter-spacing: -.02em !important;
}

/* ═══ PIE ═══════════════════════════════════════════════════════════════ */
.site-footer { margin-top: clamp(5rem, 14vh, 9rem); padding: 40px 0 46px; border-top: 1px solid var(--line); background: none; }
/* Tres columnas: copyright a la izquierda, estado CENTRADO en la página y
   privacidad a la derecha. Con «space-between» los huecos medían lo mismo,
   pero como el bloque del copyright es más ancho que el de la privacidad, el
   estado quedaba 111 px a la derecha del centro y el pie se veía torcido.
   Si hay redes sociales, van también en la columna central, encima. */
.footer-content { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 14px 32px; text-align: left; font-size: .8rem; color: var(--muted); }
.footer-content > :first-child { grid-column: 1; grid-row: 1; justify-self: start; }
.footer-content > :last-child { grid-column: 3; grid-row: 1; justify-self: end; text-align: right; }
.footer-content > :not(:first-child):not(:last-child) { grid-column: 2; justify-self: center; }
.footer-content a { transition: color .3s; }
.footer-content a:hover { color: var(--ink) !important; }
.footer-content [style*="JetBrains"] { font-family: var(--sans) !important; color: var(--muted) !important; letter-spacing: .08em; }
.status-indicator { display: inline-flex; align-items: center; gap: 10px; margin: 0; padding: 0; background: none; border: 0; font-family: var(--sans); font-size: .7rem; letter-spacing: .16em; text-transform: uppercase; }
.status-indicator span { color: var(--ink) !important; }
.status-indicator span + span { color: var(--muted) !important; }
/* El piloto del estado: un LED encendido que late. Color fijo con un brillo
   quieto alrededor (la sombra sigue a la opacidad del punto), y el punto
   entero se atenúa y vuelve a encenderse cada 1,6 s. Solo opacidad: no se
   repinta nada. Con «reducir movimiento» se queda encendido y quieto (la
   regla global acorta la animación y, al acabar, vuelve a opacidad 1).
   Se probaron antes un halo que respiraba con un parpadeo cada 7 s («raro,
   no es un color continuo, lento») y un neón/tubo; eligió este latido. */
.status-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; box-shadow: 0 0 6px -1px currentColor; animation: pr-latido 1.6s ease-in-out infinite alternate; }
.status-dot.green { color: var(--ok); }
.status-dot.red { color: var(--rec); }
@keyframes pr-latido { from { opacity: 1; } to { opacity: .35; } }

/* ═══ VISOR Y REEL ═════════════════════════════════════════════════════ */
.lightbox-overlay { position: fixed; inset: 0; z-index: 1500; align-items: center; justify-content: center; background: rgba(8, 8, 7, .96); }
.lightbox-overlay:not(.active) { display: none; }
.lightbox-overlay.active { display: flex; }
.lightbox-content { position: relative; max-width: 88vw; max-height: 84vh; }
.lightbox-img { max-width: 88vw; max-height: 80vh; object-fit: contain; border-radius: 0; }
.lightbox-caption, .lightbox-counter { text-align: center; color: var(--muted); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; margin-top: 14px; }
.lightbox-counter { position: fixed; bottom: 24px; left: 0; right: 0; }
.lightbox-close, .lightbox-nav {
    position: fixed; display: flex; align-items: center; justify-content: center;
    width: 54px; height: 54px; border-radius: 50%; border: 1px solid var(--line-2); cursor: pointer;
    background: rgba(11, 11, 10, .5); color: var(--ink); font-size: 1.3rem; transition: background-color .3s, color .3s;
}
.lightbox-close:hover, .lightbox-nav:hover { background: var(--ink); color: var(--bg); }
.lightbox-close { top: 22px; right: var(--gutter); }
.lightbox-prev { left: var(--gutter); top: 50%; transform: translateY(-50%); }
.lightbox-next { right: var(--gutter); top: 50%; transform: translateY(-50%); }
.reel-container { width: min(92vw, 1400px); aspect-ratio: 16 / 9; }

.share-toast { position: fixed; left: 50%; bottom: 30px; transform: translate(-50%, 20px); background: var(--ink); color: var(--bg); padding: 12px 22px; border-radius: 999px; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; z-index: 10000; opacity: 0; transition: opacity .3s, transform .3s; pointer-events: none; }
.share-toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ═══ TRANSICIONES ENTRE PÁGINAS ═════════════════════════════════════════
   El pie de Timeline marca body.exiting-* al pulsar un enlace interno y
   navega medio segundo después. Aquí esa marca baja un telón; al llegar a
   la página nueva, proyeccion.js lo levanta. */
/* CLAQUETA: el telón lleva escrito adónde vas (título del proyecto, Work,
   Info…) y el de llegada lo conserva mientras se levanta. Se anima con
   clip-path y no con escala, para que el rótulo no se aplaste. */
.pr-telon, .pr-llegada {
    display: grid; place-items: center; text-align: center; padding: 0 var(--gutter);
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860; text-transform: uppercase;
    font-size: clamp(3rem, 11vw, 10rem); line-height: .86; letter-spacing: -.02em; color: var(--ink);
}
.pr-telon { position: fixed; inset: 0; z-index: 9980; background: var(--bg-2); clip-path: inset(100% 0 0 0); pointer-events: none; transition: clip-path .55s var(--ease); }
body.exiting-fade .pr-telon, body.exiting-slide .pr-telon, body.exiting-scale .pr-telon { clip-path: inset(0 0 0 0); }
/* EL CABEZAL (2026-10-18): la raya roja de corte de EDIT / EMOTION recorre el
   nombre del destino de izquierda a derecha, descubriéndolo, y se queda
   aparcada al final; la tapa es del color del telón, así que solo se ve lo que
   va dejando atrás. Empieza cuando el telón ya cubre el nombre (.3 s) y tarda
   .9 s: más que la salida (el pie navega a los 500 ms) más lo que tarda el
   servidor, así que la claqueta de llegada lo continúa desde donde iba (--t, lo
   pasado desde el clic) y el telón no sube hasta que acaba (--sube). Mientras,
   el rótulo se acerca muy despacio para no parecer congelado. Solo transform y
   opacity: Safari deja de ejecutar JS en la página vieja en cuanto empieza a
   cargar la nueva, pero esto lo sigue moviendo la tarjeta gráfica. */
.pr-rotulo { position: relative; display: inline-block; }
.pr-rotulo::after {
    content: ''; position: absolute; top: -.1em; bottom: -.06em; left: -.07em; right: -.5em;
    background: var(--bg-2); border-left: max(3px, .018em) solid var(--rec);
    box-shadow: 0 -.3em 0 var(--bg-2);   /* tapa también los acentos (la Ò de EUFÒRIA asomaba por encima), sin alargar la raya */
}
body[class*="exiting-"] .pr-telon .pr-rotulo { animation: pr-rotulo-zoom 3s linear both; }
body[class*="exiting-"] .pr-telon .pr-rotulo::after { transform: translateX(calc(100% - .43em)); transition: transform .9s cubic-bezier(.45, 0, .55, 1) .3s; }
.pr-llegada .pr-rotulo { animation: pr-rotulo-zoom 3s linear calc(-1 * var(--t, 0ms)) both; }
.pr-llegada .pr-rotulo::after {
    animation: pr-cabezal-recorre .9s cubic-bezier(.45, 0, .55, 1) calc(.3s - var(--t, 0ms)) both,
               pr-cabezal-fuera .3s ease var(--sube, .3s) both;
}
@keyframes pr-rotulo-zoom { from { transform: scale(1); } to { transform: scale(1.08); } }
@keyframes pr-cabezal-recorre { from { transform: none; } to { transform: translateX(calc(100% - .43em)); } }
@keyframes pr-cabezal-fuera { to { border-left-color: transparent; } }
body.exiting-fade main, body.exiting-slide main, body.exiting-scale main { transition: transform .55s var(--ease), opacity .55s; transform: translateY(-40px); opacity: .4; }

/* ═══ CURSOR (solo ratón) ════════════════════════════════════════════════ */
.pr-cursor { display: none; }
@media (hover: hover) and (pointer: fine) {
    html.pr-cursor-on .pr-cursor {
        display: block; position: fixed; left: 0; top: 0; z-index: 9995; width: 0; height: 0;
        pointer-events: none; mix-blend-mode: difference;
    }
    .pr-cursor::before {
        content: ''; position: absolute; left: -44px; top: -44px; width: 88px; height: 88px; border-radius: 50%;
        background: #fff; transform: scale(0); transition: transform .45s var(--ease);
    }
    .pr-cursor b {
        position: absolute; left: -44px; top: -44px; width: 88px; height: 88px; display: grid; place-items: center;
        font: 500 .62rem/1 var(--sans); letter-spacing: .16em; text-transform: uppercase; color: #000;
        opacity: 0; transition: opacity .2s;
    }
    .pr-cursor.grande::before { transform: scale(1); }
    .pr-cursor.grande b { opacity: 1; transition-delay: .1s; }
}
.pr-liquido { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; display: block; }

/* ═══ ESTADOS DE PARTIDA DE LAS ANIMACIONES ═════════════════════════════
   Todo cuelga de html.pr-js (lo pone la cabecera antes de pintar) y se
   anula con html.pr-quieto (reducir movimiento, o el motor no arrancó en
   4 s). Nunca se queda nada escondido esperando a un script. */

/* Titulares que se montan letra a letra / línea a línea (SplitText). Se
   ocultan desde el primer pintado para que no aparezcan y desaparezcan. */
.pr-ln-mask { padding-top: .14em; margin-top: -.14em; padding-bottom: .05em; margin-bottom: -.05em; }
html.pr-js:not(.pr-quieto) :is(
    body.home main > .container.section > div:first-child > h1,
    body.home main > .container.section > div:first-child > p,
    .hero-text h1, .project-subtitle, .bio-header-name, .bio-header-role,
    .contact-title, .project-layout ~ .container.section > h3
):not(.pr-listo) { visibility: hidden; }

/* Tarjetas: la imagen se destapa de abajo arriba y se asienta; el texto
   sube detrás. Lo dispara un IntersectionObserver (clase .pr-visto), así
   también funciona con las tarjetas que vuelven a aparecer al filtrar. */
html.pr-js:not(.pr-quieto) .card .card-img { clip-path: inset(100% 0 0 0); transition: clip-path 1.25s var(--ease) var(--d, 0s); }
html.pr-js:not(.pr-quieto) .card .card-img img { transform: scale(1.32); transition: transform 1.7s var(--ease-out) var(--d, 0s), scale 1.4s var(--ease-out), opacity .6s; }
html.pr-js:not(.pr-quieto) .card .card-body { opacity: 0; transform: translateY(26px); transition: opacity 1s var(--ease-out) calc(var(--d, 0s) + .25s), transform 1.2s var(--ease-out) calc(var(--d, 0s) + .25s); }
html.pr-js .card.pr-visto .card-img { clip-path: inset(0 0 0 0); }
html.pr-js .card.pr-visto .card-img img { transform: scale(1); }
html.pr-js .card.pr-visto .card-body { opacity: 1; transform: none; }

/* Bloques que aparecen al llegar (encabezados, texto, ficha técnica…) */
html.pr-js:not(.pr-quieto) .pr-rev { opacity: 0; transform: translateY(34px); transition: opacity 1s var(--ease-out) var(--d, 0s), transform 1.2s var(--ease-out) var(--d, 0s); }
html.pr-js .pr-rev.pr-visto { opacity: 1; transform: none; }
/* Galería: se recorta la FOTO, no el marco. El marco es lo que vigila el
   IntersectionObserver, y un elemento recortado entero cuenta como invisible:
   nunca «entraba» en pantalla y la foto se quedaba oculta (pasaba en tu web). */
html.pr-js:not(.pr-quieto) .gallery-item.pr-rev { transform: none; transition: opacity .2s var(--d, 0s); }
html.pr-js:not(.pr-quieto) .gallery-item.pr-rev > img { clip-path: inset(0 0 100% 0); transition: clip-path 1.1s var(--ease) var(--d, 0s), scale 1.2s var(--ease-out); }
html.pr-js .gallery-item.pr-rev.pr-visto > img { clip-path: inset(0 0 0 0); }
html.pr-js:not(.pr-quieto) .section-heading.pr-rev::before { transform: scaleX(0); transform-origin: left; transition: transform 1s var(--ease) calc(var(--d, 0s) + .2s); }
html.pr-js .section-heading.pr-rev.pr-visto::before { transform: scaleX(1); }

/* OBTURADOR: la imagen de cabecera de la ficha se abre desde una línea de
   luz central, como un letterbox que se despliega, y se asienta despacio. */
html.pr-js:not(.pr-quieto) .hero-project > img { animation: pr-kb 2.6s var(--ease-out) both; }
@keyframes pr-kb {
    0%   { clip-path: inset(49.6% 0 49.6% 0); scale: 1.16; }
    42%  { clip-path: inset(0 0 0 0); }
    100% { clip-path: inset(0 0 0 0); scale: 1; }
}

/* Telón de entrada al llegar desde otra página (lo baja el de salida) */
.pr-llegada {
    position: fixed; inset: 0; z-index: 9985; background: var(--bg-2);
    animation: pr-telon-sube .85s var(--ease) var(--sube, .3s) both; pointer-events: none;
}
html.pr-quieto .pr-llegada { display: none; }
@keyframes pr-telon-sube { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(0 0 100% 0); } }

/* ═══ MÓVIL ═════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
    .hero-project { height: 78svh; }
    .footer-content { display: flex; flex-direction: column; align-items: flex-start; }
    .footer-content > :last-child { text-align: left; }
    .video-scroll .video-item { flex-basis: 92%; }
    .scroll-arrow { width: 44px; height: 44px; }
    .info-val { text-align: right; }
}

/* ═══ MOVIMIENTO REDUCIDO ═══════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
    body::before { animation: none; }
}

/* PLAY + TIMECODE sobre el vídeo de la tarjeta mientras se reproduce al
   pasar el ratón (proyeccion.js lo crea y lo actualiza a 25 fps). Era «REC»
   con un punto rojo parpadeando, pero el vídeo se está reproduciendo, no
   grabando: ahora es PLAY con el triángulo de reproducir, quieto. */
.pr-tc {
    position: absolute; left: 12px; bottom: 12px; z-index: 4;
    display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px;
    background: rgba(0, 0, 0, .55); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    font: 500 .64rem/1 var(--sans); letter-spacing: .14em; color: #fff; font-variant-numeric: tabular-nums;
    opacity: 0; transform: translateY(6px); transition: opacity .35s, transform .45s var(--ease-out); pointer-events: none;
}
.pr-tc i { width: 0; height: 0; border-style: solid; border-width: 4.5px 0 4.5px 7px; border-color: transparent transparent transparent #fff; }
.card.pr-rodando .pr-tc { opacity: 1; transform: none; }
/* Durante la claqueta no debe flotar el círculo del cursor encima del título */
body.exiting-fade .pr-cursor, body.exiting-slide .pr-cursor, body.exiting-scale .pr-cursor { opacity: 0 !important; transition: opacity .15s; }

/* ═══ GALERÍA COMO HOJA DE CONTACTOS (2026-10-15) ═════════════════════
   Las fotos NO se tocan: son fotogramas de su trabajo, con su color y su
   grafismo. Debajo de cada una va su número de fotograma en ámbar, como el
   rotulado de borde de la película, y a la derecha las iniciales del sitio
   (las pone proyeccion.js en --pr-borde). Al pasar el ratón se dibuja el
   recuadro de lápiz graso rojo con el que se marcan las tomas buenas. */
:root { --edge: #d29a4a; }
.project-gallery { counter-reset: foto; background: #080807; padding: 22px 22px 4px; gap: 10px 16px; }
.project-gallery .gallery-item { position: relative; counter-increment: foto; overflow: visible; background: transparent; padding-bottom: 30px; }
.project-gallery .gallery-item img { outline: 1px solid rgba(238, 236, 230, .08); }
/* Sin el zoom al pasar: el marco ya no recorta (el lápiz sale por fuera),
   así que la foto ampliada se saldría de su sitio. El lápiz es la respuesta. */
.project-gallery .gallery-item:hover img { scale: 1; }
.project-gallery .gallery-item::before,
.project-gallery .gallery-item::after {
    position: absolute; bottom: 9px; white-space: nowrap; pointer-events: none;
    font: 500 .66rem/1 'JetBrains Mono', ui-monospace, monospace; letter-spacing: .14em; color: var(--edge);
}
.project-gallery .gallery-item::before { content: counter(foto) 'A  \25B8'; left: 1px; opacity: .85; }
.project-gallery .gallery-item::after { content: var(--pr-borde, ''); right: 1px; font-size: .62rem; letter-spacing: .18em; opacity: .45; }
.pr-lapiz {
    position: absolute; top: -8px; left: -9px; z-index: 3; pointer-events: none; overflow: visible;
    width: calc(100% + 18px); height: calc(100% - 14px);
    opacity: 0; transition: opacity .2s;
}
.pr-lapiz path { fill: none; stroke: var(--rec); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; transition: stroke-dashoffset .6s cubic-bezier(.45, 0, .25, 1); }
.gallery-item.pr-marcada .pr-lapiz { opacity: .95; transition-duration: .08s; }

/* ═══ VISOR CON PASPARTÚ (2026-10-15) ═════════════════════════════════
   La foto abierta se monta en un marco de papel con cartela: el pie de la
   foto si lo tiene (o el título del proyecto) y su número. Lo activa
   proyeccion.js con .pr-paspartu; sin JS el visor queda como estaba. */
#lightbox.pr-paspartu .lightbox-content {
    max-width: none; max-height: none;
    background: #e8e5de; padding: 30px 30px 76px;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 40px 90px rgba(0, 0, 0, .65);
}
/* El papel nunca llega a las flechas laterales (54 px + margen a cada lado):
   el contenido va por delante en el apilado y las taparía. */
#lightbox.pr-paspartu .lightbox-img { display: block; max-width: calc(100vw - 2 * (var(--gutter) + 70px) - 60px); max-height: calc(84vh - 106px); outline: 1px solid rgba(0, 0, 0, .18); }
#lightbox.pr-paspartu .lightbox-close, #lightbox.pr-paspartu .lightbox-nav { z-index: 2; }
#lightbox.pr-paspartu .lightbox-caption,
#lightbox.pr-paspartu .lightbox-counter { display: none !important; }
.pr-placa { position: absolute; left: 30px; right: 30px; bottom: 26px; display: flex; justify-content: space-between; align-items: baseline; gap: 24px; color: #1b1a17; }
.pr-placa-tit { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: italic 400 1.25rem/1.15 var(--serif); }
.pr-placa-num { flex: none; font: 600 .62rem/1 var(--sans); letter-spacing: .24em; color: #6d6a62; font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
    .project-gallery { padding: 14px 14px 2px; }
    #lightbox.pr-paspartu .lightbox-content { padding: 12px 12px 50px; }
    #lightbox.pr-paspartu .lightbox-img { max-width: calc(100vw - 2 * var(--gutter) - 24px); max-height: calc(78vh - 62px); }
    /* En el móvil no caben a los lados del papel: van abajo, debajo de la foto */
    #lightbox.pr-paspartu .lightbox-nav { top: auto; bottom: calc(22px + env(safe-area-inset-bottom, 0px)); transform: none; width: 48px; height: 48px; }
    .pr-placa { left: 12px; right: 12px; bottom: 17px; gap: 14px; }
    .pr-placa-tit { font-size: 1.02rem; }
}

/* ═══ FOTOGRAFÍA (fotolog, 2026-10-15) ════════════════════════════════
   La maquetación común (el feed) está en assets/photography.css; aquí solo el
   acento de Proyección: el titular y el número de cada foto en la letra de
   los carteles del tema, el título en la cursiva de los pies de clip y la
   fecha y el lugar en versalitas. (Las fotos aparecen con la animación del
   propio feed; por eso .photo-entry no está en la lista de proyeccion.js.) */
.photo-head { margin: clamp(1rem, 4vh, 2.5rem) 0 clamp(3.5rem, 10vh, 6.5rem); }
.photo-head h1 {
    font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860; text-transform: uppercase;
    font-size: clamp(3.6rem, 12vw, 12rem); line-height: .82; letter-spacing: -.02em;
}
.photo-count { margin-top: 22px; font-family: var(--sans); font-size: .72rem; letter-spacing: .3em; color: var(--muted); }
.photo-frame { --photo-fondo: var(--bg-2); }   /* el fondo mientras carga la foto; el marco es el paspartú de assets/photography.css */
.photo-num { font-family: var(--display); font-variation-settings: 'wdth' 62, 'wght' 860; font-weight: 860; color: var(--ink); -webkit-text-stroke: 1.2px var(--ink); opacity: .55; }
.photo-feed.photo-anim .photo-entry.visto .photo-num { opacity: .55; }
.photo-title { font-family: var(--serif); font-style: italic; font-weight: 400; font-size: clamp(1.7rem, 3vw, 2.9rem); line-height: 1.05; color: var(--ink); }
.photo-data { font-family: var(--sans); font-size: .66rem; letter-spacing: .24em; border-top-color: var(--line-2); }
.photo-data dt { color: var(--muted); }
.photo-data dd { color: var(--ink); }
.photo-song-artist, .photo-song-link { color: var(--muted); }
.photo-counter { font-family: var(--sans); color: var(--muted); }
@media (max-width: 860px) {
    .photo-head { text-align: center; }
    .photo-num { font-size: 2.8rem; }
    .photo-title { font-size: 1.6rem; }
}

/* ── EDIT / MOTION ↔ EMOTION (proyeccion.js, «emocion») ─────────────────── */
.pr-emo { position: relative; display: inline-block; white-space: nowrap; }
.pr-slot { position: relative; display: inline-block; clip-path: inset(0 -1em); }   /* recorta solo arriba y abajo */
.pr-bar { display: inline-block; white-space: pre; transform-origin: .138em .399em; }   /* el centro de la «/» */
.pr-e { position: absolute; left: 0; top: 0; white-space: pre; }
/* Los cortes rojos: cada uno centrado en el hueco entre la tinta de la «/» y la
   de la letra de al lado (T a −.088em, «/» de .002 a .274, M a .392), con la
   misma altura que la barra (medido sobre Archivo wdth 62 / wght 860; al ir
   en em siguen al titular a cualquier tamaño). */
.pr-corte {
    --g: max(3px, .018em);
    position: absolute; top: .01em; bottom: .028em; width: var(--g); margin-left: calc(var(--g) / -2);
    background: var(--rec); transform-origin: 50% 0; transform: scaleY(0); pointer-events: none;
}
.pr-c1 { left: -.043em; }
.pr-c2 { left: .33em; }
