/* ============================================================================
   SCANFUN — Design System v2  ·  "Editorial crema"
   ----------------------------------------------------------------------------
   Fuente única de verdad del look público. Reemplaza a app.css en las páginas
   ya migradas (renderHead(['appcss' => false])) — NO se cargan las dos juntas:
   app.css tiene ~60 !important para repintar Tailwind y esa pelea de
   especificidad es justo lo que este archivo viene a terminar.

   Principios:
   1. Papel, no pantalla. Fondo crema (#F7F6F0), no blanco: el blanco puro
      deslumbra y aplana los flyers. La jerarquía la dan el tipo y el aire.
   2. Bordes, no sombras. Una retícula de líneas de 1px sostiene la página;
      las sombras se reservan para lo que de verdad flota (menús, modales).
   3. El dato en mono. Precios, fechas y contadores en Geist Mono con cifras
      tabulares: son columnas, no prosa, y no deben bailar de ancho.
   4. Sin :hover inline. Los estados viven aquí, para poder apretar la CSP.
   5. El :hover no toca el marco. El borde de 1px es la retícula, no un estado:
      recolorearlo al pasar el ratón pone a parpadear la línea que sostiene la
      página y desentona con las que siguen quietas. La señal va al relleno
      (fondo hundido) o al aire (la ficha se levanta con una sombra suave).
      Y siempre dentro de `@media (hover: hover)`: en táctil el navegador
      aplica :hover al tocar y lo deja pegado hasta que tocas otra cosa.
      Excepción: `.sf-link-arrow`, donde el `border-bottom` es el subrayado del
      enlace y no un marco.

   Tipografía:
     display → Rubik (la hermana de Rubik Mono One, la del logotipo)
     sans    → Geist
     mono    → Geist Mono
   ========================================================================== */

/* ===========================================================================
   1. TOKENS
   ========================================================================= */
:root {
    /* --- Papel y tinta ---------------------------------------------------
       Los neutros van desviados a cálido (amarillo-verdoso muy desaturado),
       no a gris puro: es lo que hace que el crema se lea como papel elegido
       y no como un blanco sucio. */
    --sf-bg:        #f7f6f0;
    --sf-bg-2:      #f1efe6;   /* bandas y bloques hundidos */
    --sf-card:      #fffffe;   /* tarjetas: un punto por encima del fondo */
    --sf-ink:       #14140f;
    --sf-ink-2:     #5c5c52;
    --sf-ink-3:     #6d6d62;   /* AA sobre las tres superficies: papel 4.83 · bg-2 4.54 · tarjeta 5.23 */
    --sf-ink-4:     #b4b2a4;

    /* --- Líneas: la retícula que sostiene todo --- */
    --sf-line:      #e4e2d6;
    --sf-line-2:    #cbc8b8;
    --sf-line-3:    #14140f;   /* línea de énfasis: tinta plena */

    /* --- Acento Scanfun ---------------------------------------------------
       Tres valores y no uno, porque sobre crema el morado de marca no sirve
       para todo: #7c5cff es precioso como relleno grande pero no llega a 4.5:1
       para texto pequeño, y con texto blanco encima se queda corto en un botón.
         ac      → rellenos con texto blanco (botones)
         ac-ink  → texto y enlaces sobre crema
         ac-vivo → el morado de marca, para decorar y para fondos oscuros */
    --sf-ac:        #6b46f0;
    --sf-ac-h:      #5a34e0;
    --sf-ac-ink:    #4c2fb8;
    --sf-ac-vivo:   #7c5cff;
    --sf-ac-soft:   #efebff;
    --sf-ac-line:   #d5c9ff;

    /* --- Semánticos (sobre crema) --- */
    --sf-ok:        #047857;
    --sf-ok-soft:   #e7f5ef;
    --sf-warn:      #b45309;
    --sf-warn-soft: #fdf1e3;
    --sf-hot:       #c2185b;   /* urgencia: hoy, últimas entradas */
    --sf-hot-soft:  #fdeaf2;

    /* --- Tipografía --- */
    --sf-display: 'Rubik', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --sf-sans:    'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --sf-mono:    'Geist Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

    --sf-t-hero: clamp(2.6rem, 7vw, 5.5rem);
    --sf-t-h2:   clamp(1.75rem, 3.6vw, 2.6rem);
    --sf-t-h3:   clamp(1.1rem, 1.8vw, 1.3rem);
    --sf-t-lead: clamp(1rem, 1.4vw, 1.15rem);
    --sf-t-body: .9375rem;
    --sf-t-sm:   .8125rem;
    --sf-t-xs:   .6875rem;

    /* --- Geometría --- */
    --sf-r-sm:   8px;
    --sf-r:      14px;      /* el radio de Tickean: suave sin ser cápsula */
    --sf-r-lg:   18px;
    --sf-r-pill: 999px;

    --sf-max:    1200px;
    --sf-gutter: clamp(1.15rem, 4vw, 2.5rem);

    /* Sombras solo para lo que flota de verdad */
    --sf-sh:     0 1px 2px rgba(20,20,15,.04), 0 8px 24px -10px rgba(20,20,15,.14);
    --sf-sh-lg:  0 24px 60px -18px rgba(20,20,15,.26);

    --sf-ease:   cubic-bezier(.22,.61,.36,1);
    --sf-ease-out: cubic-bezier(.23,1,.32,1);   /* entradas: arranca rápido y se posa */
    --sf-fast:   .15s;
    --sf-mid:    .28s;
}

/* ===========================================================================
   2. RESET + BASE
   ========================================================================= */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
    scroll-behavior: smooth;
    scroll-padding-top: 84px;   /* la nav sticky mide 64px */
    -webkit-text-size-adjust: 100%;
}

body.sf-public {
    background: var(--sf-bg);
    color: var(--sf-ink);
    font-family: var(--sf-sans);
    font-size: var(--sf-t-body);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* `overflow-x: hidden` a secas convierte a body en contenedor de scroll y
       mata todo `position: sticky` dentro (ver el bloque que lo explica más
       abajo). Esta regla es más específica que `html, body { ...clip }`, así
       que tiene que llevar el mismo par o pisa el arreglo en toda página
       pública. */
    overflow-x: hidden;
    overflow-x: clip;
    min-height: 100vh;
}

a { color: inherit; text-decoration: none; }
img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
ul, ol { list-style: none; }

:focus-visible {
    outline: 2px solid var(--sf-ac);
    outline-offset: 3px;
    border-radius: var(--sf-r-sm);
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--sf-ac-soft); color: var(--sf-ac-ink); }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--sf-line-2);
    border-radius: var(--sf-r-pill);
    border: 3px solid transparent;
    background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--sf-ink-4); background-clip: content-box; }

.sf-skip {
    position: absolute; left: -9999px; top: 0; z-index: 200;
    background: var(--sf-ink); color: var(--sf-bg);
    padding: .7rem 1.2rem; border-radius: 0 0 var(--sf-r) 0;
    font-weight: 600; font-size: var(--sf-t-sm);
}
.sf-skip:focus { left: 0; }

/* ===========================================================================
   3. TIPOGRAFÍA
   ---------------------------------------------------------------------------
   La display es Rubik, la hermana de la letra del logotipo: Rubik Mono One es
   el miembro monoespaciado de la misma familia. No se eligió por parecerse al
   logotipo, se eligió por ser la misma.

   ⚠️ Rubik NO tiene ejes ópticos. Aquí había `font-variation-settings` con
   'opsz', 'SOFT' y 'WONK' en 19 reglas: son ejes de Fraunces, y una fuente que
   no los tiene los ignora en silencio. No dan error de consola ni cambian
   nada: solo dejan el archivo diciendo algo que no ocurre. Si alguna vez
   vuelve una variable con ejes, se reponen; mientras tanto, fuera.

   ⚠️ Y el peso no se traduce uno a uno. Fraunces 600 es una serif contrastada
   y a tamaño grande pesa mucho más de lo que dice el número, porque el salto
   entre el trazo grueso y el fino hace la mitad del trabajo. Rubik es
   monolineal: a 600 el mismo titular se queda flaco. Titulares a 800,
   encabezados a 700.
   ========================================================================= */
.sf-display {
    font-family: var(--sf-display);
    font-weight: 800;
    letter-spacing: -.025em;
    line-height: 1.02;
    text-wrap: balance;
}
.sf-mono {
    font-family: var(--sf-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}

/* Micro-etiqueta: mono, versal, muy espaciada. Es el recurso que ordena toda
   la página — dice de qué es cada bloque sin gritar. */
.sf-label {
    font-family: var(--sf-mono);
    font-size: var(--sf-t-xs);
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--sf-ink-3);
    display: inline-flex; align-items: center; gap: .45rem;
}
.sf-label .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ===========================================================================
   4. LAYOUT
   ========================================================================= */
.sf-shell { max-width: var(--sf-max); margin-inline: auto; padding-inline: var(--sf-gutter); width: 100%; }
.sf-section { padding-block: clamp(2.75rem, 6vw, 4.5rem); }
.sf-section--tight { padding-block: clamp(1.5rem, 3vw, 2.5rem); }

/* Cabecera de sección: etiqueta + titular, y una línea que cruza hasta el
   borde. La línea es lo que da el aire de publicación impresa. */
.sf-sec-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1.5rem; flex-wrap: wrap;
    padding-bottom: 1.1rem; margin-bottom: 1.75rem;
    border-bottom: 1px solid var(--sf-line-3);
}
.sf-sec-head h2 { font-size: var(--sf-t-h2); margin-top: .55rem; }
.sf-sec-head p  { color: var(--sf-ink-3); font-size: var(--sf-t-sm); margin-top: .5rem; max-width: 46ch; }
.sf-sec-actions { display: flex; align-items: center; gap: .5rem; }

.sf-link-arrow {
    display: inline-flex; align-items: center; gap: .4rem;
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--sf-ink-2); white-space: nowrap;
    border-bottom: 1px solid var(--sf-line-2); padding-bottom: 2px;
    transition: color var(--sf-fast) var(--sf-ease), border-color var(--sf-fast) var(--sf-ease);
}
@media (hover: hover) { .sf-link-arrow:hover { color: var(--sf-ink); border-color: var(--sf-ink); } }

/* ===========================================================================
   5. BOTONES
   ========================================================================= */
.sf-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    padding: .68rem 1.25rem;
    font-family: var(--sf-sans);
    font-size: var(--sf-t-body); font-weight: 500;
    border: 1px solid transparent;
    border-radius: var(--sf-r-sm);
    cursor: pointer; white-space: nowrap;
    transition: background var(--sf-fast) var(--sf-ease),
                border-color var(--sf-fast) var(--sf-ease),
                color var(--sf-fast) var(--sf-ease);
}
.sf-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.sf-btn[disabled], .sf-btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }

.sf-btn--primary { background: var(--sf-ac); color: #fff; font-weight: 600; }
.sf-btn--primary:hover { background: var(--sf-ac-h); }

/* Tinta plena: el botón más serio de la página, para la acción principal
   cuando el morado ya está ocupado decorando. */
.sf-btn--ink { background: var(--sf-ink); color: var(--sf-bg); font-weight: 600; }
.sf-btn--ink:hover { background: #2b2b22; }

.sf-btn--ghost { border-color: var(--sf-line-2); color: var(--sf-ink); }
@media (hover: hover) { .sf-btn--ghost:hover { background: var(--sf-bg-2); } }

.sf-btn--soft { background: var(--sf-ac-soft); color: var(--sf-ac-ink); border-color: var(--sf-ac-line); }
.sf-btn--soft:hover { background: #e5deff; }

.sf-btn--plain { color: var(--sf-ink-2); padding-inline: .7rem; }
.sf-btn--plain:hover { color: var(--sf-ink); background: var(--sf-bg-2); }

.sf-btn--sm { padding: .45rem .85rem; font-size: var(--sf-t-sm); }
.sf-btn--lg { padding: .9rem 1.7rem; font-size: 1rem; }
.sf-btn--pill { border-radius: var(--sf-r-pill); }
.sf-btn--block { width: 100%; }

/* ===========================================================================
   6. PILLS Y CHIPS
   ========================================================================= */
.sf-pill {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .22rem .55rem;
    border-radius: var(--sf-r-sm);
    font-family: var(--sf-mono);
    font-size: var(--sf-t-xs); font-weight: 500;
    letter-spacing: .07em; text-transform: uppercase;
    white-space: nowrap;
    border: 1px solid transparent;
}
.sf-pill--hot   { background: var(--sf-hot); color: #fff; }
.sf-pill--soon  { background: var(--sf-ac-soft); color: var(--sf-ac-ink); border-color: var(--sf-ac-line); }
.sf-pill--free  { background: var(--sf-ok-soft); color: var(--sf-ok); border-color: #bfe3d4; }
.sf-pill--muted { background: var(--sf-bg-2); color: var(--sf-ink-2); border-color: var(--sf-line); }
/* Sobre una imagen hace falta fondo propio: la pill flota sobre el flyer. */
.sf-pill--glass {
    background: rgba(255,255,254,.92); color: var(--sf-ink);
    border-color: rgba(20,20,15,.1);
    backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}

/* Chips de filtro. El activo se marca con tinta plena, no solo con color:
   se distingue aunque no se perciba el matiz. */
.sf-chip {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .5rem .95rem;
    border-radius: var(--sf-r-pill);
    border: 1px solid var(--sf-line-2);
    background: transparent;
    color: var(--sf-ink-2);
    font-size: var(--sf-t-sm); font-weight: 500;
    white-space: nowrap; cursor: pointer;
    transition: all var(--sf-fast) var(--sf-ease);
}
@media (hover: hover) { .sf-chip:hover { background: var(--sf-bg-2); color: var(--sf-ink); } }
.sf-chip[aria-pressed="true"] {
    background: var(--sf-ink); color: var(--sf-bg); border-color: var(--sf-ink); font-weight: 600;
}
.sf-chip[aria-pressed="true"] .sf-chip-count { color: var(--sf-bg); opacity: .6; }
.sf-chip svg { flex-shrink: 0; }
.sf-chip-count {
    font-family: var(--sf-mono); font-size: .7rem;
    color: var(--sf-ink-4); font-variant-numeric: tabular-nums;
}

.sf-chips {
    display: flex; gap: .5rem; align-items: center;
    overflow-x: auto; padding-block: .25rem;
    scrollbar-width: none; -ms-overflow-style: none;
    scroll-snap-type: x proximity;
}
.sf-chips::-webkit-scrollbar { display: none; }
.sf-chips > * { scroll-snap-align: start; flex-shrink: 0; }

/* ===========================================================================
   7. NAVEGACIÓN
   ========================================================================= */
.sf-nav {
    position: sticky; top: 0; z-index: 60;
    background: rgba(247,246,240,.86);
    backdrop-filter: blur(14px) saturate(1.4);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    border-bottom: 1px solid transparent;
    transition: border-color var(--sf-mid) var(--sf-ease);
}
.sf-nav.is-stuck { border-bottom-color: var(--sf-line); }

.sf-nav-in {
    max-width: var(--sf-max); margin-inline: auto;
    padding-inline: var(--sf-gutter);
    height: 64px; display: flex; align-items: center; gap: 2rem;
}
.sf-nav-logo img { width: clamp(104px, 20vw, 126px); height: auto; }

.sf-nav-links { display: flex; align-items: center; gap: 1.6rem; }
.sf-nav-links a {
    position: relative; padding-block: .35rem;
    font-size: var(--sf-t-sm); font-weight: 500; color: var(--sf-ink-2);
    transition: color var(--sf-fast) var(--sf-ease);
}
.sf-nav-links a::after {
    content: ""; position: absolute; left: 0; right: 100%; bottom: 0;
    height: 1.5px; background: var(--sf-ink);
    transition: right var(--sf-mid) var(--sf-ease);
}
.sf-nav-links a:hover { color: var(--sf-ink); }
.sf-nav-links a:hover::after { right: 0; }

.sf-nav-right { margin-left: auto; display: flex; align-items: center; gap: .55rem; }

.sf-nav-search {
    display: flex; align-items: center; gap: .5rem;
    background: var(--sf-card);
    border: 1px solid var(--sf-line-2);
    border-radius: var(--sf-r-pill);
    padding: .42rem .9rem;
    min-width: 210px; color: var(--sf-ink-3);
    transition: border-color var(--sf-fast) var(--sf-ease);
}
.sf-nav-search:focus-within { border-color: var(--sf-ink); }
.sf-nav-search svg { width: 14px; height: 14px; flex-shrink: 0; }
.sf-nav-search input {
    background: none; border: none; outline: none;
    color: var(--sf-ink); font-size: var(--sf-t-sm); width: 100%;
}
.sf-nav-search input::placeholder { color: var(--sf-ink-4); }

.sf-burger { display: none; flex-direction: column; gap: 5px; padding: 8px; }
.sf-burger span {
    display: block; width: 19px; height: 1.6px; border-radius: 2px;
    background: var(--sf-ink); transition: transform var(--sf-mid) var(--sf-ease), opacity var(--sf-fast);
}
.sf-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.6px) rotate(45deg); }
.sf-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.sf-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.6px) rotate(-45deg); }

/* El menú ya no aparece de golpe (display: none → block): se funde y baja
   8px, y los enlaces entran escalonados, 30 ms entre uno y otro. Se oculta con
   visibility y no con display para que la transición pueda ocurrir. Enlaces
   grandes en la display: es un menú de cinco cosas, no una lista de texto. */
.sf-mmenu {
    position: fixed; inset: 64px 0 0 0; z-index: 55;
    display: flex; flex-direction: column;
    background: var(--sf-bg);
    padding: .75rem var(--sf-gutter) max(1.35rem, env(safe-area-inset-bottom));
    overflow-y: auto;
    /* El scroll del panel no arrastra la página de detrás al llegar al final. */
    overscroll-behavior: contain;
    visibility: hidden; opacity: 0; transform: translateY(-8px);
    transition: opacity .22s var(--sf-ease-out), transform .22s var(--sf-ease-out), visibility 0s linear .22s;
}
.sf-mmenu.is-open {
    visibility: visible; opacity: 1; transform: none;
    transition: opacity .22s var(--sf-ease-out), transform .22s var(--sf-ease-out), visibility 0s;
}

/* `:not(.sf-btn)` no es cosmético: sin él, este color ganaba por especificidad
   al del botón (0,1,1 contra 0,1,0) y "Vender entradas" salía en gris tinta
   sobre el morado — 1.2:1, ilegible. */
.sf-mmenu a:not(.sf-btn) {
    display: flex; align-items: center; justify-content: space-between;
    padding: 1rem .1rem; color: var(--sf-ink);
    font-family: var(--sf-display); font-weight: 700; font-size: 1.35rem; letter-spacing: -.01em;
    border-bottom: 1px solid var(--sf-line);
}
.sf-mmenu a:not(.sf-btn)::after {
    content: ""; width: 9px; height: 9px; margin-right: .3rem;
    border-top: 1.8px solid var(--sf-ink-3); border-right: 1.8px solid var(--sf-ink-3);
    transform: rotate(45deg);
}
.sf-mmenu a:not(.sf-btn):last-of-type { border-bottom: none; }
.sf-mmenu .sf-btn { margin-top: .75rem; }
.sf-mmenu > * { opacity: 0; transform: translateY(6px); transition: opacity .25s var(--sf-ease-out), transform .25s var(--sf-ease-out); }
.sf-mmenu.is-open > * { opacity: 1; transform: none; }
.sf-mmenu.is-open > :nth-child(2) { transition-delay: .03s; }
.sf-mmenu.is-open > :nth-child(3) { transition-delay: .06s; }
.sf-mmenu.is-open > :nth-child(4) { transition-delay: .09s; }
.sf-mmenu.is-open > :nth-child(5) { transition-delay: .12s; }
.sf-mmenu.is-open > :nth-child(n+6) { transition-delay: .15s; }
@media (prefers-reduced-motion: reduce) {
    .sf-mmenu, .sf-mmenu > * { transform: none !important; }
}

/* ===========================================================================
   8. HERO
   ---------------------------------------------------------------------------
   Sin foto de fondo: el titular es la portada. Los eventos entran justo
   debajo, en la pasarela — así se ve que hay cartelera sin que ninguna imagen
   compita con el texto ni tape el buscador.
   ========================================================================= */
.sf-hero { padding-block: clamp(2.5rem, 8vw, 5.5rem) clamp(1.5rem, 3vw, 2.5rem); }
/* ⚠️ 13ch estaba medido para Fraunces. Rubik es más ancha por carácter, y la
   unidad ch no lo compensa entero: con 13ch el titular pasaba a tres líneas y
   dejaba "aquí." huérfano en la última, en todas las anchuras de escritorio.
   15ch es el mínimo medido que lo devuelve a dos. */
.sf-hero h1 { font-size: var(--sf-t-hero); max-width: 15ch; margin-block: 1.1rem 1.2rem; }
/* El énfasis del titular va en color, no en cursiva. Con Fraunces era su
   itálica, que tiene carácter; la oblicua de Rubik no lo tiene y quedaría como
   un texto inclinado sin motivo. El morado es el mismo del FUN del logotipo:
   un solo recurso de énfasis en toda la marca en vez de dos. */
.sf-hero h1 em { font-style: normal; color: var(--sf-ac-ink); }
.sf-hero-lead { color: var(--sf-ink-2); font-size: var(--sf-t-lead); line-height: 1.55; max-width: 48ch; }

.sf-hero-search {
    display: flex; align-items: center; gap: .5rem;
    background: var(--sf-card);
    border: 1px solid var(--sf-line-3);
    border-radius: var(--sf-r-pill);
    padding: .4rem .4rem .4rem 1.1rem;
    max-width: 580px; margin-top: 2rem;
    transition: box-shadow var(--sf-mid) var(--sf-ease);
}
.sf-hero-search:focus-within { box-shadow: 0 0 0 4px var(--sf-ac-soft); }
.sf-hero-search > svg { width: 17px; height: 17px; color: var(--sf-ink-3); flex-shrink: 0; }
.sf-hero-search input {
    flex: 1; min-width: 0; background: none; border: none; outline: none;
    color: var(--sf-ink); font-size: 1rem;
}
.sf-hero-search input::placeholder { color: var(--sf-ink-4); }

.sf-hero-quick { display: flex; gap: .5rem; margin-top: 1.1rem; flex-wrap: wrap; }

/* Cifras: separadas por líneas verticales, como una ficha técnica */
.sf-hero-stats { display: flex; gap: 0; margin-top: 2.5rem; flex-wrap: wrap; }
.sf-hero-stat { padding-right: 2rem; margin-right: 2rem; border-right: 1px solid var(--sf-line-2); }
.sf-hero-stat:last-child { border-right: none; margin-right: 0; padding-right: 0; }
.sf-hero-stat .n {
    font-family: var(--sf-mono); font-size: 1.6rem; font-weight: 500;
    font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: -.03em;
}
.sf-hero-stat .l {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    text-transform: uppercase; letter-spacing: .12em;
    color: var(--sf-ink-3); margin-top: .5rem;
}

/* --- Hero compacto en el móvil --------------------------------------------
   En un iPhone el hero ocupaba la pantalla entera y los eventos asomaban
   cortados por el pie: la primera impresión era un titular y un buscador,
   sin un solo cartel. Se aprieta el aire vertical para que la pasarela entre
   en la primera pantalla. */
@media (max-width: 620px) {
    .sf-hero { padding-block: 1.6rem .75rem; }
    .sf-hero h1 { margin-block: .75rem .75rem; }
    .sf-hero-search { margin-top: 1.25rem; }
    /* Los chips de fecha en una sola fila que se desliza: partidos en dos
       líneas se comían otros 60px. */
    .sf-hero-quick--scroll {
        flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
        margin-inline: calc(var(--sf-gutter) * -1);
        padding-inline: var(--sf-gutter);
        margin-top: .9rem;
    }
    .sf-hero-quick--scroll::-webkit-scrollbar { display: none; }
}

/* ===========================================================================
   8b. PASARELA DE EVENTOS
   ---------------------------------------------------------------------------
   Sustituye a la cinta de flyers. La cinta era un marquee: para cerrar el
   bucle duplicaba la lista (con tres eventos se veía el mismo cartel dos veces
   a la vez) y era decorativa (aria-hidden, sin enlaces). La pasarela es un
   scroll con snap: cada tarjeta es la tarjeta de evento de siempre, se
   arrastra con el dedo y landing.js la hace avanzar de una en una.
   ========================================================================= */
.sf-section--pasarela { padding-block: clamp(.75rem, 2vw, 1.5rem) clamp(2rem, 4vw, 3rem); }
.sf-section--pasarela .sf-sec-head { margin-bottom: 1.25rem; }

.sf-pasarela { position: relative; }
.sf-pasarela-track {
    position: relative;   /* offsetLeft de las tarjetas se mide contra el track */
    display: grid; grid-auto-flow: column;
    grid-auto-columns: min(64vw, 280px);
    gap: 1rem;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--sf-gutter);
    padding: .35rem var(--sf-gutter) 1.25rem;
    margin-inline: calc(var(--sf-gutter) * -1);
    scrollbar-width: none;
}
.sf-pasarela-track::-webkit-scrollbar { display: none; }
.sf-pasarela-track:focus-visible { outline: 2px solid var(--sf-ac); outline-offset: -2px; border-radius: var(--sf-r); }
.sf-pasarela-track > * { scroll-snap-align: start; }
@media (min-width: 768px) { .sf-pasarela-track { grid-auto-columns: 272px; gap: 1.25rem; } }

/* Entrada escalonada al cargar: las tarjetas suben una detrás de otra. Solo
   las seis primeras; las demás ya nacen fuera de la pantalla. */
@keyframes sf-pas-in { from { opacity: 0; transform: translateY(18px); } }
.sf-pasarela-track > * { animation: sf-pas-in .7s var(--sf-ease) both; }
.sf-pasarela-track > :nth-child(2) { animation-delay: .07s; }
.sf-pasarela-track > :nth-child(3) { animation-delay: .14s; }
.sf-pasarela-track > :nth-child(4) { animation-delay: .21s; }
.sf-pasarela-track > :nth-child(5) { animation-delay: .28s; }
.sf-pasarela-track > :nth-child(n+6) { animation-delay: .35s; }

/* En el móvil la tarjeta en foco manda y las vecinas se retiran un paso.
   Es lo que convierte un scroll en una pasarela: se ve cuál es "la de ahora"
   y que hay más a la derecha. */
@media (max-width: 767px) {
    .sf-pasarela.is-live .sf-card {
        transition: transform .55s var(--sf-ease), opacity .55s var(--sf-ease), box-shadow .55s var(--sf-ease);
        transform: scale(.93); opacity: .62;
    }
    .sf-pasarela.is-live .sf-card.is-current { transform: none; opacity: 1; box-shadow: var(--sf-sh); }
}

.sf-pasarela-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.sf-pasarela-foot[hidden] { display: none; }
.sf-pasarela-dots { display: flex; align-items: center; flex-wrap: wrap; }
/* El botón es más grande que la barrita que se ve: la zona pulsable no puede
   medir 8px. */
.sf-pas-dot {
    position: relative; width: 20px; height: 28px;
    background: none; border: none; cursor: pointer;
    transition: width .4s var(--sf-ease);
}
.sf-pas-dot::before, .sf-pas-dot::after {
    content: ""; position: absolute; left: 6px; right: 6px; top: 50%;
    height: 6px; margin-top: -3px; border-radius: 999px;
}
.sf-pas-dot::before { background: var(--sf-line-2); }
.sf-pas-dot.is-on { width: 48px; }
/* La barra del punto activo se llena con el tiempo que falta para avanzar */
.sf-pas-dot.is-on::after {
    background: var(--sf-ink);
    transform-origin: left center;
    transform: scaleX(var(--pas-p, 0));
}
.sf-pasarela.is-stopped .sf-pas-dot.is-on::after { transform: none; }

.sf-pasarela-nav { display: flex; gap: .4rem; }
.sf-pasarela-nav .i-play { display: none; }
.sf-pasarela.is-stopped .sf-pasarela-nav .i-pause { display: none; }
.sf-pasarela.is-stopped .sf-pasarela-nav .i-play { display: block; }
@media (pointer: coarse) {
    .sf-pasarela-nav .sf-rail-btn { width: 44px; height: 44px; }
    .sf-pas-dot { height: 44px; }
}

/* --- De la tarjeta al evento ---------------------------------------------
   Transición entre documentos: el flyer tocado (landing.js le pone
   view-transition-name al tocarlo) viaja hasta el cartel de la página del
   evento (.ev-flyer-vt). El resto de la página se funde. */
@view-transition { navigation: auto; }
::view-transition-group(sf-flyer) { animation-duration: .45s; animation-timing-function: var(--sf-ease-out); }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .25s; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }

/* Sin espera de doble toque en las tarjetas: el toque es un clic directo */
.sf-card { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.sf-card:active { transform: scale(.98); transition-duration: .1s; }

/* ===========================================================================
   8d. HERO CON CARTELERA
   ---------------------------------------------------------------------------
   El titular es la portada y la cartelera sale de él: al cargar, landing.js
   lanza cada tarjeta desde el centro del titular hasta su sitio (WAAPI,
   lanzarDesdeTitulo). Aquí viven los estados en reposo: el titular palabra a
   palabra, la pasarela centrada y el fondo que toma el color del flyer activo.

   Curvas: --sf-ease-out para lo que entra, 600ms para el cambio de tarjeta
   (es movimiento de escaparate, no de interfaz: se permite más de 300ms).
   ========================================================================= */
.sf-hero--cartelera {
    position: relative; isolation: isolate; overflow: hidden;
    padding-block: clamp(2rem, 6vw, 4.25rem) clamp(1.75rem, 4vw, 3rem);
    text-align: center;
}
.sf-hero-head { display: flex; flex-direction: column; align-items: center; }
.sf-hero--cartelera .sf-hero-title {
    margin: 1rem auto 0; max-width: 15ch; text-wrap: balance;
    /* Un punto más bajo que el hero de siempre: la tarjeta entera tiene que
       caber debajo en un portátil de 900px de alto. */
    font-size: clamp(2.5rem, 5.4vw, 4.6rem);
}

/* Titular palabra a palabra: suben y se enfocan, 60ms entre una y otra */
@keyframes sf-palabra { from { opacity: 0; transform: translateY(.3em); filter: blur(8px); } }
.sf-hero-title .w { display: inline-block; animation: sf-palabra .8s var(--sf-ease-out) both; }
.sf-hero-title .w:nth-child(2) { animation-delay: .06s; }
.sf-hero-title .w:nth-child(3) { animation-delay: .12s; }
.sf-hero-title .w:nth-child(4) { animation-delay: .18s; }
.sf-hero-title .w:nth-child(5) { animation-delay: .24s; }

/* Fondo: el flyer activo, muy difuminado y bajo un velo crema. Da el
   ambiente del evento sin tapar nada; cambia con un fundido lento. */
.sf-pas-bg { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.sf-pas-bg > * {
    position: absolute; left: -10%; top: -10%; width: 120%; height: 120%;
    object-fit: cover; filter: blur(70px) saturate(1.5);
    opacity: 0; transition: opacity 1.2s var(--sf-ease-out);
}
.sf-pas-bg > .is-on { opacity: .4; }
.sf-pas-bg::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(to bottom, rgba(247,246,240,.78) 0%, rgba(247,246,240,.5) 50%, var(--sf-bg) 100%);
}

/* Pasarela centrada: la activa en medio, las vecinas encogidas a los lados.
   El padding de media pantalla menos media tarjeta deja que la primera y la
   última también puedan quedar en el centro. */
.sf-pasarela--hero { margin-top: clamp(1.25rem, 4vw, 2.5rem); }
.sf-pasarela--hero .sf-pasarela-track {
    --col: min(62vw, 260px);
    grid-auto-columns: var(--col); gap: .9rem;
    margin-inline: 0; scroll-padding-inline: 0;
    padding: 1rem calc(50% - var(--col) / 2) 1.75rem;
}
@media (min-width: 768px) { .sf-pasarela--hero .sf-pasarela-track { --col: 256px; gap: 1.25rem; } }
.sf-pasarela--hero .sf-pasarela-track > * { scroll-snap-align: center; animation: none; text-align: left; }
.sf-pasarela--hero.is-live .sf-card {
    transform: scale(.86); opacity: .55;
    transition: transform .6s var(--sf-ease-out), opacity .6s var(--sf-ease-out), box-shadow .6s var(--sf-ease-out);
}
.sf-pasarela--hero.is-live .sf-card.is-current { transform: none; opacity: 1; box-shadow: var(--sf-sh-lg); }
.sf-pasarela--hero .sf-pasarela-foot { justify-content: center; gap: 1.25rem; padding-inline: var(--sf-gutter); }
.sf-hero-mas { margin-top: 1.25rem; }

/* --- Lupa y buscador plegado ------------------------------------------- */
.sf-nav-lupa {
    display: grid; place-items: center; flex-shrink: 0;
    width: 40px; height: 40px; border-radius: 50%;
    border: 1px solid var(--sf-line-2); background: transparent; color: var(--sf-ink);
    cursor: pointer; transition: background var(--sf-fast) var(--sf-ease), color var(--sf-fast) var(--sf-ease);
}
.sf-nav-lupa svg { width: 18px; height: 18px; }
@media (hover: hover) { .sf-nav-lupa:hover { background: var(--sf-bg-2); } }
.sf-nav-lupa[aria-expanded="true"] { background: var(--sf-ink); color: var(--sf-bg); }
@media (pointer: coarse) { .sf-nav-lupa { width: 44px; height: 44px; } }

/* Fuera del <header> (como el menú móvil): dentro, el backdrop-filter de la
   cabecera lo posicionaría contra ella y no contra la pantalla. */
.sf-buscar {
    position: fixed; top: 64px; left: 0; right: 0; z-index: 57;
    background: rgba(247,246,240,.97);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--sf-line);
    box-shadow: var(--sf-sh);
    opacity: 0; transform: translateY(-8px);
    transition: opacity .2s var(--sf-ease-out), transform .2s var(--sf-ease-out);
}
.sf-buscar.is-open { opacity: 1; transform: none; }
.sf-buscar-in { padding-block: 1rem 1.1rem; }
.sf-buscar .sf-hero-search { margin-top: 0; max-width: 680px; }
.sf-buscar .sf-hero-quick { margin-top: .8rem; }

/* --- Mapa: ciudades a las que llegamos pronto --------------------------
   En morado claro y con un latido lento, no en gris: gris se leía como
   "apagado", y el mensaje es el contrario, que Scanfun está creciendo.
   Pero SECUNDARIAS: un aro pequeño, sin rótulo y con trazo continuo. Con el
   aro punteado y el mismo tamaño que las reales, catorce "pronto" competían
   con las cinco ciudades que de verdad tienen eventos. Forma distinta (aro
   hueco frente a punto lleno) además del color: no se distinguen solo por él. */
.sf-map-pin.is-soon .sf-map-dot { fill: var(--sf-card); stroke: var(--sf-ac-vivo); stroke-width: 2; }
.sf-map-pin.is-soon.is-on .sf-map-dot { fill: var(--sf-ac-vivo); stroke: var(--sf-card); stroke-width: 2.5; }
.sf-map-pin.is-soon .sf-map-pulse { fill: var(--sf-ac-vivo); }
@keyframes sf-map-latido { 0%, 100% { opacity: 0; transform: scale(1); } 50% { opacity: .18; transform: scale(2.2); } }
.sf-map-sec.is-in .sf-map-pin.is-soon:not(.is-on) .sf-map-pulse,
.sf-map-sec:not(.is-armed) .sf-map-pin.is-soon:not(.is-on) .sf-map-pulse {
    animation: sf-map-latido 3.2s ease-in-out infinite;
    animation-delay: calc(var(--i, 0) * .37s);
}
.sf-map-pronto {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: .1rem .8rem;
    margin-top: 1rem; font-size: var(--sf-t-sm);
}
.sf-map-pronto-l {
    display: inline-flex; align-items: center; gap: .4rem;
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .12em; text-transform: uppercase; color: var(--sf-ac-ink);
}
.sf-map-pronto-l .dot, .sf-map-pronto-tag .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--sf-ac-vivo); }
.sf-map-pronto-c {
    background: none; border: none; border-bottom: 1px dashed var(--sf-ac-line);
    padding: .2rem 0; font: inherit; color: var(--sf-ink-2); cursor: pointer;
    transition: color var(--sf-fast) var(--sf-ease);
}
@media (hover: hover) { .sf-map-pronto-c:hover { color: var(--sf-ac-ink); } }
.sf-map-pronto-c[aria-pressed="true"] { color: var(--sf-ac-ink); border-bottom-style: solid; border-bottom-color: var(--sf-ac-ink); }
@media (pointer: coarse) { .sf-map-pronto-c { padding-block: .7rem; } }
.sf-map-panel.sf-map-panel--pronto { background: linear-gradient(160deg, var(--sf-ac-soft), var(--sf-card) 65%); border-color: var(--sf-ac-line); }
.sf-map-pronto-tag {
    display: inline-flex; align-items: center; gap: .4rem; color: var(--sf-ac-ink) !important;
}
.sf-map-pronto-t {
    font-family: var(--sf-display); font-weight: 700; font-size: 1.25rem; letter-spacing: -.01em;
    color: var(--sf-ink); padding: .7rem .35rem 0;
}
.sf-map-panel--pronto p:not(.sf-map-pronto-t) { color: var(--sf-ink-2); padding: .35rem .35rem 0; }
.sf-map-pronto-cta { margin: .9rem .35rem .3rem; }


/* ===========================================================================
   8c. MAPA DE ECUADOR
   ---------------------------------------------------------------------------
   SVG propio (includes/mapa-ecuador.php). Al entrar en pantalla el contorno
   se dibuja, el relleno de puntos aparece y los pines caen uno a uno; luego
   las ciudades se encienden por turnos. Los estados "sin dibujar" cuelgan de
   .is-armed, que solo pone landing.js: sin JS el mapa se ve entero.
   ========================================================================= */
.sf-map-sec {
    background: var(--sf-bg-2);
    border-block: 1px solid var(--sf-line);
    overflow: hidden;
}
.sf-map-in {
    display: grid; gap: 1.75rem;
    grid-template-areas: "head" "art" "side";
}
@media (min-width: 900px) {
    .sf-map-in {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
        grid-template-areas: "head art" "side art";
        grid-template-rows: auto 1fr;
        column-gap: 3.5rem; row-gap: 1.5rem;
        align-items: start;
    }
}
.sf-map-head { grid-area: head; }
.sf-map-art  { grid-area: art; align-self: center; }
.sf-map-side { grid-area: side; }

.sf-map-head h2 { font-size: var(--sf-t-h2); margin-top: .55rem; max-width: 17ch; }
.sf-map-head h2 em { font-style: normal; color: var(--sf-ac-ink); }
.sf-map-lead { color: var(--sf-ink-2); margin-top: .7rem; }
.sf-map-stats { margin-top: 1.5rem; }

.sf-map-list { display: flex; flex-wrap: wrap; gap: .45rem; }
.sf-map-city-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--sf-ac); flex-shrink: 0; }
.sf-map-city-dot.is-past { background: transparent; border: 1.5px solid currentColor; }
.sf-chip[aria-pressed="true"] .sf-map-city-dot:not(.is-past) { background: var(--sf-ac-vivo); }

@keyframes sf-map-panel-in { from { opacity: 0; transform: translateY(8px); } }
.sf-map-panel {
    margin-top: 1.1rem;
    background: var(--sf-card);
    border: 1px solid var(--sf-line);
    border-radius: var(--sf-r);
    padding: .9rem .9rem .75rem;
    animation: sf-map-panel-in .45s var(--sf-ease);
}
.sf-map-panel[hidden] { display: none; }
.sf-map-panel-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    padding: 0 .35rem .7rem; margin-bottom: .35rem;
    border-bottom: 1px solid var(--sf-line);
}
.sf-map-panel-head strong { font-family: var(--sf-display); font-weight: 700; font-size: 1.15rem; letter-spacing: -.01em; }
.sf-map-panel-head span {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .1em; text-transform: uppercase; color: var(--sf-ink-3); white-space: nowrap;
}
.sf-map-panel ul { list-style: none; }
.sf-map-ev {
    display: grid; grid-template-columns: 42px 1fr; gap: .75rem; align-items: center;
    padding: .45rem .35rem; border-radius: var(--sf-r-sm);
    transition: background var(--sf-fast) var(--sf-ease);
}
@media (hover: hover) { .sf-map-ev:hover { background: var(--sf-bg-2); } }
.sf-map-ev-img {
    display: block; width: 42px; aspect-ratio: 3/4; overflow: hidden;
    border-radius: 6px; border: 1px solid var(--sf-line); background: var(--sf-bg-2);
}
.sf-map-ev-img img { width: 100%; height: 100%; object-fit: cover; }
.sf-map-ev-in { display: flex; flex-direction: column; min-width: 0; gap: .1rem; }
.sf-map-ev-in .t { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-map-ev-in .m {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs); color: var(--sf-ink-3);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sf-map-ver { margin: .6rem .35rem .2rem; background: none; cursor: pointer; }

/* --- El dibujo --- */
.sf-map { display: block; width: 100%; height: auto; max-height: 580px; margin-inline: auto; overflow: visible; }
@media (max-width: 899px) { .sf-map { max-height: 430px; } }

/* Tierra en el blanco de las tarjetas sobre la banda hundida: la forma del
   país se lee por contraste de superficie, sin textura. El relleno de puntos
   de antes, sumado a las fronteras, habría sido ruido. Los trazos no escalan
   con el mapa (vector-effect): a 390px el SVG se pinta a ~0,56 y un filete
   de 1 unidad se quedaba en medio píxel. */
.sf-map-land { fill: var(--sf-card); transition: opacity 1.2s var(--sf-ease) .6s; }
.sf-map-prov {
    fill: none; stroke: var(--sf-line); stroke-width: 1; stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
    transition: opacity 1.2s var(--sf-ease) 1s;
}
.sf-map-shore {
    fill: none; stroke: var(--sf-ink); stroke-width: 1.4; stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
    stroke-dasharray: 1; stroke-dashoffset: 0;
    transition: stroke-dashoffset 2.2s cubic-bezier(.65, 0, .35, 1);
}
.sf-map-sec.is-armed:not(.is-in) .sf-map-land,
.sf-map-sec.is-armed:not(.is-in) .sf-map-prov { opacity: 0; }
.sf-map-sec.is-armed:not(.is-in) .sf-map-shore { stroke-dashoffset: 1; }

/* Galápagos: mismo lenguaje que el continente (tierra blanca con costa en
   tinta) dentro de un recuadro de filete, que es como se lee un "fuera de
   escala". El recuadro punteado con manchas grises parecía un hueco. */
.sf-map-inset { fill: var(--sf-bg-2); stroke: var(--sf-line-2); stroke-width: 1; vector-effect: non-scaling-stroke; }
.sf-map-isla { fill: var(--sf-card); stroke: var(--sf-ink); stroke-width: 1; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.sf-map-inset-l { font-family: var(--sf-mono); font-size: 13px; letter-spacing: .14em; fill: var(--sf-ink-3); }
@media (max-width: 899px) { .sf-map-inset-l { font-size: 15px; letter-spacing: .08em; } }

.sf-map-pin { cursor: pointer; outline: none; }
.sf-map-hit { fill: transparent; }
.sf-map-dot, .sf-map-pulse {
    transform-box: fill-box; transform-origin: center;
    transition: transform .6s cubic-bezier(.34, 1.56, .64, 1), opacity .4s var(--sf-ease-out), fill .3s var(--sf-ease);
    transition-delay: calc(1.2s + var(--i, 0) * .07s);
}
.sf-map-dot { fill: var(--sf-ac); stroke: var(--sf-card); stroke-width: 3; }
.sf-map-pin.is-past .sf-map-dot { fill: var(--sf-card); stroke: var(--sf-ink-3); stroke-width: 2.5; }
.sf-map-pulse { fill: var(--sf-ac-vivo); opacity: 0; }
.sf-map-sec.is-armed:not(.is-in) .sf-map-dot,
.sf-map-sec.is-armed:not(.is-in) .sf-map-name { transform: scale(.4); opacity: 0; }
/* Al activarse ya no hay que esperar la caída inicial */
.sf-map-pin.is-on .sf-map-dot { transform: scale(1.3); fill: var(--sf-ac-ink); transition-delay: 0s; }
.sf-map-pin.is-on.is-past .sf-map-dot { fill: var(--sf-card); stroke: var(--sf-ink); }
@keyframes sf-map-pulse { from { opacity: .5; transform: scale(1); } to { opacity: 0; transform: scale(3.4); } }
.sf-map-sec.is-in .sf-map-pin.is-on .sf-map-pulse,
.sf-map-sec:not(.is-armed) .sf-map-pin.is-on .sf-map-pulse { animation: sf-map-pulse 1.8s var(--sf-ease) infinite; }

/* Rótulo directo en cada ciudad con eventos (sfMapaRotulos() decide el lado
   para que no se pisen). Antes solo se veía el de la ciudad seleccionada y el
   resto eran puntos anónimos. Las "pronto" solo lo enseñan al elegirlas.
   El cuerpo va en unidades del SVG: en el móvil el mapa se pinta a ~0,56, así
   que ahí sube a 23 (≈13px en pantalla) — y ese es el que usa sfMapaRotulos()
   para medir, así que cambiarlo aquí sin cambiarlo allí hace que se pisen. */
.sf-map-name {
    font-family: var(--sf-mono); font-size: 17px; font-weight: 500;
    letter-spacing: .06em; text-transform: uppercase;
    fill: var(--sf-ink-2);
    /* Halo del color de la tierra: el nombre se lee aunque cruce una frontera */
    paint-order: stroke; stroke: var(--sf-card); stroke-width: 5px; stroke-linejoin: round;
    transform-box: fill-box; transform-origin: center;
    transition: opacity .4s var(--sf-ease-out), fill .3s var(--sf-ease);
    transition-delay: calc(1.4s + var(--i, 0) * .07s);
    pointer-events: none;
}
@media (max-width: 899px) { .sf-map-name { font-size: 23px; stroke-width: 6px; } }
.sf-map-pin.is-on .sf-map-name { fill: var(--sf-ink); font-weight: 700; transition-delay: 0s; }
.sf-map-pin.is-soon .sf-map-name { opacity: 0; transition-delay: 0s; }
.sf-map-pin.is-soon.is-on .sf-map-name { opacity: 1; }
@media (hover: hover) { .sf-map-pin.is-soon:hover .sf-map-name { opacity: 1; } }

.sf-map-trail {
    fill: none; stroke: var(--sf-ac-vivo); stroke-width: 2.2; stroke-linecap: round;
    stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0;
}
@keyframes sf-map-trail {
    0%   { stroke-dashoffset: 1; opacity: .9; }
    65%  { stroke-dashoffset: 0; opacity: .9; }
    100% { stroke-dashoffset: 0; opacity: 0; }
}
.sf-map-trail.is-go { animation: sf-map-trail 1.4s var(--sf-ease) forwards; }

/* ===========================================================================
   8d. MAPA DEL LUGAR (assets/js/mapa-lugar.js)
   ---------------------------------------------------------------------------
   Mapa propio del sitio exacto de un evento: MapLibre + teselas de
   OpenFreeMap con el estilo de la marca (tools/mapa/estilo.js). Sustituye al
   iframe de Google, que no se podía reestilizar. El único color del mapa es
   el pin: calles, agua y parques van apagados a propósito.
   ========================================================================= */
.sf-lugar-mapa {
    position: relative; height: 260px; background: var(--sf-bg-2);
    /* El canvas de MapLibre hereda la fuente del sistema en sus controles */
    font-family: var(--sf-sans);
}
@media (min-width: 900px) { .sf-lugar-mapa { height: 300px; } }
.sf-lugar-mapa.is-cargando::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(100deg, transparent 30%, rgba(255,255,254,.55) 50%, transparent 70%) var(--sf-bg-2);
    background-size: 200% 100%;
    animation: sf-lugar-cargando 1.4s linear infinite;
}
@keyframes sf-lugar-cargando { from { background-position: 150% 0; } to { background-position: -50% 0; } }
@media (prefers-reduced-motion: reduce) { .sf-lugar-mapa.is-cargando::after { animation: none; } }

/* Pin: gota morada con filete blanco y el nombre del lugar encima. */
.sf-pin { display: flex; flex-direction: column; align-items: center; gap: 6px; pointer-events: none; }
.sf-pin-nombre {
    max-width: 220px; padding: 5px 10px;
    background: var(--sf-card); color: var(--sf-ink);
    border: 1px solid var(--sf-line); border-radius: 8px;
    box-shadow: 0 1px 2px rgba(20,20,15,.06), 0 4px 12px rgba(20,20,15,.08);
    font: 600 12px/1.3 var(--sf-sans); letter-spacing: -.005em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sf-pin-gota {
    position: relative; width: 34px; height: 34px; margin-bottom: 4px;
    display: grid; place-items: center;
    background: var(--sf-ac); border: 3px solid #fff;
    border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
    box-shadow: 0 2px 6px rgba(20,20,15,.25);
}
.sf-pin-punto { width: 10px; height: 10px; border-radius: 50%; background: #fff; }
/* Sombra en el suelo: sitúa la punta de la gota sobre el mapa */
.sf-pin::after {
    content: ''; width: 14px; height: 5px; margin-top: -6px; border-radius: 50%;
    background: rgba(20,20,15,.22); filter: blur(1px);
}
@keyframes sf-pin-cae { from { opacity: 0; transform: translateY(-14px); } }
.sf-pin-gota, .sf-pin-nombre { animation: sf-pin-cae .45s var(--sf-ease-out, ease-out) both; }
.sf-pin-nombre { animation-delay: .12s; }
@media (prefers-reduced-motion: reduce) { .sf-pin-gota, .sf-pin-nombre { animation: none; } }
/* Zona aproximada (sin punto exacto): solo el rótulo, en el morado claro, sin
   gota ni sombra en el suelo — no señala un sitio, nombra una zona. */
.sf-pin--zona .sf-pin-nombre { color: var(--sf-ac-ink); border-color: var(--sf-ac-line); }
.sf-pin--zona::after { display: none; }
/* La gota va rotada: la animación tiene que conservar la rotación */
@keyframes sf-pin-cae-gota { from { opacity: 0; transform: translateY(-14px) rotate(-45deg); } }
.sf-pin-gota { animation-name: sf-pin-cae-gota; }

/* Controles de MapLibre en el lenguaje del sistema. Doble clase a propósito:
   maplibre-gl.css se carga DESPUÉS (bajo demanda) y con la misma
   especificidad ganaría por orden, dejando su doble borde gris. */
.sf-lugar-mapa .maplibregl-ctrl.maplibregl-ctrl-group {
    border-radius: var(--sf-r-sm); border: 1px solid var(--sf-line);
    box-shadow: 0 1px 2px rgba(20,20,15,.06); background: var(--sf-card); overflow: hidden;
}
.sf-lugar-mapa .maplibregl-ctrl-group button { width: 34px; height: 34px; }
.sf-lugar-mapa .maplibregl-ctrl-group button + button { border-top-color: var(--sf-line); }
@media (pointer: coarse) { .sf-lugar-mapa .maplibregl-ctrl-group button { width: 44px; height: 44px; } }
.sf-lugar-mapa .maplibregl-ctrl-attrib {
    font: 400 10px/1.4 var(--sf-sans); color: var(--sf-ink-3);
    background: rgba(255,255,254,.85);
}
.sf-lugar-mapa .maplibregl-ctrl-attrib a { color: var(--sf-ink-3); }
.sf-lugar-mapa .maplibregl-ctrl.maplibregl-ctrl-attrib.maplibregl-compact { background: rgba(255,255,254,.85); border-radius: 12px; }
/* El botón (i) es un icono negro de MapLibre: se apaga al tono de los rótulos */
.sf-lugar-mapa .maplibregl-ctrl-attrib-button { opacity: .5; }
@media (hover: hover) { .sf-lugar-mapa .maplibregl-ctrl-attrib-button:hover { opacity: .8; } }
.sf-lugar-mapa .maplibregl-cooperative-gesture-screen {
    background: rgba(20,20,15,.55); color: #fff;
    font: 600 15px/1.4 var(--sf-sans); padding: 1rem; text-align: center;
}

/* ===========================================================================
   9. BARRA DE CONFIANZA
   ========================================================================= */
.sf-trust { border-bottom: 1px solid var(--sf-line); }
.sf-trust-in {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
}
.sf-trust-item {
    display: flex; align-items: flex-start; gap: .75rem;
    padding: 1.4rem clamp(1rem, 2vw, 1.6rem);
    border-right: 1px solid var(--sf-line);
}
.sf-trust-item:last-child { border-right: none; }
.sf-trust-item svg { width: 18px; height: 18px; color: var(--sf-ac-ink); flex-shrink: 0; margin-top: 3px; }
.sf-trust-item h4 { font-size: var(--sf-t-body); font-weight: 600; }
.sf-trust-item p  { font-size: var(--sf-t-sm); color: var(--sf-ink-3); margin-top: .1rem; line-height: 1.45; }

/* ===========================================================================
   10. RAILS
   ========================================================================= */
.sf-rail-wrap { position: relative; }
.sf-rail {
    display: grid; grid-auto-flow: column;
    grid-auto-columns: min(66vw, 240px);
    gap: 1.1rem;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none; -ms-overflow-style: none;
    padding-block: .25rem 1rem;
    padding-inline: var(--sf-gutter);
    margin-inline: calc(var(--sf-gutter) * -1);
}
.sf-rail::-webkit-scrollbar { display: none; }
.sf-rail > * { scroll-snap-align: start; }
/* Ancho fijo y no 1fr: con dos eventos pasados, 1fr los estiraba a media pantalla cada uno. */
@media (min-width: 768px) { .sf-rail { grid-auto-columns: 262px; } }

.sf-rail-nav { display: none; gap: .4rem; }
@media (min-width: 900px) { .sf-rail-nav { display: flex; } }
.sf-rail-btn {
    width: 32px; height: 32px; display: grid; place-items: center;
    border: 1px solid var(--sf-line-2); border-radius: 50%;
    color: var(--sf-ink-2);
    transition: all var(--sf-fast) var(--sf-ease);
}
@media (hover: hover) { .sf-rail-btn:hover:not([disabled]) { background: var(--sf-bg-2); color: var(--sf-ink); } }
.sf-rail-btn[disabled] { opacity: .3; cursor: default; }
.sf-rail-btn svg { width: 15px; height: 15px; }

/* ===========================================================================
   11. TARJETA DE EVENTO
   ---------------------------------------------------------------------------
   Anatomía: flyer 3:4 arriba, ficha debajo sobre el papel de la tarjeta.
   El texto NO va encima de la imagen: sobre un flyer cualquiera hay que meter
   un degradado negro para poder leer, y eso ensucia el arte del organizador.
   Separados, el flyer se ve entero y el dato se lee siempre.
   ========================================================================= */
.sf-card {
    display: flex; flex-direction: column;
    background: var(--sf-card);
    border: 1px solid var(--sf-line);
    border-radius: var(--sf-r);
    overflow: hidden;
    transition: transform var(--sf-mid) var(--sf-ease), box-shadow var(--sf-mid) var(--sf-ease);
}
@media (hover: hover) { .sf-card:hover { transform: translateY(-2px); box-shadow: var(--sf-sh); } }

.sf-card-poster {
    position: relative; aspect-ratio: 3 / 4; overflow: hidden;
    background: var(--sf-bg-2);
    border-bottom: 1px solid var(--sf-line);
}
.sf-card-poster img { width: 100%; height: 100%; object-fit: cover; }
/* Sin flyer: la fecha ocupa su lugar, en mono y grande. Es el dato que se
   busca cuando no hay arte que mirar. */
.sf-card-ph {
    position: absolute; inset: 0; display: grid; place-content: center;
    text-align: center; color: var(--sf-ink-3);
    background: repeating-linear-gradient(-45deg, var(--sf-bg-2) 0 10px, var(--sf-bg) 10px 20px);
}
.sf-card-ph .d { font-family: var(--sf-mono); font-size: 3rem; font-weight: 500; line-height: 1; color: var(--sf-ink-2); }
.sf-card-ph .m { font-family: var(--sf-mono); font-size: var(--sf-t-xs); letter-spacing: .2em; margin-top: .4rem; }

.sf-card-tags {
    position: absolute; top: .6rem; left: .6rem; right: .6rem;
    display: flex; gap: .35rem; flex-wrap: wrap;
}

.sf-card-in { padding: .85rem .95rem 1rem; display: flex; flex-direction: column; gap: .4rem; flex: 1; }
/* La categoría hereda su color de --cat, que inyecta PHP */
.sf-card-cat {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--cat, var(--sf-ink-3));
    display: flex; align-items: center; gap: .35rem;
}
.sf-card-cat .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.sf-card-title {
    font-family: var(--sf-display); font-weight: 700;
    font-size: 1.08rem; line-height: 1.2; letter-spacing: -.015em;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sf-card-meta {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    color: var(--sf-ink-3); letter-spacing: .02em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sf-card-foot {
    display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
    margin-top: auto; padding-top: .7rem;
    border-top: 1px solid var(--sf-line);
}
.sf-card-org { font-size: var(--sf-t-sm); color: var(--sf-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-card-price { font-family: var(--sf-mono); font-size: .875rem; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sf-card-price small { font-size: var(--sf-t-xs); color: var(--sf-ink-3); margin-right: .25rem; }
.sf-card-price--free { color: var(--sf-ok); }

.sf-card--past .sf-card-poster img { filter: grayscale(1) contrast(.9); opacity: .75; }
.sf-card--past:hover .sf-card-poster img { filter: grayscale(.4); opacity: 1; }

/* --- Destacado: ficha editorial, flyer a un lado ------------------------- */
.sf-featured { display: grid; gap: 1.1rem; grid-template-columns: 1fr; }
@media (min-width: 980px) { .sf-featured { grid-template-columns: 1.7fr 1fr; } }

.sf-feat {
    display: grid; grid-template-columns: 1fr;
    background: var(--sf-card);
    border: 1px solid var(--sf-line);
    border-radius: var(--sf-r-lg);
    overflow: hidden;
    transition: transform var(--sf-mid) var(--sf-ease), box-shadow var(--sf-mid) var(--sf-ease);
}
@media (min-width: 620px) { .sf-feat { grid-template-columns: minmax(220px, 42%) 1fr; } }
@media (hover: hover) { .sf-feat:hover { transform: translateY(-2px); box-shadow: var(--sf-sh); } }
.sf-feat-img { position: relative; aspect-ratio: 3/4; background: var(--sf-bg-2); border-right: 1px solid var(--sf-line); }
.sf-feat-img img { width: 100%; height: 100%; object-fit: cover; }
.sf-feat-tags { position: absolute; top: .7rem; left: .7rem; display: flex; gap: .35rem; }
.sf-feat-in { padding: clamp(1.15rem, 2.5vw, 2rem); display: flex; flex-direction: column; }
.sf-feat-in h3 { font-size: clamp(1.55rem, 3vw, 2.35rem); margin-block: .7rem .5rem; }
.sf-feat-by { color: var(--sf-ink-3); font-size: var(--sf-t-sm); }
.sf-feat-desc { color: var(--sf-ink-2); font-size: var(--sf-t-body); margin-top: .9rem; line-height: 1.6; }

/* Ficha técnica: dos columnas de dato en mono, como un programa de mano */
.sf-feat-data {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: .9rem 1.5rem; margin-top: 1.5rem; padding-top: 1.25rem;
    border-top: 1px solid var(--sf-line);
}
.sf-feat-data dt {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .12em; text-transform: uppercase; color: var(--sf-ink-4);
}
.sf-feat-data dd { font-size: var(--sf-t-body); margin-top: .3rem; font-weight: 500; }
.sf-feat-data dd.big { font-family: var(--sf-mono); font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.sf-feat-cta { display: flex; align-items: center; gap: .75rem; margin-top: 1.6rem; flex-wrap: wrap; }

/* --- Tarjeta horizontal (columna del destacado) --- */
.sf-hcard {
    display: grid; grid-template-columns: 92px 1fr; gap: .9rem;
    background: var(--sf-card);
    border: 1px solid var(--sf-line);
    border-radius: var(--sf-r);
    padding: .7rem; align-items: center;
    transition: transform var(--sf-fast) var(--sf-ease), box-shadow var(--sf-fast) var(--sf-ease);
}
@media (hover: hover) { .sf-hcard:hover { transform: translateY(-2px); box-shadow: var(--sf-sh); } }
.sf-hcard-img { aspect-ratio: 3/4; border-radius: 9px; overflow: hidden; background: var(--sf-bg-2); border: 1px solid var(--sf-line); }
.sf-hcard-img img { width: 100%; height: 100%; object-fit: cover; }
.sf-hcard-in { min-width: 0; display: flex; flex-direction: column; gap: .3rem; }
.sf-hcard-in h4 {
    font-family: var(--sf-display); font-weight: 700;
    font-size: 1rem; line-height: 1.2; letter-spacing: -.015em;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sf-hcard-row {
    display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
    font-family: var(--sf-mono); font-size: var(--sf-t-xs); color: var(--sf-ink-3);
}
.sf-hcard-row .price { color: var(--sf-ink); font-variant-numeric: tabular-nums; }

/* --- Grilla --- */
.sf-grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fill, minmax(214px, 1fr)); }
@media (max-width: 480px) { .sf-grid { grid-template-columns: repeat(2, 1fr); gap: .7rem; } }

/* ===========================================================================
   12. LO QUE SE VIENE (cuenta atrás)
   ========================================================================= */
.sf-soon { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); }
.sf-soon-card {
    display: grid; grid-template-columns: 104px 1fr; gap: 1.1rem;
    background: var(--sf-card);
    border: 1px solid var(--sf-line);
    border-radius: var(--sf-r);
    padding: .9rem; align-items: center;
    transition: transform var(--sf-mid) var(--sf-ease), box-shadow var(--sf-mid) var(--sf-ease);
}
@media (hover: hover) { .sf-soon-card:hover { transform: translateY(-2px); box-shadow: var(--sf-sh); } }
.sf-soon-flyer { aspect-ratio: 3/4; border-radius: 9px; overflow: hidden; background: var(--sf-bg-2); border: 1px solid var(--sf-line); }
.sf-soon-flyer img { width: 100%; height: 100%; object-fit: cover; }
.sf-soon-in { min-width: 0; }
.sf-soon-in h4 {
    font-family: var(--sf-display); font-weight: 700;
    font-size: 1.08rem; line-height: 1.2; letter-spacing: -.015em;
    margin-block: .5rem .25rem;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sf-soon-meta { font-family: var(--sf-mono); font-size: var(--sf-t-xs); color: var(--sf-ink-3); }

.sf-cd-label {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    text-transform: uppercase; letter-spacing: .12em;
    color: var(--sf-ink-4); margin-top: .85rem;
}
.sf-cd { display: flex; align-items: baseline; gap: .25rem; margin-top: .35rem; }
.sf-cd-u { display: grid; justify-items: center; }
.sf-cd-n {
    font-family: var(--sf-mono); font-size: 1.2rem; font-weight: 500;
    font-variant-numeric: tabular-nums; line-height: 1;
    /* Ancho fijo: sin esto los dos puntos saltan con cada dígito */
    min-width: 2.1ch; text-align: center;
}
.sf-cd-l { font-family: var(--sf-mono); font-size: .56rem; text-transform: uppercase; letter-spacing: .1em; color: var(--sf-ink-4); margin-top: .3rem; }
.sf-cd-s { color: var(--sf-ink-4); font-family: var(--sf-mono); align-self: flex-start; }

/* ===========================================================================
   13. CÓMO FUNCIONA
   ========================================================================= */
.sf-how { background: var(--sf-bg-2); border-block: 1px solid var(--sf-line); }
.sf-steps {
    display: grid; margin-top: 2.5rem;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    border: 1px solid var(--sf-line); border-radius: var(--sf-r);
    background: var(--sf-card); overflow: hidden;
}
.sf-step { padding: 1.6rem 1.5rem; border-right: 1px solid var(--sf-line); }
.sf-step:last-child { border-right: none; }
.sf-step-n {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .12em; color: var(--sf-ac-ink);
}
.sf-step h3 { font-family: var(--sf-display); font-size: var(--sf-t-h3); font-weight: 700; margin-block: .7rem .45rem; letter-spacing: -.015em; }
.sf-step p  { color: var(--sf-ink-2); font-size: var(--sf-t-sm); line-height: 1.6; }
@media (max-width: 700px) {
    .sf-step { border-right: none; border-bottom: 1px solid var(--sf-line); }
    .sf-step:last-child { border-bottom: none; }
}

/* ===========================================================================
   14. BANDA CTA — el único bloque de tinta plena de la página
   ========================================================================= */
.sf-cta { background: var(--sf-ink); color: var(--sf-bg); }
.sf-cta-in {
    padding-block: clamp(3rem, 8vw, 5rem);
    display: grid; gap: 2rem; align-items: center;
    grid-template-columns: 1fr;
}
@media (min-width: 860px) { .sf-cta-in { grid-template-columns: 1.4fr 1fr; gap: 4rem; } }
.sf-cta .sf-label { color: rgba(247,246,240,.5); }
.sf-cta h2 { font-size: clamp(1.9rem, 4.5vw, 3rem); margin-block: .9rem .9rem; }
.sf-cta h2 em { font-style: normal; color: var(--sf-ac-vivo); }
.sf-cta p { color: rgba(247,246,240,.66); font-size: var(--sf-t-lead); max-width: 44ch; }
.sf-cta-actions { display: flex; gap: .7rem; flex-wrap: wrap; }
.sf-cta .sf-btn--primary { background: var(--sf-ac); }
@media (hover: hover) { .sf-cta .sf-btn--primary:hover { background: var(--sf-ac-vivo); } }
.sf-cta .sf-btn--ghost { border-color: rgba(247,246,240,.28); color: var(--sf-bg); }
@media (hover: hover) { .sf-cta .sf-btn--ghost:hover { background: rgba(247,246,240,.12); } }
/* Lista de argumentos, en mono, con línea entre cada uno */
.sf-cta-list { display: grid; gap: 0; }
.sf-cta-list li {
    display: flex; align-items: center; gap: .7rem;
    padding-block: .8rem;
    border-bottom: 1px solid rgba(247,246,240,.14);
    font-family: var(--sf-mono); font-size: var(--sf-t-sm);
    color: rgba(247,246,240,.8);
}
.sf-cta-list li:last-child { border-bottom: none; }
.sf-cta-list svg { width: 15px; height: 15px; color: var(--sf-ac-vivo); flex-shrink: 0; }

/* ===========================================================================
   15. FOOTER
   ========================================================================= */
.sf-footer { border-top: 1px solid var(--sf-line); background: var(--sf-bg); }
.sf-footer-in {
    display: grid; gap: 2.5rem; grid-template-columns: 1fr;
    padding-block: clamp(2.5rem, 6vw, 3.5rem);
}
@media (min-width: 800px) { .sf-footer-in { grid-template-columns: 1.4fr 2fr; gap: 4rem; } }
.sf-footer-brand img { width: 126px; margin-bottom: 1rem; }
.sf-footer-brand p { color: var(--sf-ink-3); font-size: var(--sf-t-sm); line-height: 1.65; max-width: 38ch; }
.sf-social { display: flex; gap: .5rem; margin-top: 1.25rem; }
.sf-social a {
    width: 36px; height: 36px; display: grid; place-items: center;
    border: 1px solid var(--sf-line-2); border-radius: 50%; color: var(--sf-ink-2);
    transition: all var(--sf-fast) var(--sf-ease);
}
@media (hover: hover) { .sf-social a:hover { background: var(--sf-bg-2); color: var(--sf-ink); } }
.sf-social svg { width: 16px; height: 16px; }

.sf-fcols { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(135px, 1fr)); }
.sf-fcols h5 {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs); font-weight: 500;
    text-transform: uppercase; letter-spacing: .13em;
    color: var(--sf-ink-4); margin-bottom: .9rem;
}
.sf-fcols a { display: block; font-size: var(--sf-t-sm); color: var(--sf-ink-2); padding-block: .35rem; transition: color var(--sf-fast) var(--sf-ease); }
.sf-fcols a:hover { color: var(--sf-ink); }

.sf-fbar {
    border-top: 1px solid var(--sf-line);
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; padding-block: 1.25rem;
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    color: var(--sf-ink-3); letter-spacing: .03em;
}

/* ===========================================================================
   16. FORMULARIOS
   ---------------------------------------------------------------------------
   Un solo juego de controles para todo el sitio: acceso, checkout y paneles.
   Antes cada zona traía los suyos (.auth-input oscuro, .input-field claro, más
   lo que pusiera Tailwind encima), y el mismo campo se veía de tres maneras.
   ========================================================================= */
.sf-field { display: flex; flex-direction: column; gap: .4rem; }
.sf-field + .sf-field { margin-top: 1.05rem; }

.sf-field-label {
    display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
    font-size: var(--sf-t-sm); font-weight: 500; color: var(--sf-ink-2);
}
.sf-field-label a { font-size: var(--sf-t-sm); color: var(--sf-ac-ink); }
.sf-field-label a:hover { text-decoration: underline; }

.sf-input, .sf-select, .sf-textarea {
    width: 100%;
    padding: .7rem .9rem;
    background: var(--sf-card);
    border: 1px solid var(--sf-line-2);
    border-radius: var(--sf-r-sm);
    color: var(--sf-ink);
    font-size: var(--sf-t-body);
    font-family: var(--sf-sans);
    outline: none;
    transition: border-color var(--sf-fast) var(--sf-ease), box-shadow var(--sf-fast) var(--sf-ease);
    -webkit-appearance: none; appearance: none;
}
.sf-input::placeholder, .sf-textarea::placeholder { color: var(--sf-ink-4); }
.sf-input:focus, .sf-select:focus, .sf-textarea:focus {
    border-color: var(--sf-ac);
    box-shadow: 0 0 0 3px var(--sf-ac-soft);
}
.sf-input:disabled, .sf-select:disabled, .sf-textarea:disabled {
    background: var(--sf-bg-2); color: var(--sf-ink-3); cursor: not-allowed;
}
.sf-input[aria-invalid="true"] { border-color: var(--sf-hot); }
.sf-textarea { resize: vertical; min-height: 6rem; line-height: 1.55; }
/* Cifras (precio, cupo, cédula) en mono: se leen en columna, no en frase */
.sf-input--num { font-family: var(--sf-mono); font-variant-numeric: tabular-nums; }

.sf-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%235c5c52' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right .8rem center;
    padding-right: 2.25rem; cursor: pointer;
}

/* Campo con icono a la izquierda */
.sf-input-wrap { position: relative; }
.sf-input-ico {
    position: absolute; left: .85rem; top: 50%; transform: translateY(-50%);
    width: 17px; height: 17px; color: var(--sf-ink-3); pointer-events: none;
}
.sf-input-ico + .sf-input { padding-left: 2.5rem; }
/* Botón del ojo para revelar la contraseña */
.sf-input-btn {
    position: absolute; right: .7rem; top: 50%; transform: translateY(-50%);
    color: var(--sf-ink-3); padding: .25rem; line-height: 0;
    transition: color var(--sf-fast) var(--sf-ease);
}
.sf-input-btn:hover { color: var(--sf-ink); }
.sf-input-btn.is-on { color: var(--sf-ac-ink); }
.sf-input--pwd { padding-right: 2.75rem; }

.sf-hint { font-size: var(--sf-t-sm); color: var(--sf-ink-3); line-height: 1.5; }

/* Casilla: el área pulsable es toda la fila, no el cuadradito de 16px */
.sf-check {
    display: flex; align-items: flex-start; gap: .65rem;
    font-size: var(--sf-t-sm); color: var(--sf-ink-2); line-height: 1.5; cursor: pointer;
}
.sf-check input[type="checkbox"], .sf-check input[type="radio"] {
    margin-top: .15rem; width: 1.05rem; height: 1.05rem;
    accent-color: var(--sf-ac); flex-shrink: 0; cursor: pointer;
}
.sf-check a { color: var(--sf-ac-ink); font-weight: 500; }
.sf-check a:hover { text-decoration: underline; }

/* Separador con palabra en medio */
.sf-or {
    display: flex; align-items: center; gap: .85rem;
    margin-block: 1.25rem;
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .12em; text-transform: uppercase; color: var(--sf-ink-4);
}
.sf-or::before, .sf-or::after { content: ""; flex: 1; height: 1px; background: var(--sf-line); }

/* ===========================================================================
   17. AVISOS
   ========================================================================= */
.sf-alert {
    display: flex; align-items: flex-start; gap: .65rem;
    padding: .8rem .95rem;
    border: 1px solid transparent; border-radius: var(--sf-r-sm);
    font-size: var(--sf-t-sm); line-height: 1.5;
}
.sf-alert svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 1px; }
.sf-alert--info  { background: var(--sf-ac-soft); color: var(--sf-ac-ink); border-color: var(--sf-ac-line); }
.sf-alert--ok    { background: var(--sf-ok-soft); color: var(--sf-ok); border-color: #bfe3d4; }
.sf-alert--warn  { background: var(--sf-warn-soft); color: var(--sf-warn); border-color: #f3ddbe; }
.sf-alert--error { background: var(--sf-hot-soft); color: var(--sf-hot); border-color: #f6c9dc; }

/* ===========================================================================
   18. ACCESO (login · registro · recuperar contraseña)
   ---------------------------------------------------------------------------
   Ya no es una tarjeta negra: el acceso es el mismo papel que el resto del
   sitio. Tener dos mundos visuales para "la web" y "mi cuenta" hacía que
   entrar pareciera saltar a otro producto.
   ========================================================================= */
.sf-auth {
    min-height: 100vh;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 2.5rem 1.15rem;
    background:
        radial-gradient(62% 48% at 50% 0%, var(--sf-ac-soft), transparent 64%),
        var(--sf-bg);
}
.sf-auth-card {
    width: 100%; max-width: 420px;
    background: var(--sf-card);
    border: 1px solid var(--sf-line);
    border-radius: var(--sf-r-lg);
    padding: clamp(1.5rem, 4vw, 2.25rem);
    box-shadow: var(--sf-sh);
}
.sf-auth-card--wide { max-width: 520px; }
.sf-auth-brand { text-align: center; margin-bottom: 1.75rem; }
.sf-auth-brand img { width: 145px; height: auto; margin-inline: auto; }
.sf-auth-brand p {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--sf-ink-3); margin-top: .85rem;
}
.sf-auth-title {
    font-family: var(--sf-display);
    font-weight: 700; font-size: 1.3rem; letter-spacing: -.015em;
    text-align: center; margin-bottom: .45rem;
}
.sf-auth-sub { text-align: center; font-size: var(--sf-t-sm); color: var(--sf-ink-3); margin-bottom: 1.5rem; }
.sf-auth-foot {
    display: flex; gap: 1.5rem; justify-content: center; margin-top: 1.75rem;
    font-family: var(--sf-mono); font-size: var(--sf-t-xs); letter-spacing: .06em;
}
.sf-auth-foot a { color: var(--sf-ink-3); transition: color var(--sf-fast) var(--sf-ease); }
.sf-auth-foot a:hover { color: var(--sf-ink); }

/* ===========================================================================
   19. TEXTO CORRIDO (términos, privacidad, descripciones largas)
   ---------------------------------------------------------------------------
   Medida de ~68 caracteres: más ancho y el ojo pierde el renglón al volver.
   ========================================================================= */
.sf-prose { max-width: 68ch; }
.sf-prose > * + * { margin-top: 1.1rem; }
.sf-prose h2 {
    font-family: var(--sf-display);
    font-weight: 700; font-size: 1.45rem; letter-spacing: -.02em;
    margin-top: 2.75rem; padding-top: 1.25rem; border-top: 1px solid var(--sf-line);
}
.sf-prose h3 {
    font-family: var(--sf-display);
    font-weight: 700; font-size: 1.08rem; margin-top: 1.75rem;
}
.sf-prose p, .sf-prose li { color: var(--sf-ink-2); line-height: 1.7; }
.sf-prose ul, .sf-prose ol { padding-left: 1.15rem; display: grid; gap: .5rem; }
.sf-prose ul li { list-style: disc; }
.sf-prose ol li { list-style: decimal; }
.sf-prose a { color: var(--sf-ac-ink); text-decoration: underline; text-underline-offset: 2px; }
.sf-prose strong { color: var(--sf-ink); font-weight: 600; }
.sf-prose code {
    font-family: var(--sf-mono); font-size: .85em;
    background: var(--sf-bg-2); border: 1px solid var(--sf-line);
    border-radius: 5px; padding: .1em .35em;
}
.sf-prose .sf-meta {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .08em; text-transform: uppercase; color: var(--sf-ink-4);
}

/* Página de documento completa */
.sf-doc { padding-block: clamp(2.5rem, 6vw, 4rem); }
.sf-prose > header { margin-bottom: 2.5rem; }
.sf-prose > header h1 {
    font-size: clamp(2rem, 5vw, 3rem);
    margin-block: .8rem .55rem;
}
/* El primer h2 no lleva la línea superior: ya la trae la cabecera */
.sf-prose > h2:first-of-type { border-top: none; padding-top: 0; }
.sf-prose .sf-alert { margin-top: 2.5rem; }

/* Cabecera sobria para páginas de documento */
.sf-doc-head {
    border-bottom: 1px solid var(--sf-line);
    background: var(--sf-bg);
}
.sf-doc-head-in {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; height: 64px;
}
.sf-doc-head img { width: 126px; height: auto; }

/* ===========================================================================
   20. PERFIL PÚBLICO DE EMPRESA (/e/slug)
   ---------------------------------------------------------------------------
   La cabecera la ocupa la empresa, no Scanfun: el visitante llegó buscando a
   ese organizador. Scanfun se firma pequeño a la derecha.
   ========================================================================= */
.sf-org-mini { display: flex; align-items: center; gap: .6rem; min-width: 0; }
/* Flecha de vuelta a la cartelera, antes del nombre de la empresa */
.sf-org-volver {
    display: grid; place-items: center; flex-shrink: 0;
    width: 36px; height: 36px; margin-left: -.4rem;
    border-radius: 50%; color: var(--sf-ink-2);
    transition: background var(--sf-fast) var(--sf-ease), color var(--sf-fast) var(--sf-ease);
}
.sf-org-volver svg { width: 18px; height: 18px; }
@media (hover: hover) { .sf-org-volver:hover { background: var(--sf-bg-2); color: var(--sf-ink); } }
@media (pointer: coarse) { .sf-org-volver { width: 44px; height: 44px; } }
.sf-org-volver + .sf-org-mini { margin-right: auto; }

.sf-org-donde {
    display: inline-flex; align-items: center; gap: .4rem;
    margin-top: .9rem;
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .08em; text-transform: uppercase; color: var(--sf-ink-3);
}
.sf-org-donde svg { width: 14px; height: 14px; color: var(--sf-ac-ink); flex-shrink: 0; }

/* Cierre del perfil: la invitación a seguir mirando en Scanfun */
.sf-org-mas {
    display: flex; align-items: center; justify-content: space-between; gap: 1.25rem; flex-wrap: wrap;
    padding-block: 2rem; border-bottom: 1px solid var(--sf-line);
}
.sf-org-mas p { color: var(--sf-ink-2); margin-top: .4rem; max-width: 46ch; }
.sf-org-mini-img {
    width: 30px; height: 30px; border-radius: 8px; object-fit: cover;
    border: 1px solid var(--sf-line); flex-shrink: 0;
}
.sf-org-mini-ph {
    width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
    display: grid; place-items: center;
    background: var(--sf-ink); color: var(--sf-bg);
    font-family: var(--sf-display); font-weight: 700; font-size: .95rem;
}
.sf-org-mini-nombre {
    font-weight: 600; font-size: var(--sf-t-body);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sf-powered {
    display: flex; align-items: center; gap: .5rem; flex-shrink: 0;
    opacity: .6; transition: opacity var(--sf-fast) var(--sf-ease);
}
.sf-powered:hover { opacity: 1; }
.sf-powered span {
    font-family: var(--sf-mono); font-size: var(--sf-t-xs);
    letter-spacing: .1em; text-transform: uppercase; color: var(--sf-ink-3);
}
@media (max-width: 520px) { .sf-powered span { display: none; } }

/* --- Portada ---
   Sin texto encima, así que no necesita velo: se recorta con una máscara que
   la funde en el papel. Un degradado opaco dejaría una banda gris. */
.sf-org-cover {
    position: relative; height: clamp(150px, 26vw, 280px);
    background: var(--sf-bg-2);
    border-bottom: 1px solid var(--sf-line);
    overflow: hidden;
}
.sf-org-cover-img { width: 100%; height: 100%; object-fit: cover; }
.sf-org-cover::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(to bottom, transparent 55%, rgba(247,246,240,.55) 100%);
}

/* --- Ficha del organizador --- */
.sf-org-perfil {
    text-align: center;
    /* El logo monta sobre la portada: el margen negativo es justo su mitad */
    margin-top: -46px; position: relative; z-index: 2;
    padding-bottom: 1rem;
}
.sf-org-logo {
    width: 92px; height: 92px; margin-inline: auto;
    border-radius: 20px; overflow: hidden;
    border: 3px solid var(--sf-bg);
    background: var(--sf-card);
    box-shadow: var(--sf-sh);
    display: grid; place-items: center;
}
.sf-org-logo img { width: 100%; height: 100%; object-fit: cover; }
.sf-org-logo span {
    font-family: var(--sf-display); font-weight: 700; font-size: 2.4rem;
    color: var(--sf-ink);
}
.sf-org-nombre { font-size: clamp(1.7rem, 4.5vw, 2.6rem); margin-top: 1.1rem; }
.sf-org-desc {
    color: var(--sf-ink-2); max-width: 54ch; margin: .85rem auto 0;
    line-height: 1.65;
}
.sf-org-stats { justify-content: center; margin-top: 1.75rem; }
.sf-org-acciones {
    display: flex; gap: .55rem; justify-content: center; flex-wrap: wrap;
    margin-top: 1.75rem;
}

/* ===========================================================================
   TOAST — lo crea showToast() en app.js
   ========================================================================= */
.sf-toast {
    position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 200;
    max-width: min(92vw, 380px);
    padding: .8rem 1.1rem;
    border: 1px solid var(--sf-line-2);
    border-radius: var(--sf-r-sm);
    background: var(--sf-ink); color: var(--sf-bg);
    font-size: var(--sf-t-sm); line-height: 1.45;
    box-shadow: var(--sf-sh-lg);
    animation: sf-toast-in .26s var(--sf-ease);
}
.sf-toast--success { background: var(--sf-ok); border-color: var(--sf-ok); color: #fff; }
.sf-toast--error   { background: var(--sf-hot); border-color: var(--sf-hot); color: #fff; }
.sf-toast--warning { background: var(--sf-warn); border-color: var(--sf-warn); color: #fff; }
.sf-toast--info    { background: var(--sf-ink); border-color: var(--sf-ink); color: var(--sf-bg); }
.sf-toast.is-out { animation: sf-toast-out .26s var(--sf-ease) forwards; }
@keyframes sf-toast-in  { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes sf-toast-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(12px); } }
@media (max-width: 520px) {
    .sf-toast { left: 1rem; right: 1rem; bottom: 1rem; max-width: none; }
}

/* ===========================================================================
   21. ESTADOS Y UTILIDADES
   ========================================================================= */
.sf-empty {
    text-align: center; padding: clamp(2.5rem, 7vw, 4.5rem) 1.5rem;
    border: 1px dashed var(--sf-line-2); border-radius: var(--sf-r);
    color: var(--sf-ink-3);
}
.sf-empty h3 { font-family: var(--sf-display); font-size: var(--sf-t-h3); color: var(--sf-ink); font-weight: 700; margin-bottom: .5rem; }
.sf-empty p { font-size: var(--sf-t-sm); max-width: 42ch; margin-inline: auto; }

.sf-hidden { display: none !important; }
/* Compatibilidad: varias vistas y app.js alternan la clase `hidden` de app.css.
   Se conserva aquí para que las páginas migradas no tengan que reescribir su JS. */
.hidden { display: none !important; }
.sf-visually-hidden {
    position: absolute !important; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* La clase base solo la pone JS, así que sin JS todo se ve. */
.sf-reveal { opacity: 0; transform: translateY(14px); }
.sf-reveal.is-in { opacity: 1; transform: none; transition: opacity .55s var(--sf-ease), transform .55s var(--sf-ease); }

/* ===========================================================================
   22. RESPONSIVE
   ========================================================================= */
@media (max-width: 900px) {
    .sf-nav-links, .sf-nav-search { display: none; }
    .sf-burger { display: flex; }
    .sf-nav-right .sf-btn { display: none; }
    /* El usuario con sesión sí conserva su acceso al panel: es a donde va. */
    .sf-nav-right .sf-btn.sf-nav-panel { display: inline-flex; }
}
@media (max-width: 620px) {
    .sf-hero-search .sf-btn span { display: none; }
    .sf-hero-search .sf-btn { padding-inline: .8rem; }
    .sf-hero-stat { padding-right: 1.25rem; margin-right: 1.25rem; }
    .sf-soon-card { grid-template-columns: 84px 1fr; gap: .8rem; }
    .sf-hcard { grid-template-columns: 76px 1fr; }
    .sf-trust-item { border-right: none; border-bottom: 1px solid var(--sf-line); }
    .sf-fbar { justify-content: center; text-align: center; }
}

/* ===========================================================================
   MÓVIL — correcciones de comportamiento, no de aspecto
   ---------------------------------------------------------------------------
   Todo lo de aquí arregla algo que se rompe en un teléfono de verdad, no en
   una ventana estrecha del escritorio. Son cosas distintas.
   ========================================================================= */

/* --- 1. El zoom de iOS ----------------------------------------------------
   Safari amplía la página al enfocar un campo con menos de 16px, y NO vuelve
   a su sitio al salir: el usuario se queda con el checkout descuadrado y
   scroll horizontal. Se aplica por tipo de puntero y no por ancho, porque el
   problema es del dispositivo táctil, no del tamaño de la ventana. */
@media (pointer: coarse) {
    .sf-input, .sf-select, .sf-textarea,
    .input-field, select.input-field, textarea.input-field,
    .sf-hero-search input, .sf-nav-search input,
    .manual-input-wrap input,
    input[type="text"], input[type="email"], input[type="tel"],
    input[type="password"], input[type="number"], input[type="search"],
    input[type="date"], input[type="datetime-local"], select, textarea {
        font-size: 16px;
    }
}

/* --- 2. Alto de la ventana en móvil ---------------------------------------
   100vh en iOS incluye la barra de direcciones, así que una pantalla centrada
   queda cortada por abajo. dvh mide el alto real; se deja 100vh de reserva
   para los navegadores que no lo entienden. */
.sf-auth { min-height: 100vh; min-height: 100dvh; }
body.sf-panel { min-height: 100vh; min-height: 100dvh; }
.main-content { min-height: 100vh; min-height: 100dvh; }

/* --- 3. Áreas pulsables ---------------------------------------------------
   El dedo necesita unos 44px. En escritorio no importa: ahí hay un cursor
   de un píxel. */
@media (pointer: coarse) {
    .sf-mmenu a:not(.sf-btn) { padding-block: 1rem; }
    .sf-chip { padding-block: .62rem; }
    .sf-btn--sm, .btn-sm { padding-block: .58rem !important; }
    .sf-btn { min-height: 44px; }
    .sf-input-btn { padding: .5rem; }
    .hdr-chip { padding-block: .55rem; }
    /* Enlaces sueltos que funcionan como botón: el mínimo se declara, no se
       deduce del interlineado. */
    .sf-auth-foot a, .sf-fcols a, .sf-link-arrow, .back-link, .sf-powered {
        display: inline-flex; align-items: center;
        min-height: 44px; padding-block: .35rem;
    }
    /* El logotipo es el enlace a la portada, y su caja es la de la imagen: un
       <a> alrededor de un <img> no tiene más alto que el <img>. Con el
       logotipo apaisado nuevo (220x40) esa caja se queda en 18,9px a 390px de
       ancho, así que el mínimo va aquí y no se hereda de ningún sitio. */
    .sf-nav-logo,
    .sf-auth-brand a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* --- 4. La barra fija de compra tapa el final de la página ----------------
   El botón flotante de la página de evento se superpone al contenido: sin
   este hueco, la última fila de datos queda debajo y no se puede leer. */
@media (max-width: 899px) {
    .event-step1-grid, .checkout-wrap { padding-bottom: 7rem; }
}

/* --- 5. Rejillas que se quedan estrechas ---------------------------------- */
@media (max-width: 520px) {
    /* Dos columnas de 168px no caben en 360px: el contenido se sale */
    .grid-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; }
    .stat-card { padding: .85rem .9rem; }
    .stat-value { font-size: 1.35rem; }

    /* La ficha del destacado pasa a una columna */
    .sf-feat-data { grid-template-columns: 1fr; gap: .75rem; }

    /* Las cifras del hero con línea divisoria se amontonan */
    .sf-hero-stat { padding-right: 1rem; margin-right: 1rem; }
    .sf-hero-stat .n { font-size: 1.35rem; }

    /* Modales a pantalla casi completa */
    .modal { max-height: 92vh; border-radius: 12px; }
    .modal-header { padding: 1.15rem 1.15rem .25rem; font-size: 1.1rem; }
    .modal-body { padding: 1rem 1.15rem; }
    .modal-footer { padding: 0 1.15rem 1.15rem; }
    .modal-footer .btn-primary, .modal-footer .btn-ghost,
    .modal-footer .btn-secondary { flex: 1 1 auto; justify-content: center; }
}

/* --- 6. Cabecera de página del panel --------------------------------------
   El botón de acción no debe quedar pegado al título ni ocupar toda la fila
   si es corto. */
@media (max-width: 640px) {
    .page-header { align-items: flex-start; gap: .85rem; }
    .page-header h1 { font-size: 1.35rem; }
}

/* --- 7. Sin desbordes laterales ------------------------------------------
   Una sola tabla ancha o un rail mal medido provocan scroll horizontal en
   toda la página, que es el defecto móvil más molesto y el más difícil de
   localizar a ojo.

   ⚠️ Va `clip`, NO `hidden`. Son la misma imagen —el desborde no se ve y no se
   puede desplazar— pero `overflow-x: hidden` obliga al otro eje a `auto`, y eso
   convierte a `html` y `body` en contenedores de scroll. En cuanto lo son,
   TODO `position: sticky` de la página deja de pegarse al borde de la pantalla
   y se queda flotando dentro de un contenedor que no es el que scrollea: se va
   con el contenido como si fuera estático.

   Medido en un Chromium real: la barra superior del panel (`.m-topbar`, la que
   lleva la hamburguesa del menú) se declaraba `sticky` desde el rediseño y
   nunca llegó a pegarse. En una pantalla larga —el editor de un evento con
   cinco localidades son ~6.000px— había que subir la página entera para poder
   abrir el menú. Nadie lo vio leyendo el CSS porque la regla que lo rompe está
   a 1.100 líneas de distancia y no menciona `sticky`.

   `clip` no crea contenedor de scroll, así que `sticky` vuelve a funcionar. Se
   deja `hidden` delante como respaldo: un navegador que no entienda `clip`
   ignora la segunda declaración y se queda con el comportamiento de antes. */
html, body { max-width: 100%; overflow-x: hidden; overflow-x: clip; }

/* ===========================================================================
   23. MOVIMIENTO REDUCIDO
   Se anula lo decorativo, no se acorta: una cinta a 0.01s sigue siendo un
   parpadeo. Lo que desaparece es la animación, no el contenido.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
    .sf-pasarela-track > * { animation: none; }
    .sf-pasarela.is-live .sf-card { transform: none; opacity: 1; }
    .sf-pasarela--hero.is-live .sf-card { transform: none; }
    .sf-hero-title .w { animation: none; }
    /* Las fichas ya no recolorean el marco: su señal es levantarse. Sin
       movimiento, la sombra sola sigue diciendo que la ficha responde. */
    .sf-card:hover, .sf-feat:hover, .sf-hcard:hover,
    .sf-soon-card:hover { transform: none; }
    .sf-reveal { opacity: 1; transform: none; }
}
