/* =========================================================
   ISMAEL — PORTAFOLIO
   -----------------------------------------------------------
   Dirección de arte: trip-hop de finales de los noventa.
   Portishead, Morcheeba, Hooverphonic. Noir analógico,
   pero leído como sitio de desarrollador.

   1. EL VERDE MANDA. El teal (#74b8a6) lleva la voz: enlaces,
      estados activos, numeración, reglas, botones. El ámbar
      (#d9a463) entra dosificado, solo en categorías y en el
      bloque de resultado. No compiten.

   2. TIPOGRAFÍA DE DEV. JetBrains Mono para todo lo que sea
      dato, etiqueta o cifra. Inter con tracking cerrado para
      los títulos. Sin serif: esto es un portafolio técnico.

   3. GRANO ANALÓGICO. Una capa de ruido SVG sobre el fondo,
      estática, para romper la planitud del color digital.

   4. LOS LOGOTIPOS, EN GRIS. El carrusel del stack es la única
      zona sin color de marca: gris neutro en reposo, blanco al
      pasar el cursor. Veintiún logotipos con su color corporativo
      serían veintiún acentos peleándose con el teal, y el stack
      pasaría de ser un dato a ser el centro de la página. En
      blanco y negro se lee como lo que es: una lista.

   Presupuesto de rendimiento:
   - Cero box-shadow. El relieve se hace con bordes de 1px.
   - Cero backdrop-filter.
   - Un solo @keyframes: la cinta del stack (.stackreel-track).
     Anima transform y nada más, así que vive en el compositor
     sin provocar recálculo de diseño ni repintado. Se detiene
     con el cursor encima, con el foco dentro y con movimiento
     reducido.
   - El resto de lo que se anima son transiciones que dispara una
     interacción o la entrada en pantalla: transform y opacity
     en el revelado y en el relevo del oleaje, y color en los
     :hover. Son cambios de una sola vez, no movimiento
     continuo, así que su repintado se paga una vez.
   - Dos capas position:fixed: el grano y el lightbox.
   - Todo el movimiento se apaga con prefers-reduced-motion.

   Lo otro que se mueve sin parar es el oleaje de la portada, y
   no está aquí: se repinta en un <canvas> porque su curva es
   una suma de armónicos que hay que recalcular en cada
   fotograma, y eso no cabe en unos keyframes. Está acotado a un
   elemento, se detiene al salir de pantalla y no arranca con
   movimiento reducido. El modelo, en includes/functions.php.
   ========================================================= */

:root {
    /* --- Superficies. Oscuros profundos con temperatura verde. --- */
    --void:        #050908;
    --bg:          #0a0f0e;
    --bg-raised:   #0d1413;
    --bg-panel:    #111a18;
    --bg-panel-hi: #16211f;

    /* --- Líneas --- */
    --line:        #1c2926;
    --line-strong: #2a3b37;

    /* --- Verde teal: la voz principal --- */
    --teal:        #74b8a6;
    --teal-soft:   #5b9c8c;
    --teal-deep:   #3f6f66;
    --teal-wash:   rgba(116, 184, 166, 0.09);

    /* --- Ámbar: acento de apoyo, dosificado --- */
    --amber:       #d9a463;
    --amber-soft:  #b0834c;
    --amber-deep:  #7a5c37;
    --amber-wash:  rgba(217, 164, 99, 0.08);

    /* --- Texto --- */
    --text:        #e0e8e5;
    --text-dim:    #93a49f;
    --text-faint:  #5f6f6a;

    /* --- Blanco y gris neutros: solo para el carrusel del stack ---
       Los tres grises de arriba llevan verde dentro. Estos dos no:
       son neutros exactos, porque un logotipo teñido de verde no
       se lee como un logotipo en blanco y negro, se lee como un
       logotipo mal impreso.

       El logotipo va en blanco y el nombre en gris, un escalón por
       debajo. Si los dos van igual de claros compiten y la cinta se
       lee como una pared; con el nombre más apagado la vista la
       recorre por los símbolos y baja al texto solo para confirmar
       cuál es. Que es justo el orden en que está montado: logotipo
       arriba, nombre debajo, como un pie de foto. */
    --logo:        #ffffff;
    --logo-dim:    #79807e;

    /* --- Tipografía. Fuentes de desarrollador, sin serif. --- */
    --sans:   'Inter', system-ui, -apple-system, sans-serif;
    --mono:   'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

    /* --- Métrica --- */
    --shell:  1240px;
    --gutter: 32px;
    --radius: 2px;

    /* --- Curva de movimiento compartida --- */
    --ease:   cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

html {
    scroll-behavior: smooth;
    scroll-padding-top: 90px;
}

body {
    margin: 0;
    background-color: var(--bg);
    color: var(--text);
    font-family: var(--sans);
    font-size: 16px;
    font-weight: 400;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Grano analógico. Capa única, estática, sin animación.
   Al ser fixed no se repinta al hacer scroll: el compositor
   la mantiene como una textura encima del documento. */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9999;
    pointer-events: none;
    opacity: 0.038;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

a { color: inherit; text-decoration: none; }

img {
    max-width: 100%;
    display: block;
}

p { margin: 0 0 1.2em; }
p:last-child { margin-bottom: 0; }

.shell {
    max-width: var(--shell);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

.shell-narrow {
    max-width: 780px;
    margin: 0 auto;
    padding: 0 var(--gutter);
}

:focus-visible {
    outline: 2px solid var(--teal);
    outline-offset: 3px;
}

::selection {
    background: rgba(116, 184, 166, 0.24);
    color: var(--text);
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 10000;
    padding: 12px 20px;
    background: var(--teal);
    color: var(--void);
    font-family: var(--mono);
    font-size: 12px;
}
.skip-link:focus {
    left: 12px;
    top: 12px;
}

/* Todo el movimiento del sitio se apaga aquí, incluida la ola. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
    }
    .reveal { opacity: 1 !important; transform: none !important; }
}

/* =========================================================
   REVELADO AL ENTRAR EN PANTALLA
   La clase la pone el JS, así que sin JavaScript todo queda
   visible. Solo opacity y transform: nada que provoque
   recálculo de diseño.
   ========================================================= */

.reveal {
    opacity: 0;
    transform: translate3d(0, 14px, 0);
    transition: opacity .6s var(--ease), transform .6s var(--ease);
}

.reveal.is-in {
    opacity: 1;
    transform: translate3d(0, 0, 0);
}

/* Escalonado por posición: las filas del índice y las tarjetas
   entran en cascada corta en lugar de todas de golpe. */
.reveal-stagger > * {
    opacity: 0;
    transform: translate3d(0, 16px, 0);
    transition: opacity .55s var(--ease), transform .55s var(--ease);
}
.reveal-stagger.is-in > * {
    opacity: 1;
    transform: translate3d(0, 0, 0);
}
.reveal-stagger.is-in > *:nth-child(1) { transition-delay: 0ms; }
.reveal-stagger.is-in > *:nth-child(2) { transition-delay: 55ms; }
.reveal-stagger.is-in > *:nth-child(3) { transition-delay: 110ms; }
.reveal-stagger.is-in > *:nth-child(4) { transition-delay: 165ms; }
.reveal-stagger.is-in > *:nth-child(5) { transition-delay: 205ms; }
.reveal-stagger.is-in > *:nth-child(6) { transition-delay: 240ms; }
.reveal-stagger.is-in > *:nth-child(7) { transition-delay: 270ms; }
.reveal-stagger.is-in > *:nth-child(8) { transition-delay: 295ms; }
/* a partir de la novena entran juntas: alargar más la cascada
   se percibe como lentitud, no como elegancia */
.reveal-stagger.is-in > *:nth-child(n+9) { transition-delay: 315ms; }

/* =========================================================
   TIPOGRAFÍA COMPARTIDA
   ========================================================= */

/* Etiqueta mono en versalitas. El acento retro-técnico. */
.micro {
    display: block;
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-faint);
}

.micro-amber { color: var(--amber-soft); }
.micro-teal  { color: var(--teal); }

/* Numeración de índice. Se lee como pista de disco. */
.ordinal {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    color: var(--teal-deep);
    font-variant-numeric: tabular-nums;
}

/* La declaración, en mono como los títulos. */
.statement {
    font-family: var(--mono);
    font-weight: 600;
    font-size: clamp(18px, 2.1vw, 26px);
    line-height: 1.5;
    letter-spacing: -0.03em;
    color: var(--text);
    margin: 0;
}

.statement em {
    font-style: normal;
    color: var(--teal);
}

/* Cuerpo de lectura para las fichas */
.prose {
    font-size: 17px;
    line-height: 1.78;
    color: var(--text-dim);
}
.prose p { margin: 0 0 1.4em; }
.prose strong { color: var(--text); font-weight: 500; }
.prose a {
    color: var(--teal);
    border-bottom: 1px solid var(--teal-deep);
    transition: border-color .2s var(--ease);
}
.prose a:hover { border-color: var(--teal); }
.prose ul, .prose ol { padding-left: 22px; margin: 0 0 1.4em; }
.prose li { margin-bottom: 0.5em; }
.prose h2, .prose h3 {
    font-family: var(--sans);
    font-weight: 500;
    color: var(--text);
    letter-spacing: -0.015em;
    margin: 2em 0 0.7em;
}
.prose h2 { font-size: 21px; }
.prose h3 { font-size: 17px; }

/* =========================================================
   CABECERA
   ========================================================= */

.masthead {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}

.masthead-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 28px;
    height: 89px;
}

/* Marca en mono, en una sola línea. Como el prompt de una terminal. */
.wordmark {
    font-family: var(--mono);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.17em;
    text-transform: uppercase;
    color: var(--text);
    white-space: nowrap;
    transition: color .2s var(--ease);
}
.wordmark span {
    color: var(--teal);
}
.wordmark:hover { color: var(--teal); }

.nav {
    display: flex;
    gap: 4px;
}
.nav a {
    position: relative;
    padding: 9px 16px;
    font-family: var(--mono);
    font-size: 11.5px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-dim);
    transition: color .2s var(--ease);
}
.nav a:hover { color: var(--text); }

/* El estado activo se marca con una regla ámbar bajo la etiqueta.
   Es el único indicador de posición en el sitio. */
.nav a.is-active {
    color: var(--teal);
}
.nav a.is-active::after {
    content: '';
    position: absolute;
    left: 16px;
    right: 16px;
    bottom: 2px;
    height: 1px;
    background: var(--teal);
}

/* =========================================================
   ENCABEZADO DE PÁGINA
   ========================================================= */

.page-head {
    padding: 92px 0 68px;
    border-bottom: 1px solid var(--line);
    background: var(--bg-raised);
}

.page-head-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: 40px;
}

.page-title {
    font-family: var(--mono);
    font-size: clamp(28px, 3.8vw, 43px);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.035em;
    margin: 18px 0 0;
    color: var(--text);
}

.page-lede {
    max-width: 60ch;
    margin: 26px 0 0;
    font-size: 17.5px;
    line-height: 1.75;
    color: var(--text-dim);
}

.page-count {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-faint);
    white-space: nowrap;
    padding-bottom: 8px;
}

/* =========================================================
   SECCIONES
   ========================================================= */

.band { padding: 88px 0; }
.band-raised {
    background: var(--bg-raised);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}
.band-tight { padding: 64px 0; }

.band-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 28px;
    flex-wrap: wrap;
    margin-bottom: 44px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--line);
}

.band-title {
    font-family: var(--mono);
    font-size: clamp(16px, 1.8vw, 21px);
    font-weight: 600;
    letter-spacing: -0.025em;
    margin: 12px 0 0;
    color: var(--text);
}

.band-link {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--teal);
    display: inline-flex;
    align-items: center;
    gap: 9px;
    transition: gap .25s var(--ease);
}
.band-link:hover { gap: 15px; }

/* Apunte a la derecha del rótulo, donde en otras secciones va el
   enlace al índice. Se limita el ancho para que no se estire hasta
   el borde: pasado ese punto deja de leerse como una nota al
   título y compite con él. */
.band-note {
    max-width: 42ch;
    margin: 0;
    font-size: 14.5px;
    line-height: 1.65;
    color: var(--text-dim);
}

/* =========================================================
   PORTADA
   ========================================================= */

.opening {
    padding: 112px 0 96px;
    border-bottom: 1px solid var(--line);
    /* Luz verde entrando por la izquierda y un rastro cálido muy
       tenue abajo a la derecha. Gradientes estáticos. */
    background:
        radial-gradient(115% 85% at 4% 8%, rgba(116, 184, 166, 0.10), transparent 58%),
        radial-gradient(90% 70% at 96% 100%, rgba(217, 164, 99, 0.045), transparent 62%),
        linear-gradient(180deg, var(--bg-raised) 0%, var(--bg) 100%);
}

.opening-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
    gap: 64px;
    align-items: stretch;
}

/* Título en mono. Se reduce el cuerpo respecto a una sans porque
   la mono es ~15% más ancha por carácter. */
.opening-statement {
    font-family: var(--mono);
    font-size: clamp(27px, 3.5vw, 45px);
    font-weight: 700;
    line-height: 1.24;
    letter-spacing: -0.035em;
    margin: 24px 0 0;
    color: var(--text);
}
.opening-statement em {
    font-style: normal;
    color: var(--teal);
}

.opening-body {
    max-width: 54ch;
    margin: 32px 0 0;
    font-size: 17.5px;
    line-height: 1.78;
    color: var(--text-dim);
}

.opening-actions {
    display: flex;
    gap: 13px;
    flex-wrap: wrap;
    margin-top: 40px;
}

/* =========================================================
   OLEAJE — columna derecha de la portada

   Dos capas superpuestas que dibujan el mismo oleaje:
   un SVG con el fotograma t=0 y un canvas que lo anima.
   El modelo está en includes/functions.php y el montaje en
   includes/wave.php.

   Aquí no hay ninguna animación del oleaje. No puede haberla:
   la onda es una suma de armónicos que se recalcula en cada
   fotograma, y eso no se expresa con keyframes. El CSS solo
   se ocupa de los bordes y del relevo entre las dos capas.

   Lo único que se anima es la opacity del cruce, que el
   compositor resuelve en GPU.
   ========================================================= */

.opening-aside {
    position: relative;
    align-self: stretch;
    min-height: 430px;

    /* Fundido vertical. El de los costados lo hace un degradado por
       línea, con los cortes desordenados entre ellas.

       Seis paradas y no dos: un fundido lineal se delata porque el
       ojo encuentra el punto donde arranca. Las paradas intermedias
       al 35% y al 40% curvan la rampa y el borde se disuelve sin
       que se pueda señalar dónde empieza. */
    -webkit-mask-image: linear-gradient(180deg,
        transparent 0%,
        rgba(0, 0, 0, 0.35) 7%,
        #000 21%,
        #000 77%,
        rgba(0, 0, 0, 0.40) 92%,
        transparent 100%);
    mask-image: linear-gradient(180deg,
        transparent 0%,
        rgba(0, 0, 0, 0.35) 7%,
        #000 21%,
        #000 77%,
        rgba(0, 0, 0, 0.40) 92%,
        transparent 100%);
}

/* Las dos capas ocupan exactamente el mismo hueco, apiladas. El alto
   lo fija min-height del contenedor, porque los hijos son absolutos y
   no lo empujan. */
.swell-still,
.swell-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
}

.swell-still-line {
    fill: none;
    /* El color, la opacidad y el fundido van en el degradado que trae
       cada trazo desde el SVG. */
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* El canvas nace invisible y el JS marca .is-live en el contenedor
   cuando tiene el primer fotograma pintado. Sin ese relevo se vería
   un hueco en blanco mientras el script arranca.

   El cruce es lento a propósito: las dos capas dibujan el mismo
   instante del oleaje, así que lo que se ve es el dibujo asentándose,
   no un cambio de imagen. */
.swell-canvas {
    opacity: 0;
    transition: opacity 1s var(--ease);
}

.opening-aside.is-live .swell-canvas { opacity: 1; }

.opening-aside.is-live .swell-still {
    opacity: 0;
    transition: opacity 1s var(--ease);
}

/* =========================================================
   BOTONES
   ========================================================= */

.btn {
    display: inline-flex;
    align-items: center;
    gap: 11px;
    padding: 14px 27px;
    font-family: var(--mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: transparent;
    color: var(--text);
    cursor: pointer;
    transition: color .22s var(--ease), border-color .22s var(--ease), background-color .22s var(--ease);
}

.btn-solid {
    background: var(--teal);
    border-color: var(--teal);
    color: var(--void);
}
.btn-solid:hover {
    background: #8bc9b8;
    border-color: #8bc9b8;
}

.btn-line:hover {
    border-color: var(--teal);
    color: var(--teal);
    background: var(--teal-wash);
}

/* =========================================================
   ÍNDICE DE PROYECTOS — filas tipo tracklist
   ========================================================= */

.index-list {
    border-top: 1px solid var(--line);
}

.entry {
    display: grid;
    grid-template-columns: 54px minmax(0, 1fr) minmax(0, 0.85fr) 132px;
    align-items: center;
    gap: 28px;
    padding: 26px 8px;
    border-bottom: 1px solid var(--line);
    transition: background-color .22s var(--ease), padding-left .22s var(--ease);
}
.entry:hover {
    background: var(--bg-panel);
    padding-left: 18px;
}

.entry-ordinal {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    color: var(--teal-deep);
    font-variant-numeric: tabular-nums;
    transition: color .22s var(--ease);
}
.entry:hover .entry-ordinal { color: var(--teal); }

.entry-title {
    font-family: var(--sans);
    font-size: 19px;
    font-weight: 500;
    letter-spacing: -0.015em;
    line-height: 1.34;
    margin: 0;
    color: var(--text);
}

.entry-summary {
    font-size: 14px;
    line-height: 1.6;
    color: var(--text-faint);
    margin: 6px 0 0;
    /* dos líneas como máximo, para que las filas no se desalineen */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Las categorías son el acento ámbar. Es el único sitio del índice
   donde entra el color cálido. */
.entry-category {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--amber-soft);
    transition: color .22s var(--ease);
}
.entry:hover .entry-category { color: var(--amber); }

.entry-action {
    justify-self: end;
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-faint);
    display: inline-flex;
    align-items: center;
    gap: 9px;
    transition: color .22s var(--ease), gap .22s var(--ease);
}
.entry:hover .entry-action {
    color: var(--teal);
    gap: 15px;
}

.entry.is-hidden { display: none; }

/* =========================================================
   TARJETAS DESTACADAS
   ========================================================= */

.feature-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 26px;
}

.feature {
    display: flex;
    flex-direction: column;
    background: var(--bg-panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    transition: transform .28s var(--ease), border-color .28s var(--ease), background-color .28s var(--ease);
}
.feature:hover {
    transform: translateY(-4px);
    border-color: var(--line-warm);
    background: var(--bg-panel-hi);
}

.feature-frame {
    position: relative;
    aspect-ratio: 3 / 2;
    background-color: var(--void);
    /* Patrón diagonal tenue para los proyectos sin imagen.
       Estático, una sola capa. */
    background-image: repeating-linear-gradient(
        128deg,
        rgba(116, 184, 166, 0.05) 0px,
        rgba(116, 184, 166, 0.05) 1px,
        transparent 1px,
        transparent 11px
    );
    display: flex;
    align-items: center;
    justify-content: center;
    border-bottom: 1px solid var(--line);
    overflow: hidden;
}
.feature-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Las capturas de pantalla saturadas romperían la paleta.
       Se atenúan en reposo y recuperan color al enfocar la tarjeta. */
    filter: saturate(0.82) brightness(0.9);
    transition: filter .35s var(--ease), transform .45s var(--ease);
}
.feature:hover .feature-frame img {
    filter: saturate(1) brightness(1);
    transform: scale(1.025);
}

.feature-frame .frame-empty {
    font-family: var(--mono);
    font-size: 10px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--teal-deep);
}

.feature-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 26px 28px 28px;
}

.feature-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 13px;
}

.feature-category {
    font-family: var(--mono);
    font-size: 10px;
    letter-spacing: 0.17em;
    text-transform: uppercase;
    color: var(--amber-soft);
    transition: color .22s var(--ease);
}
.feature:hover .feature-category { color: var(--amber); }

.feature-title {
    font-family: var(--sans);
    font-size: 21px;
    font-weight: 500;
    letter-spacing: -0.02em;
    line-height: 1.3;
    margin: 0 0 13px;
    color: var(--text);
}

.feature-summary {
    font-size: 14.5px;
    line-height: 1.68;
    color: var(--text-dim);
    margin: 0 0 24px;
}

.feature-foot {
    margin-top: auto;
    padding-top: 18px;
    border-top: 1px solid var(--line);
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-faint);
    display: inline-flex;
    align-items: center;
    gap: 9px;
    transition: color .22s var(--ease), gap .22s var(--ease);
}
.feature:hover .feature-foot {
    color: var(--teal);
    gap: 15px;
}

/* =========================================================
   FILTROS
   ========================================================= */

.filterbar {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    margin-bottom: 8px;
}

.filter {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    padding: 9px 16px;
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    background: transparent;
    color: var(--text-dim);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    cursor: pointer;
    transition: color .2s var(--ease), border-color .2s var(--ease), background-color .2s var(--ease);
}
.filter:hover {
    color: var(--text);
    border-color: var(--line-strong);
}
.filter.is-on {
    color: var(--void);
    background: var(--teal);
    border-color: var(--teal);
}

.filter-count {
    font-size: 9.5px;
    opacity: 0.65;
    font-variant-numeric: tabular-nums;
}

.filter-empty {
    padding: 60px 0;
    text-align: center;
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: 0.1em;
    color: var(--text-faint);
}

/* =========================================================
   FICHA DE PROYECTO
   ========================================================= */

.case-head {
    padding: 76px 0 60px;
    border-bottom: 1px solid var(--line);
    background:
        radial-gradient(100% 80% at 6% 0%, rgba(116, 184, 166, 0.07), transparent 60%),
        var(--bg-raised);
}

.crumb {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-faint);
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 28px;
    transition: color .2s var(--ease), gap .22s var(--ease);
}
.crumb:hover { color: var(--teal); gap: 16px; }

.case-title {
    font-family: var(--mono);
    font-size: clamp(24px, 3.1vw, 37px);
    font-weight: 700;
    line-height: 1.24;
    letter-spacing: -0.035em;
    margin: 0;
    max-width: 26ch;
    color: var(--text);
}

.case-summary {
    max-width: 62ch;
    margin: 26px 0 0;
    font-size: 18px;
    line-height: 1.72;
    color: var(--text-dim);
}

/* Ficha técnica en rejilla, con reglas de 1px */
.case-spec {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1px;
    margin-top: 44px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
}
.case-spec-item {
    background: var(--bg-panel);
    padding: 20px 22px 22px;
}
.case-spec-item .micro { margin-bottom: 8px; }
.case-spec-item p {
    margin: 0;
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--text);
}

.case-hero {
    margin: 0;
    background: var(--void);
    border-bottom: 1px solid var(--line);
}
.case-hero img {
    width: 100%;
    max-height: 74vh;
    object-fit: cover;
}

.case-body { padding: 80px 0; }

.case-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2.15fr);
    gap: 64px;
    align-items: start;
}

.case-aside {
    position: sticky;
    top: 118px;
    border-top: 1px solid var(--line-strong);
    padding-top: 22px;
}
.case-aside .micro { margin-bottom: 14px; }

.taglist {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}
.tag {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.07em;
    color: var(--text-dim);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 5px 11px;
}

/* El resultado es el otro acento ámbar: lo que el cliente se lleva. */
.case-outcome {
    margin-top: 34px;
    padding: 24px 26px;
    border-left: 2px solid var(--amber);
    background: var(--amber-wash);
}
.case-outcome .micro { margin-bottom: 10px; color: var(--amber-soft); }
.case-outcome p {
    margin: 0;
    font-family: var(--sans);
    font-size: 16.5px;
    font-weight: 500;
    line-height: 1.62;
    letter-spacing: -0.015em;
    color: var(--text);
}

.case-external {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-top: 30px;
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--teal);
    border-bottom: 1px solid var(--teal-deep);
    padding-bottom: 3px;
    transition: gap .22s var(--ease), border-color .2s var(--ease);
}
.case-external:hover { gap: 16px; border-color: var(--teal); }

/* --- Galería --- */
.gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 22px;
}

.shot {
    margin: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--bg-panel);
}
.shot-btn {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: var(--void);
    cursor: zoom-in;
    overflow: hidden;
}
.shot-btn img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    filter: saturate(0.85) brightness(0.92);
    transition: filter .35s var(--ease), transform .45s var(--ease);
}
.shot-btn:hover img {
    filter: saturate(1) brightness(1);
    transform: scale(1.03);
}
.shot figcaption {
    padding: 13px 16px 15px;
    font-family: var(--mono);
    font-size: 11px;
    line-height: 1.55;
    letter-spacing: 0.04em;
    color: var(--text-faint);
    border-top: 1px solid var(--line);
}

/* --- Navegación anterior / siguiente --- */
.case-nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    background: var(--line);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}
.case-nav-item {
    background: var(--bg-raised);
    padding: 36px 32px;
    transition: background-color .22s var(--ease);
}
.case-nav-item:hover { background: var(--bg-panel-hi); }
.case-nav-item.is-next { text-align: right; }
.case-nav-item .micro { margin-bottom: 11px; }
.case-nav-item p {
    margin: 0;
    font-family: var(--sans);
    font-size: 18px;
    font-weight: 500;
    letter-spacing: -0.015em;
    line-height: 1.36;
    color: var(--text);
    transition: color .22s var(--ease);
}
.case-nav-item:hover p { color: var(--teal); }

/* =========================================================
   LIGHTBOX
   ========================================================= */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 5vh 5vw;
    background: rgba(4, 7, 6, 0.965);
}
.lightbox[open],
.lightbox.is-open { display: flex; }

.lightbox-figure {
    margin: 0;
    max-width: 100%;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    gap: 16px;
    align-items: center;
}
.lightbox-figure img {
    max-width: 100%;
    max-height: 82vh;
    object-fit: contain;
    border: 1px solid var(--line-strong);
}
.lightbox-figure figcaption {
    font-family: var(--mono);
    font-size: 11.5px;
    letter-spacing: 0.08em;
    color: var(--text-dim);
    text-align: center;
    max-width: 70ch;
}

.lightbox-close,
.lightbox-prev,
.lightbox-next {
    position: absolute;
    background: transparent;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    color: var(--text-dim);
    font-family: var(--mono);
    font-size: 13px;
    cursor: pointer;
    padding: 11px 15px;
    transition: color .2s var(--ease), border-color .2s var(--ease);
}
.lightbox-close:hover,
.lightbox-prev:hover,
.lightbox-next:hover {
    color: var(--teal);
    border-color: var(--teal);
}
.lightbox-close { top: 22px; right: 24px; }
.lightbox-prev  { left: 20px;  top: 50%; transform: translateY(-50%); }
.lightbox-next  { right: 20px; top: 50%; transform: translateY(-50%); }

.lightbox-counter {
    position: absolute;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.15em;
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}

body.no-scroll { overflow: hidden; }

/* =========================================================
   PERFIL
   ========================================================= */

.timeline {
    border-top: 1px solid var(--line);
}
.timeline-row {
    display: grid;
    grid-template-columns: 128px minmax(0, 1fr);
    gap: 34px;
    padding: 30px 0;
    border-bottom: 1px solid var(--line);
}
.timeline-year {
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: 0.12em;
    color: var(--amber-soft);
    padding-top: 4px;
    font-variant-numeric: tabular-nums;
}
.timeline-body h3 {
    font-family: var(--sans);
    font-size: 18px;
    font-weight: 500;
    letter-spacing: -0.015em;
    margin: 0 0 9px;
    color: var(--text);
}
.timeline-body p {
    margin: 0;
    font-size: 15px;
    line-height: 1.72;
    color: var(--text-dim);
    max-width: 68ch;
}

.capability-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(272px, 1fr));
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
}
.capability {
    background: var(--bg-panel);
    padding: 30px 28px 32px;
}
.capability .ordinal { display: block; margin-bottom: 16px; }
.capability h3 {
    font-family: var(--sans);
    font-size: 17px;
    font-weight: 500;
    letter-spacing: -0.015em;
    margin: 0 0 11px;
    color: var(--text);
}
.capability p {
    margin: 0;
    font-size: 14.5px;
    line-height: 1.7;
    color: var(--text-dim);
}

.stack-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 36px;
}
.stack-column .micro { margin-bottom: 16px; }
.stack-column ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
.stack-column li {
    padding: 9px 0;
    border-bottom: 1px solid var(--line);
    font-size: 14.5px;
    color: var(--text-dim);
}

/* =========================================================
   CARRUSEL DEL STACK

   La única animación en bucle del CSS. Marcado en
   includes/stack.php, logotipos en includes/tech-icons.php.

   Cómo cierra el bucle
   --------------------
   La cinta lleva dos copias idénticas de la lista y se desplaza
   hasta -50% de su propio ancho. Ese -50% es, exactamente, el
   ancho de una copia: cuando la animación termina, el primer
   elemento de la segunda copia está donde arrancó el primero de
   la primera, así que el reinicio cae sobre un fotograma
   idéntico y no hay salto que ver.

   El -50% es relativo al ancho de la cinta, no a la pantalla, y
   por eso funciona igual con cualquier número de tecnologías:
   añadir o quitar una no obliga a recalcular nada.

   Lo que sí hay que revisar al tocar la lista es la duración,
   porque es fija y la velocidad sale de dividir: si el recorrido
   se alarga y la duración no, la cinta va más deprisa; y si se
   acorta, se arrastra. Ha pasado ya dos veces al cambiar el
   tamaño de los logotipos.

   La regla, para no volver a tropezar:

       duración = ancho de UNA copia / 61

   61 px/s es el ritmo al que se alcanza a leer un nombre sin
   querer perseguirlo. Medido en el navegador con 22 tecnologías y
   los logotipos a 34px: la copia mide 2409px, así que 40s.

   El ancho de una copia no se puede calcular a ojo desde aquí
   —depende de la tipografía y del largo de cada nombre—, hay que
   medirlo: getBoundingClientRect().width sobre .stackreel-list.

   Por qué no hay JavaScript
   -------------------------
   No hace falta clonar nada en el cliente: la segunda copia la
   imprime PHP. Y no hace falta medir nada, porque el recorrido
   se expresa en porcentaje del propio elemento. Un carrusel que
   necesita JavaScript para medirse es un carrusel que se ve
   saltar mientras se mide.

   Coste
   -----
   Se anima transform y solo transform. El compositor promueve la
   cinta a su propia capa y la desplaza sin volver a maquetar ni
   repintar el contenido. Los degradados de los costados son una
   máscara estática: no participan del bucle.
   ========================================================= */

.stackreel {
    position: relative;
    overflow: hidden;

    /* A sangre, sin .shell: la cinta tiene que salirse de la
       caja para que se lea como algo que sigue más allá del
       borde y no como una fila que se acabó. */
    padding: 6px 0;

    /* Seis paradas, igual que en el oleaje. Un fundido de dos
       paradas deja ver dónde arranca, y aquí se notaría más que
       en la ola: lo que se desvanece son formas reconocibles,
       así que el ojo va a buscar el punto exacto en el que un
       logotipo empieza a apagarse. */
    -webkit-mask-image: linear-gradient(90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.35) 4%,
        #000 15%,
        #000 85%,
        rgba(0, 0, 0, 0.35) 96%,
        transparent 100%);
    mask-image: linear-gradient(90deg,
        transparent 0%,
        rgba(0, 0, 0, 0.35) 4%,
        #000 15%,
        #000 85%,
        rgba(0, 0, 0, 0.35) 96%,
        transparent 100%);
}

.stackreel-track {
    display: flex;
    width: max-content;
    animation: stackreel-run 40s linear infinite;
}

/* Se detiene con el cursor encima para poder leerla, y con el
   foco dentro porque quien navega con teclado no tiene cursor
   con el que pararla. */
.stackreel:hover .stackreel-track,
.stackreel:focus-within .stackreel-track {
    animation-play-state: paused;
}

@keyframes stackreel-run {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}

.stackreel-list {
    display: flex;
    /* stretch y no center: así el borde derecho de cada elemento
       llega de arriba abajo de la franja y las separaciones se leen
       como columnas y no como guiones flotando a media altura. */
    align-items: stretch;
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Logotipo arriba, nombre debajo.
   En fila —logotipo y nombre uno al lado del otro— el logotipo no
   puede pasar de la altura de la mayúscula sin descolocar la línea
   de texto, y a ese tamaño varios se vuelven irreconocibles: el
   delfín de MySQL, la maraña de SQL Server o el pingüino se quedan
   en manchas. Apilado, el logotipo ya no tiene que caber en una
   línea y puede ir al doble, que es donde se distingue de qué marca
   se trata. El nombre pasa a hacer de pie de foto. */
.stackreel-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 11px;
    padding: 4px 22px;
    white-space: nowrap;
    text-align: center;

    /* Suelo de ancho para que los nombres cortos no queden en una
       celda estrecha al lado de TYPESCRIPT o JAVASCRIPT. Sin esto
       el ritmo de la cinta va a saltos. */
    min-width: 108px;

    /* Una regla de 1px entre tecnologías, como en el resto del
       sitio. Al ir en el costado derecho de cada elemento, la
       serie no se corta nunca: la última regla de una copia hace
       de separador con la primera de la siguiente. */
    border-right: 1px solid var(--line);
}

.stackreel-logo {
    flex: none;
    width: 34px;
    height: 34px;

    color: var(--logo);
    fill: currentColor;

    /* Blancos, pero no a quemarropa. Sobre un fondo casi negro el
       blanco puro de veintidós siluetas pesa más que los títulos
       de la página. Un punto por debajo siguen leyéndose blancos y
       dejan de competir. El :hover los sube al blanco entero. */
    opacity: 0.9;
    transition: opacity .28s var(--ease);
}

.stackreel-name {
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    line-height: 1;
    color: var(--logo-dim);
    transition: color .28s var(--ease);
}

.stackreel-item:hover .stackreel-logo { opacity: 1; }
.stackreel-item:hover .stackreel-name { color: var(--logo); }

/* El sprite de los <symbol>. Fuera de pantalla pero no con
   display:none: un símbolo dentro de un contenedor oculto no
   siempre se resuelve al referenciarlo con <use>. */
.tech-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
    pointer-events: none;
}

/* El caso de movimiento reducido no está aquí: vive al final del
   archivo, después del bloque adaptativo. Tiene que ganarle a la
   máscara que se redefine a 720px, y entre dos media queries de
   la misma especificidad gana la última. */

/* =========================================================
   CONTACTO
   ========================================================= */

.contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: 64px;
    align-items: start;
}

.channel-list {
    border-top: 1px solid var(--line-strong);
}
.channel {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 24px;
    padding: 22px 4px;
    border-bottom: 1px solid var(--line);
    transition: padding-left .22s var(--ease), background-color .22s var(--ease);
}
.channel:hover {
    padding-left: 14px;
    background: var(--bg-panel);
}
.channel-value {
    font-family: var(--sans);
    font-size: 17px;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--text);
    transition: color .22s var(--ease);
}
.channel:hover .channel-value { color: var(--teal); }

/* =========================================================
   PIE
   ========================================================= */

.footer {
    border-top: 1px solid var(--line);
    background: var(--void);
    padding: 52px 0 46px;
}

.footer-inner {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 34px;
}

.footer-block .micro { margin-bottom: 11px; }
.footer-block p {
    margin: 0;
    font-size: 14.5px;
    color: var(--text-dim);
}

.footer-link {
    font-size: 14.5px;
    color: var(--text-dim);
    border-bottom: 1px solid var(--line-strong);
    padding-bottom: 2px;
    transition: color .2s var(--ease), border-color .2s var(--ease);
}
.footer-link:hover {
    color: var(--teal);
    border-color: var(--teal-deep);
}

/* Punto de estado. Estático, sin pulso. */
.footer-status {
    display: flex;
    align-items: center;
    gap: 9px;
}
.footer-status::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--teal);
    flex: none;
}

.footer-meta {
    display: flex;
    flex-direction: column;
    gap: 9px;
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.footer-meta p { font-size: inherit; color: inherit; }
.footer-meta a { transition: color .2s var(--ease); }
.footer-meta a:hover { color: var(--teal); }

/* =========================================================
   ADAPTATIVO
   ========================================================= */

@media (max-width: 1080px) {
    /* En una columna el oleaje pasa debajo del texto y se achata.
       No hay que ajustar nada más: la geometría del oleaje está en
       fracciones del bloque, no en píxeles, así que se recompone para
       la nueva proporción y los fundidos siguen cayendo justo en los
       bordes. El canvas se redimensiona con un ResizeObserver. */
    .opening-grid { grid-template-columns: 1fr; gap: 44px; }
    .opening-aside {
        min-height: 260px;
        max-height: 300px;
    }
    .case-columns { grid-template-columns: 1fr; gap: 44px; }
    .case-aside { position: static; }
    .contact-grid { grid-template-columns: 1fr; gap: 48px; }
}

@media (max-width: 860px) {
    /* El índice pasa de tabla a bloques apilados */
    .entry {
        grid-template-columns: 40px minmax(0, 1fr);
        gap: 8px 18px;
        padding: 22px 6px;
    }
    .entry-category {
        grid-column: 2;
        order: 3;
    }
    .entry-action { display: none; }
    .entry:hover { padding-left: 6px; }
}

@media (max-width: 720px) {
    :root { --gutter: 20px; }

    /* En una franja tan baja el fundido vertical tiene que apretarse o
       se come casi todo el oleaje. Se conservan las paradas
       intermedias: son ellas las que evitan que se vea el arranque. */
    .opening-aside {
        min-height: 230px;
        max-height: 260px;
        -webkit-mask-image: linear-gradient(180deg,
            transparent 0%,
            rgba(0, 0, 0, 0.4) 4%,
            #000 12%,
            #000 87%,
            rgba(0, 0, 0, 0.45) 96%,
            transparent 100%);
        mask-image: linear-gradient(180deg,
            transparent 0%,
            rgba(0, 0, 0, 0.4) 4%,
            #000 12%,
            #000 87%,
            rgba(0, 0, 0, 0.45) 96%,
            transparent 100%);
    }

    .masthead-inner {
        height: auto;
        padding: 16px 0 14px;
        flex-direction: column;
        align-items: flex-start;
        gap: 14px;
    }
    .nav {
        flex-wrap: wrap;
        gap: 2px;
        margin-left: -16px;
    }
    html { scroll-padding-top: 20px; }
    .masthead { position: static; }

    .opening { padding: 68px 0 62px; }
    .page-head { padding: 60px 0 46px; }
    .page-head-inner { grid-template-columns: 1fr; gap: 20px; align-items: start; }
    .page-count { padding-bottom: 0; }

    .band { padding: 60px 0; }
    .case-body { padding: 54px 0; }
    .case-head { padding: 52px 0 44px; }

    .feature-grid, .gallery { grid-template-columns: 1fr; }

    .case-nav { grid-template-columns: 1fr; }
    .case-nav-item { padding: 26px 22px; }
    .case-nav-item.is-next { text-align: left; }

    .timeline-row { grid-template-columns: 1fr; gap: 10px; }

    /* En pantalla estrecha todo se aprieta, así que la copia se
       acorta y hay que bajar la duración para no perder el ritmo.
       Medido a 390px: copia de 2128px, 34s, 63 px/s. Prácticamente
       el mismo paso que en escritorio, que es lo que se busca: la
       velocidad aparente no debería depender del tamaño de la
       pantalla.

       Los fundidos también se recogen: sobre 390px de ancho, un
       15% por lado se comía un logotipo entero. */
    .stackreel-item { gap: 9px; padding: 4px 14px; min-width: 86px; }
    .stackreel-logo { width: 27px; height: 27px; }
    .stackreel-name { font-size: 9px; letter-spacing: 0.1em; }
    .stackreel-track { animation-duration: 34s; }
    .stackreel {
        -webkit-mask-image: linear-gradient(90deg,
            transparent 0%,
            rgba(0, 0, 0, 0.35) 3%,
            #000 9%,
            #000 91%,
            rgba(0, 0, 0, 0.35) 97%,
            transparent 100%);
        mask-image: linear-gradient(90deg,
            transparent 0%,
            rgba(0, 0, 0, 0.35) 3%,
            #000 9%,
            #000 91%,
            rgba(0, 0, 0, 0.35) 97%,
            transparent 100%);
    }

    .lightbox { padding: 3vh 3vw; }
    .lightbox-prev { left: 8px; }
    .lightbox-next { right: 8px; }
}

/* =========================================================
   MOVIMIENTO REDUCIDO — CARRUSEL DEL STACK

   Va al final del archivo a propósito. El bloque general de
   prefers-reduced-motion está arriba, junto al resto de las
   reglas base, pero este tiene que ir después del bloque
   ADAPTATIVO: a 720px se redefine la máscara de la cinta, y
   entre dos media queries con la misma especificidad gana la
   que aparece más abajo. Puesto arriba, en un teléfono con
   movimiento reducido volverían los fundidos y taparían el
   primer y el último logotipo de una rejilla que ya no se mueve.

   Y no basta con parar la animación. La regla global de arriba
   deja la duración en 0.01ms, lo que lleva la cinta de golpe a
   su fotograma final: parada a -50% del recorrido, con la mitad
   de las tecnologías fuera de la pantalla y sin animación que
   las traiga ni scroll con el que alcanzarlas. Así que la cinta
   deja de ser cinta: se reparte en filas, se descarta la copia
   —que solo existía para cerrar el bucle— y se quitan los
   fundidos.
   ========================================================= */

@media (prefers-reduced-motion: reduce) {
    .stackreel {
        -webkit-mask-image: none;
        mask-image: none;
    }
    .stackreel-track {
        animation: none;
        width: 100%;
        flex-wrap: wrap;
    }
    .stackreel-list {
        flex-wrap: wrap;
        justify-content: center;
        row-gap: 26px;
    }
    .stackreel-list[aria-hidden="true"] { display: none; }
    .stackreel-item {
        padding: 0 20px;
        border-right: 0;
    }
}
