/* ==========================================================================
   Onskates — Design tokens (Sistema de diseño v1.2)
   Valores extraídos del manual de marca real (.claude/skills/onskates-design)
   ========================================================================== */
:root{
  --negro: #000000;
  --turquesa: #00B0E0;
  --azul: #004B67;
  --negro-pista: #0B0C0E;
  --negro-pista-2: #16181B;
  --gris-oscuro: #333333;
  --gris-claro: #E5E5E5;
  --papel: #FAFAF7;
  --papel-2: #F0F0EF;
  --blanco: #FFFFFF;
  --linea: rgba(215,215,215,0.6);
  --on-dark: #F2F2EF;
  --on-dark-secundario: #CBCED2;
  --on-dark-tenue: #ABAEB2;
  --error: #B3261E;

  --oro: #D9B44A;
  --plata: #BFC4C9;
  --bronce: #C0824C;

  --font-display: "Anton", "Arial Narrow", sans-serif;
  --font-body: "Montserrat", -apple-system, sans-serif;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-pill: 999px;

  --header-h: 84px;
  --max-w: 1180px;

  /* Gramática de movimiento — "la línea del patinador": toda entrada traza
     un arco, nunca una línea recta. Tres curvas, nunca bounce ni elastic. */
  --ease-glide: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-push:  cubic-bezier(0.7, 0, 0.84, 0);
  --ease-carve: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-whisper: 120ms;
  --dur-nudge: 220ms;
  --dur-glide: 420ms;
  --dur-arrival: 720ms;
}

/* Transición nativa entre páginas — el sello de la marca se queda anclado
   en su sitio mientras el contenido de detrás se funde, en vez del
   parpadeo blanco por defecto. Cero JavaScript; se degrada sola a una
   navegación normal donde no hay soporte (Safari, Firefox de momento). */
@view-transition{
  navigation: auto;
}
/* La forma correcta de respetar reduced-motion para View Transitions no es
   condicionar el @view-transition en sí (soporte de anidado en @media poco
   fiable entre navegadores), sino apagar la animación de los pseudo-
   elementos que el navegador genera durante la transición. */
@media (prefers-reduced-motion: reduce){
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*){
    animation: none !important;
  }
}

*{ box-sizing: border-box; }
html{ scroll-behavior: smooth; }
body{
  margin: 0;
  font-family: var(--font-body);
  color: var(--gris-oscuro);
  background: var(--papel);
  -webkit-font-smoothing: antialiased;
}
img{ max-width: 100%; display: block; }
a{ color: inherit; text-decoration: none; }
p{ margin: 0 0 1em; }
/* Oculta visualmente pero deja el contenido disponible para lectores de
   pantalla — p.ej. un <caption> de tabla que ya está cubierto en pantalla
   por un <h2> visible justo encima. */
.visually-hidden{
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   Header
   ========================================================================== */
.site-header{
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  background: var(--blanco);
  border-bottom: 1px solid var(--linea);
  transition: transform .3s ease;
  padding: 0 24px;
}
.site-header.hide{ transform: translateY(-100%); }

.header-inner{
  max-width: var(--max-w);
  height: 100%;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 24px;
}

.logo-lockup{ display: flex; align-items: center; flex-shrink: 0; }
.logo-wordmark{ height: 60px; width: auto; object-fit: contain; view-transition-name: site-logo; }

.nav-center{
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  min-width: 0;
}

.header-actions{
  display: flex;
  align-items: center;
  gap: 18px;
  flex-shrink: 0;
}

.main-nav{
  display: flex;
  align-items: center;
  gap: 26px;
  font-size: 14px;
  font-weight: 600;
}
.main-nav > a{ color: var(--gris-oscuro); transition: color .15s ease; white-space: nowrap; }
.main-nav > a:hover, .main-nav > a.active, .nav-link.active{ color: var(--azul); }

/* Elementos de nav con desplegable (El Club, Team, Clases) */
.nav-item{
  position: relative;
  display: flex;
  align-items: center;
}
.nav-item-row{ display: flex; align-items: center; }
.nav-link{ color: var(--gris-oscuro); transition: color .15s ease; white-space: nowrap; }
.nav-link:hover{ color: var(--azul); }

.nav-caret{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  color: var(--gris-oscuro);
}
.nav-caret::after{
  content: "";
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform .15s ease;
}
.nav-item.open .nav-caret{ color: var(--azul); }
.nav-item.open .nav-caret::after{ transform: rotate(180deg); }

.dropdown{
  display: flex;
  flex-direction: column;
  position: absolute;
  top: calc(100% + 14px);
  left: 0;
  min-width: 220px;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radius-md);
  padding: 8px;
  z-index: 60;
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
}
.nav-item.open .dropdown{ opacity: 1; transform: none; pointer-events: auto; }
/* Puente invisible que cubre el hueco entre el nav-item y el desplegable,
   para que el hover no se pierda al cruzar ese espacio con el ratón. */
.nav-item::after{
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 14px;
}
.dropdown a{
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
  color: var(--gris-oscuro);
  white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}
.dropdown a:hover{ background: var(--papel-2); color: var(--azul); }

/* En escritorio los desplegables se abren también con el ratón (hover),
   sin perder el clic para teclado/táctil por debajo de 900px. */
@media (min-width: 901px){
  .nav-item:hover .dropdown,
  .nav-item:focus-within .dropdown{ opacity: 1; transform: none; pointer-events: auto; }
  .nav-item:hover .nav-caret,
  .nav-item:focus-within .nav-caret{ color: var(--azul); }
  .nav-item:hover .nav-caret::after,
  .nav-item:focus-within .nav-caret::after{ transform: rotate(180deg); }
}

.nav-cta{
  flex-shrink: 0;
  background: var(--turquesa);
  color: var(--negro);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.02em;
  padding: 14px 22px;
  border-radius: var(--radius-md);
  transition: background .15s ease, color .15s ease;
}
.nav-cta:hover{ background: var(--azul); color: var(--blanco); }
.nav-cta:focus-visible{ outline: 2px solid var(--negro); outline-offset: 2px; }

.nav-toggle{
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}
.nav-toggle span{
  display: block;
  height: 2px;
  width: 24px;
  background: var(--negro);
  transition: transform .2s ease, opacity .2s ease;
  transform-origin: center;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1){ transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2){ opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3){ transform: translateY(-7px) rotate(-45deg); }

/* ==========================================================================
   Hero — titular con relieve turquesa desplazado (firma de marca)
   ========================================================================== */
.hero-photo{
  position: relative;
  overflow: hidden;
}
.hero-bg{
  position: absolute;
  inset: 0;
}
.hero-bg img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 38%;
}
.hero-scrim{
  position: absolute;
  inset: 0;
  /* Degradado direccional en vez de opacidad plana: el texto vive en la
     mitad izquierda (.hero-inner max-width:560px de un .hero-content de
     1180px), así que solo esa zona necesita oscurecerse a fondo — la mitad
     derecha, donde está el atleta, se deja respirar. */
  background: linear-gradient(90deg, rgba(11,12,14,0.82) 0%, rgba(11,12,14,0.60) 48%, rgba(11,12,14,0.28) 100%);
}
/* Parallax sutil del hero — solo en navegadores con scroll-timelines y sin
   prefers-reduced-motion. El escalado de más da margen para el desplazamiento
   sin dejar huecos en los bordes; overflow:hidden en .hero-photo recorta el resto. */
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    .hero-bg img{
      animation: heroParallax linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
      will-change: transform;
    }
    @keyframes heroParallax{
      from{ transform: scale(1.12) translateY(-3%); }
      to{ transform: scale(1.12) translateY(3%); }
    }
  }
}
.hero-content{
  position: relative;
  z-index: 1;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 120px 24px 96px;
}
.hero-inner{ max-width: 560px; }
.hero-photo .eyebrow{ color: var(--on-dark-secundario); }
.hero-photo .hero-title{ color: var(--blanco); }
@media (max-width: 640px){
  .hero-content{ padding: 88px 20px 64px; }
  /* Con .hero-inner a ancho completo en móvil ya no hay una mitad "libre de
     texto" que respirar — el degradado vuelve a vertical (oscuro abajo,
     donde está el titular) y el recorte se centra más en el patinador para
     no perder el patín trasero ni la mano delantera del salto. */
  .hero-bg img{ object-position: center 34%; }
  .hero-scrim{ background: linear-gradient(180deg, rgba(11,12,14,0.55) 0%, rgba(11,12,14,0.86) 68%, rgba(11,12,14,0.86) 100%); }
}

.eyebrow{
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--azul);
  margin: 0 0 20px;
  display: flex;
  align-items: center;
  gap: 10px;
  scroll-margin-top: calc(var(--header-h) + 20px);
}
.content-inner .eyebrow,
.content-inner-wide .eyebrow{
  max-width: none;
  /* .content-inner p (0,1,1) le gana en especificidad a .eyebrow a secas
     (0,1,0) cuando el eyebrow es un <p>, aplanándolo a 17px gris de cuerpo
     normal en vez de 13px azul en mayúsculas — bug preexistente en las 15
     páginas que combinan .content-inner con .eyebrow, no algo nuevo. */
  font-size: 13px;
  line-height: normal;
  color: var(--azul);
}
.eyebrow::before{
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 8px solid var(--turquesa);
}

.hero-title{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(40px, 6.4vw, 76px);
  line-height: 1.15;
  letter-spacing: 0.005em;
  color: var(--negro);
  margin: 0 0 36px;
  text-transform: uppercase;
}
/* La firma de marca (relieve turquesa desplazado) se reserva para textos
   cortos de una línea, como el logotipo — ver .logo-word. En un titular
   multilínea el duplicado se solapa entre líneas y rompe la lectura. */

.hero-actions{ display: flex; gap: 16px; flex-wrap: wrap; }
.hero-actions .link-arrow{ margin: 0; }

.btn{
  display: inline-block;
  padding: 14px 26px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.02em;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.btn:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
.btn-primary{ background: var(--turquesa); color: var(--negro); border-color: var(--turquesa); }
.btn-primary:hover{ background: var(--azul); color: var(--blanco); border-color: var(--azul); }
.btn-secondary{ background: transparent; color: var(--negro); border-color: var(--negro); }
.btn-secondary:hover{ background: var(--negro); color: var(--blanco); }
.btn-secondary-dark{ background: transparent; color: var(--blanco); border-color: rgba(255,255,255,0.4); }
.btn-secondary-dark:hover{ background: var(--blanco); color: var(--negro); border-color: var(--blanco); }

/* ==========================================================================
   Propuesta de valor
   ========================================================================== */
.value-prop{
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 64px 24px 72px;
}
.value-prop p{
  max-width: 62ch;
  font-size: clamp(17px, 2vw, 20px);
  line-height: 1.55;
  color: var(--negro);
  margin: 0;
}

/* ==========================================================================
   Etapas — recorrido narrativo por el club
   El Club (1.0) → Escuela (2.0) → Team (3.0, Negro Pista) → Únete (4.0)
   Regla de marca: nunca cruzar fondos ni roles de icono entre sub-marcas.
   ========================================================================== */
.stage{ padding: 88px 24px; }
.stage-dark{ background: var(--negro-pista); color: var(--blanco); position: relative; overflow: hidden; }
.stage-tint{ background: var(--papel-2); }

.stage-watermark{
  position: absolute;
  top: 96px;
  left: -8px;
  width: 260px;
  opacity: 0.07;
  pointer-events: none;
  user-select: none;
}
@media (max-width: 860px){
  .stage-watermark{ width: 200px; top: 80px; left: -4px; }
}
/* Deriva casi imperceptible del watermark, ligada al scroll — el icono ya
   está al 7% de opacidad, así que el movimiento se nota sin distraer. */
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    .stage-watermark{
      animation: watermarkDrift linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
    @keyframes watermarkDrift{
      from{ transform: translateY(-18px) rotate(-3deg); }
      to{ transform: translateY(18px) rotate(3deg); }
    }
  }
}

.stage-inner{
  max-width: var(--max-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 0.5fr 1.5fr;
  gap: 48px;
  align-items: start;
}
@media (max-width: 860px){
  .stage-inner{ grid-template-columns: 1fr; gap: 20px; }
}
/* Etapas 2 (Escuela) y 3 (Team) llevan foto en el marcador — con la columna
   base de 0.5fr se quedaba a 283px de ancho, visiblemente más pequeña que
   la de Team (481px, ya ensanchada para el watermark). Misma proporción en
   ambas para que las dos fotos midan lo mismo. Envuelto en min-width para
   no ganarle en especificidad al colapso a una columna de la media query
   de arriba en móvil. */
@media (min-width: 861px){
  .stage-dark .stage-inner,
  .stage-tint .stage-inner{ grid-template-columns: 0.85fr 1.15fr; }
  /* El texto de Escuela (317px) es más corto que su foto a este ancho de
     columna (535px) — Team no necesita esto porque su texto ya casa casi
     exacto. En vez de dejar hueco vacío bajo el texto, se centra junto a
     la foto; la foto se queda arriba (comportamiento por defecto de
     .stage-inner) para no descolgar el número/etiqueta del marcador. */
  .stage-tint .stage-content{ align-self: center; }
}

.stage-marker{ position: relative; }
/* Foto de apoyo en la columna del marcador — rellena el hueco que dejaba
   antes solo número + etiqueta (Etapa 2.0 y 3.0). Proporción 0.9 elegida
   para que la altura resultante (ancho de columna ÷ 0.9) case con la
   altura real de la columna de texto de al lado en ambas etapas — medido
   en vivo: Escuela 283×314 vs texto 317px, Team 481×535 vs texto 531px —
   así ninguna de las dos tarjetas deja espacio vacío bajo el texto ni
   fuerza a la foto a desbordar por debajo. */
.stage-marker-photo{
  display: block;
  width: 100%;
  aspect-ratio: 0.9;
  object-fit: cover;
  border-radius: var(--radius-md);
  margin-top: 24px;
}
@media (max-width: 860px){
  /* Contenedor bajo y ancho (220px de alto) muy distinto a la proporción
     0.9 (alta y estrecha) de escritorio — con object-position 50% (por
     defecto) el recorte caía justo a la altura del torso y dejaba fuera
     las tres caras. 12% saca las caras sin perder el logo de la camiseta. */
  .stage-marker-photo{ aspect-ratio: auto; height: 220px; object-position: center 12%; }
}
/* Etapa 3 (Team): mismo alto que la base, pero recortada hacia abajo
   (object-position) para descartar la grada vacía de encima del patinador
   en vez de sus pies — así gana protagonismo dentro del mismo encuadre.
   z-index por encima del watermark absoluto vecino. */
.stage-marker-photo-team{
  position: relative;
  z-index: 1;
  object-position: center 82%;
}
@media (max-width: 640px){
  .stage-marker-photo-team{ display: none; }
}
.stage-num{
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.2vw, 1.75rem);
  line-height: 1;
  color: var(--azul);
  display: block;
}
.stage-dark .stage-num{ color: var(--turquesa); }
/* El número de etapa "entra en foco" al aparecer, ligado al scroll — capa
   aditiva sobre el fade/translateY que ya aplica .reveal al .stage-marker
   contenedor; no sustituye ese sistema, se suma a él en navegadores compatibles. */
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    .stage-num{
      animation: stageNumFocus linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 40%;
    }
    @keyframes stageNumFocus{
      from{ opacity: 0.35; transform: scale(0.82); }
      to{ opacity: 1; transform: scale(1); }
    }
  }
}
.stage-label{
  display: block;
  margin-top: 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--azul);
}
.stage-dark .stage-label{ color: var(--on-dark-secundario); }

.stage-content h2{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(24px, 3.4vw, 32px);
  text-transform: uppercase;
  letter-spacing: 0.01em; /* tracking normal — Escuela/El Club/Únete */
  color: var(--negro);
  margin: 0 0 16px;
}
.stage-dark .stage-content h2{ color: var(--blanco); letter-spacing: -0.02em; /* tracking cerrado — Team */ }
/* Combinador de hijo directo, no descendiente — .stage-content contiene
   componentes con sus propios <p> más abajo (.next-comp-highlight,
   .stage-stats), que esta regla no debe alcanzar. Con "p" a secas
   (descendiente) su especificidad (0,1,1) le ganaba por accidente a las
   reglas de .next-comp-highlight-name/-details/-countdown (0,1,0),
   colapsando las tres a un mismo tamaño y color de texto. */
.stage-content > p{
  max-width: 60ch;
  font-size: 17px;
  line-height: 1.6;
  color: var(--gris-oscuro);
  margin: 0 0 16px;
}
.stage-dark .stage-content > p{ color: var(--on-dark-secundario); }

.path-tag{
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 12px;
  margin-bottom: 16px;
  border-radius: var(--radius-pill);
  background: var(--turquesa);
  color: var(--negro);
}

.link-arrow{
  display: inline-block;
  font-weight: 700;
  font-size: 14px;
  color: var(--azul);
  padding: 14px 6px;
  margin: -6px -6px -14px;
}
/* --turquesa como outline sobre fondo claro medía 2.42:1 con teclado real
   (bajo el mínimo 3:1 de WCAG 2.2 §1.4.11 para indicadores de foco) — el
   propio texto del link-arrow ya usa --azul en claro por el mismo motivo.
   --turquesa se mantiene en las variantes oscuras de abajo, donde sí tiene
   contraste de sobra. */
.link-arrow:focus-visible{ outline: 2px solid var(--azul); outline-offset: 2px; border-radius: 2px; }
.stage-dark .link-arrow,
.content-block-dark .link-arrow,
.page-hero-dark .link-arrow{ color: var(--turquesa); }
.stage-dark .link-arrow:focus-visible,
.content-block-dark .link-arrow:focus-visible,
.page-hero-dark .link-arrow:focus-visible{ outline-color: var(--turquesa); }
.link-arrow-glyph{ display: inline-block; transition: transform .15s ease; }
.link-arrow:hover .link-arrow-glyph,
.btn:hover .link-arrow-glyph{ transform: translateX(4px); }

/* Franja compacta de enlaces — versión ligera de .values-grid para una
   sección de apoyo intermedia, no un cierre de página con peso propio. */
.team-quicklinks{
  display: flex;
  flex-wrap: wrap;
  gap: 16px 36px;
  margin-top: 20px;
}
/* Sin margen negativo aquí: en un contenedor flex con gap, un margen
   negativo se resta del gap y puede solapar filas al hacer wrap (probado:
   -12px de solape con el margen simétrico de .link-arrow). margin:0 deja
   que el gap absorba el padding extra del target táctil. */
.team-quicklinks .link-arrow{ margin: 0; }

.stage-divider{
  max-width: var(--max-w);
  margin: 0 auto;
  height: 1px;
  background: var(--linea);
}

/* Etapa 3 — cifras del Team + aviso de próxima competición */
.stage-stats{
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  margin: 24px 0 32px;
}
/* AVISO para quien reutilice .stage-stats en un contexto nuevo: los colores
   de abajo (turquesa/on-dark-secundario) solo tienen contraste garantizado
   sobre fondo oscuro (--negro-pista, la Etapa 3/Team). Turquesa sobre
   --papel-2 da 2.22:1 — falla incluso el mínimo de texto grande. Cualquier
   fondo nuevo (no oscuro, no .stage-tint) necesita su propio chequeo de
   contraste y su propio override, igual que el de .stage-tint aquí abajo. */
.stat-num{
  display: block;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.8rem, 3vw, 2.4rem);
  color: var(--turquesa);
}
.stage-stats p{ margin: 4px 0 0; font-size: 12px; color: var(--on-dark-secundario); }
/* .content-block-dark .content-inner p (0,2,1) le gana por accidente a las
   reglas de .stage-stats p / .next-comp-highlight-name/-details/-countdown
   (0,1,1 o 0,1,0) cuando el elemento es un <p>, aplanándolas todas a 17px
   gris — mismo patrón del bug del eyebrow ya arreglado antes. Solo el color
   de la cuenta atrás se había corregido; el tamaño seguía roto en las 4. */
.content-block-dark .content-inner .stage-stats p{ font-size: 12px; line-height: normal; }
.content-block-dark .content-inner .next-comp-highlight-name{
  font-family: var(--font-display);
  font-size: 20px;
  line-height: normal;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  color: var(--blanco);
}
.content-block-dark .content-inner .next-comp-highlight-details{
  font-size: 14px;
  line-height: normal;
  color: var(--on-dark-secundario);
}
/* Etapa 2 (Escuela) usa .stage-tint, fondo claro — override verificado:
   azul da 8.36:1 sobre --papel-2 (turquesa daba solo 2.22:1). */
.stage-tint .stat-num,
.content-block-tint .stat-num{ color: var(--azul); }
.stage-tint .stage-stats p,
.content-block-tint .stage-stats p{ color: var(--gris-oscuro); font-size: 12px; }

.badge{
  display: inline-block;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: var(--turquesa);
  color: var(--negro);
  margin-bottom: 12px;
}
.next-comp-highlight{
  border: 1px solid rgba(255,255,255,0.16);
  border-radius: var(--radius-md);
  padding: 20px 24px;
  margin-bottom: 24px;
}
.next-comp-highlight-narrow{
  max-width: 420px;
  margin-right: auto;
}
.next-comp-highlight-name{
  font-family: var(--font-display);
  font-size: 20px;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  color: var(--blanco);
  margin: 0 0 4px;
}
.next-comp-highlight-details{
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  color: var(--on-dark-secundario);
  margin: 0 0 14px;
}
.next-comp-highlight-countdown{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 13px;
  color: var(--turquesa);
  margin: 0 20px 14px 0;
}
/* Sin esta regla el atributo [hidden] no surtiría efecto: la regla de arriba
   fija display:inline-flex y, al venir de la hoja de autor, gana siempre a la
   regla [hidden]{display:none} del navegador. script.js oculta la cuenta atrás
   (en vez de eliminarla) cuando la competición ya ha pasado. */
.next-comp-highlight-countdown[hidden]{ display: none; }
/* .content-block-dark .content-inner p (0,2,1) le gana por accidente a esta
   regla (0,1,0) cuando el elemento es un <p> — mismo patrón del bug del
   eyebrow ya arreglado antes. La cuenta atrás se pintaba en gris en vez de
   turquesa. */
.content-block-dark .content-inner .next-comp-highlight-countdown{ color: var(--turquesa); font-size: 13px; line-height: normal; }
.next-comp-highlight-countdown::before{
  content: "";
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--turquesa);
}
@media (prefers-reduced-motion: no-preference){
  .next-comp-highlight-countdown::before{ animation: countdownPulse 1.8s ease-in-out infinite; }
}
@keyframes countdownPulse{
  0%, 100%{ opacity: 1; transform: scale(1); }
  50%{ opacity: 0.4; transform: scale(1.3); }
}

/* Etapa 4 */
#etapa-4 .stage-content p:not(.cta-reassurance){ margin-bottom: 28px; }
.stage-content .cta-reassurance{
  margin: 28px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--gris-oscuro);
}

/* ==========================================================================
   Páginas interiores — cabecera de página y bloques de contenido
   ========================================================================== */
.page-hero{ padding: 64px 24px 24px; }
@media (max-width: 860px) and (max-height: 500px) and (orientation: landscape){
  /* Mismo ajuste ya aplicado a .page-hero-split-media y .page-hero-photo:
     sin esto, en apaisado bajo el hero + header se comen casi toda la
     pantalla antes de llegar a cualquier contenido real. */
  .page-hero{ padding: 24px 24px 16px; }
}
.page-hero-inner{
  max-width: var(--max-w);
  margin: 0 auto;
}
.breadcrumb{
  font-size: 13px;
  font-weight: 600;
  color: var(--gris-oscuro);
  margin: 0 0 20px;
}
.breadcrumb a{
  color: var(--gris-oscuro);
  display: inline-block;
  padding: 14px 6px;
  margin: -14px -6px;
}
.breadcrumb a:hover{ color: var(--azul); }
.breadcrumb a:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; border-radius: 2px; }
.page-hero-dark .breadcrumb a:hover{ color: var(--turquesa); }
.page-hero-title{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 5.5vw, 56px);
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--negro);
  margin: 0 0 20px;
}
.page-hero-lead{
  max-width: 60ch;
  font-size: clamp(16px, 1.8vw, 19px);
  line-height: 1.6;
  color: var(--gris-oscuro);
  margin: 0;
}
/* Excepción: link-arrow incrustado a media frase (noticias.html), no una
   acción independiente. El padding/margen negativo del target táctil
   desborda la línea de texto y solapa la sección siguiente; WCAG 2.5.5
   exime explícitamente los enlaces dentro de un bloque de texto corrido,
   así que aquí vuelve a su tamaño de enlace en línea normal. */
.page-hero-lead .link-arrow{ padding: 0; margin: 0; }

.hero-jump-links{
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  margin-top: 20px;
}
.hero-jump-links a{
  font-weight: 700;
  font-size: 13.5px;
  letter-spacing: 0.02em;
  color: var(--azul);
  padding: 18px 6px 8px;
  border-bottom: 2px solid var(--linea);
  transition: border-color .15s ease, color .15s ease;
}
.hero-jump-links a:hover{ border-color: var(--turquesa); color: var(--turquesa); }
.hero-jump-links a:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; border-radius: 2px; }
.hero-jump-links .discipline-collapse-all{
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gris-oscuro);
  background: none;
  border: 1px solid var(--linea);
  border-radius: var(--radius-pill);
  padding: 7px 16px;
  margin-left: auto;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.hero-jump-links .discipline-collapse-all:hover{ border-color: var(--turquesa); color: var(--turquesa); }
.hero-jump-links .discipline-collapse-all:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }

.content-block{ padding: 64px 24px; }
.content-block-aside{ padding: 48px 24px; }
.content-block-emphasis{ padding: 88px 24px; }
.content-block-tint{ background: var(--papel-2); }
@media (max-width: 640px){
  /* En móvil, el ritmo interno de los componentes ya se aprieta (ver
     .team-result-top, .team-result-strip) pero el macro-hueco de sección
     no lo hacía — hasta un 18-20% de una pantalla de un visor entero
     gastado en blanco en cada transición. */
  .content-block{ padding: 48px 24px; }
  .content-block-emphasis{ padding: 64px 24px; }
}
.content-inner{
  max-width: var(--max-w);
  margin: 0 auto;
}
#direccion ~ p,
#direccion-exacta ~ p,
#entrenadores ~ p,
#monitores ~ p{ max-width: 60ch; }
.content-inner p{
  font-size: 17px;
  line-height: 1.65;
  color: var(--gris-oscuro);
}
.content-title{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 3.6vw, 34px);
  text-transform: uppercase;
  color: var(--negro);
  margin: 0 0 20px;
}

/* Franja de cifras sobre fondo claro */
.stat-row{ display: flex; flex-wrap: wrap; gap: 40px; margin-top: 8px; }
@media (max-width: 900px){
  .stat-row-compact{ flex-direction: column; gap: 20px; }
}
.stat-row-num{
  display: block;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.8rem, 3vw, 2.4rem);
  color: var(--azul);
}
.stat-row-item p{ margin: 4px 0 0; font-size: 13px; color: var(--gris-oscuro); }
.content-block-dark .stat-row-item p{ color: var(--on-dark-secundario); }

/* Medallero — colores por metal */
.stat-row-num.is-gold{ color: var(--oro); }
.stat-row-num.is-silver{ color: var(--plata); }
.stat-row-num.is-bronze{ color: var(--bronce); }
.stat-row-num.is-total{ color: var(--turquesa); }

/* Medallero individual (resultados.html): más peso visual que la franja
   .stat-row de base — cada cifra se convierte en su propia tarjeta ligera
   (misma familia visual que .team-result-card pero más contenida), con
   números más grandes, repartidas a todo el ancho de la sección en vez
   de agruparse a la izquierda con hueco vacío al lado. */
.stat-row-featured{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.stat-row-featured .stat-row-item{
  padding: 28px 20px;
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: var(--radius-md);
  background: rgba(255,255,255,0.03);
  text-align: center;
}
.stat-row-featured .stat-row-num{ font-size: clamp(2.6rem, 4.5vw, 3.6rem); }
@media (max-width: 720px){
  .stat-row-featured{ grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 420px){
  .stat-row-featured{ grid-template-columns: 1fr; }
}

/* Cabecera + primer bloque de contenido con imagen a la derecha a doble altura */
.page-hero-split{ padding: 64px 24px; }
.page-hero-split-inner{
  max-width: var(--max-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 56px;
  align-items: stretch;
}
.page-hero-split-media{
  border-radius: var(--radius-lg);
  overflow: hidden;
  min-height: 100%;
}
.page-hero-split-media img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.page-hero-split-divider{
  height: 1px;
  background: var(--linea);
  margin: 40px 0 36px;
}
.page-hero-split-inner .reveal p:not(.breadcrumb):not(.page-hero-lead):not(.eyebrow){
  max-width: 60ch;
  font-size: 17px;
  line-height: 1.65;
  color: var(--gris-oscuro);
}
@media (max-width: 860px){
  .page-hero-split-inner{ grid-template-columns: 1fr; gap: 28px; }
  .page-hero-split-media{ order: -1; max-height: 380px; }
}
@media (max-width: 860px) and (max-height: 500px) and (orientation: landscape){
  .page-hero-split-media{ max-height: 140px; }
}

/* Variante oscura — páginas del facet Team (Negro Pista) */
.page-hero-dark{ background: var(--negro-pista); }
.page-hero-dark .breadcrumb{ color: var(--on-dark-tenue); }
.page-hero-dark .breadcrumb a{ color: var(--on-dark-secundario); }
.page-hero-dark .page-hero-title{ color: var(--blanco); }
.page-hero-dark .page-hero-lead{ color: var(--on-dark-secundario); }
.page-hero-dark .hero-jump-links a{ color: var(--blanco); border-color: rgba(255,255,255,0.35); }
.page-hero-dark .hero-jump-links a:hover{ border-color: var(--turquesa); color: var(--turquesa); }

.content-block-dark{ background: var(--negro-pista); }
.content-block-dark-tint{ background: var(--negro-pista-2); }
.content-block-dark .eyebrow{ color: var(--on-dark-secundario); }
.content-block-dark .content-title{ color: var(--blanco); }
/* Texto claro sobre negro-pista: un paso más de interlineado y tracking
   que el equivalente en tema claro, para que los trazos finos de Montserrat
   no "vibren" sobre un fondo tan oscuro. Mismo tamaño, misma jerarquía. */
.content-block-dark .content-inner p,
.content-block-dark .content-inner-wide p{ color: var(--on-dark-secundario); line-height: 1.75; letter-spacing: 0.005em; }
/* Roster (Patinadores y Palmarés): estos componentes son <p>, así que la regla
   genérica de arriba les gana por especificidad y aplana su jerarquía propia.
   Se restauran aquí con un selector más específico. */
.content-block-dark .content-inner-wide .roster-back-name{ color: var(--blanco); line-height: normal; letter-spacing: 0.01em; }
.content-block-dark .content-inner-wide .roster-back-title{ color: var(--turquesa); line-height: normal; letter-spacing: 0.1em; }
.content-block-dark .content-inner-wide .roster-mark-discipline{ color: var(--turquesa); line-height: normal; letter-spacing: 0.08em; }
.content-block-dark .content-inner-wide .roster-mark-value{ color: var(--blanco); line-height: 1; letter-spacing: normal; }
.content-block-dark .content-inner-wide .roster-mark-context{ color: var(--on-dark-secundario); line-height: normal; letter-spacing: 0.02em; }
.content-block-dark .content-inner-wide .eyebrow{ line-height: normal; letter-spacing: 0.08em; }
.content-block-dark .content-inner .eyebrow{ line-height: normal; letter-spacing: 0.08em; }
.content-block-dark .content-inner-wide .roster-count{ line-height: normal; letter-spacing: 0.02em; }
.content-block-dark .content-inner-wide .ranking-gender-label{ line-height: normal; letter-spacing: 0.12em; }
.content-block-dark .value-card{ border-color: rgba(255,255,255,0.16); }
.content-block-dark .value-card h3{ color: var(--blanco); }
.content-block-dark .value-card p{ color: var(--on-dark-secundario); line-height: 1.6; letter-spacing: 0.005em; }

/* Cabecera de página con fotografía — variante de .page-hero */
.page-hero-photo{
  position: relative;
  overflow: hidden;
  min-height: 420px;
  display: flex;
  align-items: flex-end;
}
.page-hero-photo .page-hero-bg{ position: absolute; inset: 0; }
.page-hero-photo .page-hero-bg img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Mismo parallax por scroll que ya usa el hero de la home, extendido a las
   cabeceras interiores (hoy completamente quietas). El escalado de más da
   margen para el desplazamiento sin dejar huecos en los bordes;
   overflow:hidden en .page-hero-photo recorta el resto. */
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    .page-hero-photo .page-hero-bg img{
      animation: pageHeroParallax linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
      will-change: transform;
    }
    @keyframes pageHeroParallax{
      from{ transform: scale(1.12) translateY(-3%); }
      to{ transform: scale(1.12) translateY(3%); }
    }
  }
}
.page-hero-photo .page-hero-bg img.img-pos-low{ object-position: center 88%; }
.page-hero-photo .page-hero-bg img.img-pos-top{ object-position: center 15%; }
/* Medido con recorte real a 1280/1920/2560px de ancho (min-height:420px
   fijo, la franja se estrecha mucho en pantallas anchas): 8% deja la
   cabeza del patinador más alto con margen en los tres casos. */
.palmares-hero-photo{ object-position: center 8%; }
.page-hero-photo .page-hero-scrim{
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11,12,14,0.25) 0%, rgba(11,12,14,0.82) 100%);
}
/* Modificador puntual (escuela.html): la foto tiene cielo/nubes claras justo
   detrás del título y la entradilla — 0.25→0.82 dejaba el peor píxel en
   solo ~3:1. Reforzado para ≥5:1 medido con canvas sobre el recorte real.
   Aparte de .page-hero-photo-tall porque aquí sí comparte clase base con
   equipo-tecnico/patinadores-y-palmares/team, que no tienen este problema. */
.page-hero-photo-strong-scrim .page-hero-scrim{
  background: linear-gradient(180deg, rgba(11,12,14,0.47) 0%, rgba(11,12,14,0.91) 100%);
}
.page-hero-photo .page-hero-inner{ position: relative; z-index: 1; width: 100%; }
.page-hero-photo .breadcrumb{ color: var(--on-dark-secundario); }
.page-hero-photo .breadcrumb a{ color: var(--blanco); }
.page-hero-photo .page-hero-title{ color: var(--blanco); }
.page-hero-photo .page-hero-lead{ color: var(--on-dark-secundario); }
.page-hero-photo .hero-jump-links a{ color: var(--blanco); border-color: rgba(255,255,255,0.35); }
.page-hero-photo .hero-jump-links a:hover{ border-color: var(--turquesa); color: var(--turquesa); }
/* .stat-row (Escuela) no traía variante oscura — solo se había usado hasta
   ahora sobre fondo claro. Mismos tokens que .stage-dark para la cifra
   (turquesa) y la etiqueta (on-dark-secundario). */
.page-hero-photo .stat-row-num{ color: var(--turquesa); }
.page-hero-photo .stat-row-item p{ color: var(--on-dark-secundario); }
@media (max-width: 640px){
  .page-hero-photo{ min-height: 340px; }
}
@media (max-width: 860px) and (max-height: 500px) and (orientation: landscape){
  /* Sin este ajuste, min-height:420px en una pantalla apaisada de poca
     altura deja el título fuera de la vista antes de hacer scroll — mismo
     bug ya arreglado para .page-hero-split-media, aquí en .page-hero-photo,
     usada en el-club/equipo-tecnico/team. */
  .page-hero-photo{ min-height: 200px; }
}

/* Variante para fotos de grupo numeroso (el-club): a min-height:420px con
   un encuadre alto (center 38%) se cortaba la fila sentada de delante y, en
   móvil, el ancho recortaba el banner de la izquierda. Más alto + recorte
   centrado deja ver el grupo completo. */
.page-hero-photo-tall{ min-height: 560px; }
.page-hero-photo-tall .page-hero-bg img{ object-position: center 50%; }
/* 0.22→0.70 dejaba puntos del suelo/pared del gimnasio con brillos casi
   blancos bajo el título en móvil (recorte 30% 55%), con contraste real
   de solo 3.08:1 en el peor píxel. Reforzado para garantizar ≥5:1 incluso
   contra esos brillos, medido con canvas sobre el recorte real. */
.page-hero-photo-tall .page-hero-scrim{ background: linear-gradient(180deg, rgba(11,12,14,0.45) 0%, rgba(11,12,14,0.87) 100%); }
@media (max-width: 860px){
  .page-hero-photo-tall{ min-height: 400px; }
  .page-hero-photo-tall .page-hero-bg img{ object-position: 30% 55%; }
}
@media (max-width: 480px){
  .page-hero-photo-tall{ min-height: 320px; }
}

/* Bloque partido imagen + texto, dentro de .content-inner */
.split-block{
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: 56px;
  align-items: center;
}
.split-block-media{
  border-radius: var(--radius-lg);
  overflow: hidden;
  align-self: stretch;
}
.split-block-media img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.split-block-text > *:first-child{ margin-top: 0; }
.split-block-text p{ max-width: 60ch; }
.team-cifras-photo{ object-position: center 35%; }
@media (max-width: 860px){
  .split-block{ grid-template-columns: 1fr; gap: 28px; }
  .split-block-media{ order: -1; max-height: 420px; }
  /* Escuela "Qué necesitas": aquí el texto responde la pregunta y la foto
     solo la confirma, así que en móvil se queda debajo en vez de saltar
     arriba como en el resto de .split-block. */
  .split-block-media-end{ order: 0; max-height: 280px; }
}

/* Variante del split-block para mostrar una marca/símbolo sobre una tarjeta oscura */
.split-block-media-mark{
  background: var(--negro-pista);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px;
  min-height: 320px;
}
.split-block-media-mark img{
  width: auto;
  height: auto;
  max-width: 52%;
  max-height: 280px;
  object-fit: contain;
}
@media (max-width: 860px){
  .split-block-media-mark{ min-height: 220px; padding: 32px; }
  .split-block-media-mark img{ max-width: 40%; max-height: 180px; }
}

/* Franja fotográfica a sangre, con leyenda breve */
.photo-band{
  position: relative;
  overflow: hidden;
  height: 440px;
}
.photo-band img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 25%;
}
.photo-band img.photo-band-img-low{ object-position: center 74%; }
.photo-band img.photo-band-img-skate{ object-position: center 58%; }
.photo-band img.photo-band-img-club{ object-position: center 74%; }
/* photo-band-tall (el-club.html): a 440px de alto, cover recorta verticalmente
   tanto que solo cabían patines O entrenadora, nunca ambos (patín cortado
   arriba, pies de la entrenadora cortados abajo). A 620px se ve más rango
   vertical de la foto — ambos patines con margen y la entrenadora casi
   entera. En móvil (<=640px) el contenedor ya es más ancho que alto respecto
   a la foto, así que cover encaja por altura y se ve el 100% vertical sin
   necesidad de este alto extra; la media query de abajo restaura 320px ahí
   (mismo orden/especificidad que .photo-band, gana por ir después). */
.photo-band-tall{ height: 620px; }
.wipe-reveal{
  /* Barrido a 16° — el filo de un patín, no una cortina recta. Sigue siendo
     una `transition` (no @keyframes) a propósito: el cleanup de will-change
     en script.js escucha `transitionend`, que una animación por keyframes
     no dispara. Mismo número de puntos en ambos estados para que el propio
     navegador interpole el polígono sin saltos. */
  -webkit-clip-path: polygon(0 0, 0% 0, -16% 100%, 0 100%);
  clip-path: polygon(0 0, 0% 0, -16% 100%, 0 100%);
  transition: -webkit-clip-path var(--dur-arrival) var(--ease-glide), clip-path var(--dur-arrival) var(--ease-glide);
  /* will-change se aplica solo durante la transición vía JS (ver script.js),
     no aquí: dejarlo puesto en reposo reserva una capa de composición para
     una animación de un solo uso que no vuelve a ejecutarse en esa carga. */
}
.wipe-reveal.in-view{
  -webkit-clip-path: polygon(0 0, 116% 0, 100% 100%, 0 100%);
  clip-path: polygon(0 0, 116% 0, 100% 100%, 0 100%);
}
@media (prefers-reduced-motion: reduce){
  .wipe-reveal{ -webkit-clip-path: none; clip-path: none; transition: none; }
}
.photo-band-scrim{
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11,12,14,0) 35%, rgba(11,12,14,0.8) 100%);
}
.photo-band-caption{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 24px 32px;
}
.photo-band-caption p{
  color: var(--blanco);
  font-family: var(--font-display);
  font-size: clamp(20px, 2.6vw, 30px);
  text-transform: uppercase;
  line-height: 1.25;
  margin: 0;
  max-width: 640px;
}
@media (max-width: 640px){
  .photo-band{ height: 320px; }
}

#filosofia ~ p{ max-width: 60ch; }
#necesitas ~ p{ max-width: 60ch; }

.values-grid{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
  margin-top: 12px;
  perspective: 900px;
}
.values-grid.values-grid-3{ grid-template-columns: repeat(3, 1fr); }
@media (max-width: 860px){
  .values-grid.values-grid-3{ grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px){
  .values-grid.values-grid-3{ grid-template-columns: 1fr; }
}
.value-card{
  position: relative;
  border: 1px solid var(--linea);
  border-radius: var(--radius-md);
  padding: 24px;
  opacity: 0;
  transform-style: preserve-3d;
  transition: opacity .5s cubic-bezier(0.16, 1, 0.3, 1), transform var(--dur-nudge) var(--ease-carve), border-color .15s ease, box-shadow .15s ease;
}
/* La tarjeta entera ya se ilumina al pasar el ratón, pero hasta ahora solo
   el texto del enlace (~20px, sin padding) era clicable de verdad — un
   objetivo táctil por debajo de 44×44pt en una zona que parece tocable
   entera. El enlace se estira para cubrir toda la tarjeta ("stretched
   link"), conservando un único enlace accesible en vez de duplicar el
   área en varios elementos. */
.value-card .link-arrow::after{
  content: "";
  position: absolute;
  inset: 0;
}
.reveal.in-view .value-card{ opacity: 1; }
.value-card:hover{
  transform: translateY(-3px);
  border-color: var(--turquesa);
  box-shadow: 0 8px 20px rgba(0,0,0,0.08);
}
.value-card:nth-child(2){ transition-delay: .06s, 0s, 0s, 0s; }
.value-card:nth-child(3){ transition-delay: .12s, 0s, 0s, 0s; }
.value-card:nth-child(4){ transition-delay: .18s, 0s, 0s, 0s; }
.value-card:nth-child(n+5){ transition-delay: .24s, 0s, 0s, 0s; }
/* Variante con foto — tira la imagen a los bordes de la tarjeta con margen
   negativo en vez de restructurar .value-card en header/body, para no
   afectar ninguno de sus otros usos en el sitio. */
.value-card-photo{ overflow: hidden; }
.value-card-photo img{
  display: block;
  width: calc(100% + 48px);
  max-width: calc(100% + 48px); /* el reset global img{max-width:100%} si no, gana sobre width y deja 49px sin sangrar en el borde derecho */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  margin: -24px -24px 16px;
}
.value-num{
  display: block;
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--azul);
  margin-bottom: 10px;
}
.value-card h3,
.value-card h4{
  font-family: var(--font-display);
  font-size: 20px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--negro);
  margin: 0 0 10px;
}
.value-card p{ font-size: 15.5px; line-height: 1.5; margin: 0; max-width: none; }

/* ubicaciones.html agrupa sus 9 tarjetas en 2 zonas geográficas (Madrid
   capital / fuera de la capital) en vez de un único muro de 9 — h3 aquí,
   no h2, porque agrupa contenido bajo el h2 "Dónde entrenamos" de la
   sección; los nombres de sede pasan a h4 dentro de cada zona para no
   saltarse ningún nivel. */
.location-zone-label{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 20px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--azul);
  margin: 0 0 16px;
}
.location-zone-label-next{
  margin-top: 40px;
  padding-top: 32px;
  border-top: 1px solid var(--linea);
}

.location-days{ display: flex; gap: 6px; margin-bottom: 18px; }
.day-dot{
  width: 27px;
  height: 27px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--papel-2);
  color: var(--gris-oscuro);
  font-size: 11px;
  font-weight: 700;
}
.content-block-dark .day-dot{ background: rgba(255,255,255,0.08); color: var(--on-dark-tenue); }
.day-dot.is-active{ background: var(--turquesa); color: var(--negro); }
@media (max-width: 640px){
  .values-grid{ grid-template-columns: 1fr; }
  /* .stage-stats con flex-wrap deja "huérfano" el 3er ítem en su propia
     fila con mucho hueco muerto al lado cuando las etiquetas son cortas
     (verificado: El Club, "9"/"2018"/"RFEP"). No se aplica a .stage-stats
     en general porque las etiquetas de Team en la home ("Competiciones
     internacionales") son demasiado largas para 3 columnas iguales sin
     partirse peor — de ahí el modificador aparte, no el cambio global. */
  .stage-stats-compact{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px 10px; }
}

/* Disciplinas del inline freestyle — acordeón agrupado por familia */
.discipline-list{
  margin-top: 28px;
  border-top: 1px solid var(--linea);
}
.discipline-item{ border-bottom: 1px solid var(--linea); }
.discipline-summary{
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 4px;
  cursor: pointer;
  list-style: none;
  transition: background-color .15s ease;
}
.discipline-summary::-webkit-details-marker{ display: none; }
.discipline-summary:hover{ background: var(--papel-2); }
.content-block-tint .discipline-summary:hover{ background: var(--papel); }
/* :active repite el mismo feedback que :hover para pantallas táctiles, que
   no tienen hover — esta fila es ahora el control interactivo principal
   de la página, no una decoración, así que el toque necesita respuesta. */
.discipline-summary:active{ background: var(--papel-2); }
.content-block-tint .discipline-summary:active{ background: var(--papel); }
.discipline-summary:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: -2px; border-radius: var(--radius-sm); }
.discipline-thumb{
  flex-shrink: 0;
  width: 54px;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-md);
  background: var(--papel-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--linea);
  overflow: hidden;
}
.discipline-thumb img{ width: 100%; height: 100%; object-fit: cover; }
.discipline-thumb svg{ width: 24px; height: 24px; }
/* object-position por disciplina: todas las fotos son horizontales sobre un
   hueco vertical, así que object-fit:cover siempre muestra el alto completo
   y solo recorta a los lados — el % aquí es el centro horizontal medido a
   ojo sobre cada patinador en la foto original. */
.discipline-img-classic-solo{ object-position: 42% center; }
.discipline-img-speed{ object-position: 45% center; }
.discipline-img-battle{ object-position: 49% center; }
.discipline-img-classic-parejas{ object-position: 44% center; }
.discipline-img-salto{ object-position: 47% center; }
.discipline-img-derrapes{ object-position: 48% center; }
.discipline-img-skate-cross{ object-position: 55% center; }
.discipline-img-pump-track{ object-position: 50% center; }
.discipline-img-team-speed{ object-position: 40% center; }
.discipline-img-team-battle{ object-position: 35% center; }
.discipline-img-team-cross{ object-position: 22% center; }
.discipline-img-ligas{ object-position: 5% center; }
.discipline-summary-main{
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.discipline-summary-top{
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.discipline-summary-name{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 19px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--negro);
  margin: 0;
}
.discipline-summary-teaser{
  margin: 0;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.4;
  color: var(--gris-oscuro);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* min-height reserva siempre 2 líneas, aunque el texto real solo ocupe
     una — así todas las filas del acordeón miden lo mismo, corto o largo. */
  min-height: calc(1.4em * 2);
}
.gear-tag{
  display: inline-block;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--azul);
  color: var(--blanco);
  white-space: nowrap;
}
.gear-tag-short{ display: none; }
@media (max-width: 480px){
  /* En 375px, "Equipación obligatoria" completo no cabe junto al nombre y
     provoca que la fila se parta en dos líneas solo en estos 3 elementos,
     rompiendo la altura uniforme del resto del acordeón. */
  .gear-tag-full{ display: none; }
  .gear-tag-short{ display: inline-block; }
}
.discipline-chevron{
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--gris-oscuro);
  transition: transform .2s ease;
}
.discipline-item[open] .discipline-chevron{ transform: rotate(180deg); }
.discipline-detail{
  padding: 4px 4px 28px;
  display: grid;
  grid-template-columns: 200px minmax(0, 560px);
  gap: 32px;
  align-items: start;
}
.discipline-detail-media{
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 2 / 3;
  background: var(--papel-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--linea);
}
.discipline-detail-media img{ width: 100%; height: 100%; object-fit: cover; }
.discipline-detail-media svg{ width: 48px; height: 48px; }
.discipline-facts{
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.discipline-fact dt{
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--azul);
  margin: 0 0 6px;
}
.discipline-fact dd{
  margin: 0;
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--gris-oscuro);
  /* Techo de seguridad: en la práctica el ancho real lo marca la columna
     del grid (200px minmax(0,560px)), más estrecha que esto a cualquier
     tamaño actual — este valor solo evita líneas excesivas si esa columna
     cambia en el futuro. */
  max-width: 46ch;
}
@media (max-width: 640px){
  .discipline-summary{ gap: 14px; }
  .discipline-thumb{ width: 44px; }
  .discipline-summary-name{ font-size: 17px; }
  .discipline-detail{ grid-template-columns: 1fr; gap: 16px; padding: 0 4px 24px; }
  /* El texto (Qué es/Qué se valora) va primero en móvil: es la respuesta que
     se busca al abrir la ficha, la foto es de apoyo, no al revés. */
  .discipline-facts{ order: 1; }
  .discipline-detail-media{ order: 2; width: 160px; max-width: 45vw; }
}

.levels-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin-top: 12px;
}
@media (max-width: 780px){
  .levels-grid{ grid-template-columns: 1fr; }
}
/* horarios-tarifas.html reutiliza .levels-grid pero con solo 3 tarjetas
   simples (h3 + 1-2 líneas + enlace) — sin la fila de 7 círculos de día
   que tienen las 9 tarjetas de ubicaciones.html, que sí necesita romper
   a 1 columna en 780px. Medido en vivo con las tarjetas reales de esta
   página: a tablet portrait (768px, iPad) 1 columna deja una tarjeta de
   705px con un vacío enorme a la derecha; 3 columnas de hasta ~180px
   (probado en 640px y 560px) se siguen leyendo bien. Este modificador
   reabre 3 columnas hasta 641px, sin tocar el breakpoint de 780px que
   ubicaciones.html sí necesita. */
@media (min-width: 641px) and (max-width: 780px){
  .levels-grid-compact{ grid-template-columns: repeat(3, 1fr); }
  /* Las tarjetas de ubicaciones.html sí llevan la fila de 7 círculos de
     día (necesita ≥225px), así que reabren solo 2 columnas en este rango,
     no 3 — verificado en vivo a 768px y 700px. */
  .levels-grid-locations{ grid-template-columns: repeat(2, 1fr); }
}
/* Reaseguro para quien no sabe qué "nivel" o "especialidad combinada" le
   corresponde antes de repartirle en 3 subpáginas — sin esto, nada en la
   página responde a esa duda. */
.levels-grid-help{
  margin: 20px 0 0;
  font-size: 14px;
  color: var(--gris-oscuro);
}
.levels-grid-help a{ font-weight: 700; color: var(--azul); }
.levels-grid-help a:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; border-radius: 2px; }

/* Timeline dinámica — línea central con hitos alternados */
.timeline-dynamic{
  position: relative;
  list-style: none;
  margin: 48px 0 0;
  padding: 0;
}
.timeline-dynamic::before{
  content: "";
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 50%;
  width: 2px;
  background: var(--linea);
  transform: translateX(-50%);
}
.timeline-dynamic-item{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-height: 64px;
  padding-bottom: 40px;
}
.timeline-dynamic-item:last-child{ padding-bottom: 0; }
.timeline-dynamic-item:nth-child(even){ justify-content: flex-start; }
.timeline-dynamic-year{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 60px;
  height: 60px;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: var(--azul);
  color: var(--blanco);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 20px;
  box-shadow: 0 0 0 6px var(--papel-2);
  z-index: 1;
}
.timeline-dynamic-card{
  width: calc(50% - 48px);
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radius-md);
  padding: 20px 24px;
}
.timeline-dynamic-card p{ margin: 0; font-size: 15px; line-height: 1.6; color: var(--gris-oscuro); }
@media (max-width: 720px){
  .timeline-dynamic::before{ left: 24px; }
  .timeline-dynamic-item,
  .timeline-dynamic-item:nth-child(even){ justify-content: flex-start; padding-left: 64px; }
  .timeline-dynamic-year{ left: 24px; width: 48px; height: 48px; font-size: 18px; box-shadow: 0 0 0 4px var(--papel-2); }
  .timeline-dynamic-card{ width: 100%; }
}

.club-cta{ text-align: left; }
.club-cta .content-inner p{ max-width: 60ch; margin-bottom: 28px; }
.content-block-dark-tint .content-inner > p:not(.eyebrow){ max-width: 60ch; }

.content-inner-wide{ max-width: var(--max-w); margin: 0 auto; }

.schedule-note{
  max-width: 70ch;
  font-size: 13px;
  font-weight: 600;
  color: var(--gris-oscuro);
  opacity: 0.75;
  margin: -8px 0 28px;
}
.schedule-note:has(a){ opacity: 1; }
.schedule-note a{ color: var(--azul); text-decoration: underline; }
.schedule-note a:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; border-radius: 2px; }
.schedule-day{
  padding: 30px 32px;
  border: 1px solid var(--linea);
  border-radius: var(--radius-lg);
  margin-bottom: 18px;
  background: var(--blanco);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.schedule-day:last-child{ margin-bottom: 0; }
.schedule-day:hover{ border-color: var(--turquesa); box-shadow: 0 10px 28px rgba(0,0,0,0.06); }
.schedule-day:has(.schedule-day-title.is-today){ border-color: var(--turquesa); }
.schedule-day-title{
  display: flex;
  align-items: baseline;
  gap: 18px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(20px, 2.6vw, 26px);
  text-transform: uppercase;
  color: var(--negro);
  margin: 0 0 18px;
}
.schedule-day-title::after{
  content: "";
  flex: 1;
  height: 1px;
  background: var(--linea);
}
.today-tag{
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blanco);
  background: var(--azul);
  padding: 3px 10px;
  border-radius: var(--radius-pill);
}
.schedule-row{
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 13px 10px;
  margin: 0 -10px;
  border-radius: var(--radius-sm);
  transition: background .15s ease;
}
.schedule-row:hover{ background: rgba(0,0,0,0.035); }
.schedule-day .schedule-row{ border-bottom: 1px solid var(--linea); }
.schedule-day .schedule-row:last-child{ border-bottom: none; }
.schedule-location{
  flex: 0 0 250px;
  white-space: nowrap;
  font-weight: 700;
  font-size: 15.5px;
  color: var(--negro);
}
.schedule-time{
  flex: 0 0 170px;
  white-space: nowrap;
  font-family: var(--font-display);
  font-size: 13.5px;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--azul);
  background: rgba(0,176,224,0.12);
  border-radius: var(--radius-pill);
  padding: 6px 12px;
}
.schedule-activity{
  flex: 1;
  font-size: 15.5px;
  color: var(--gris-oscuro);
}
/* El layout de fila fija (ubicación 250px + hora 170px) necesita sitio real
   para la tercera columna (actividad) — por debajo de ~820px la exprime a
   una franja de 1-2 palabras y el texto más largo ("Speed, derrapes, salto
   y slalom") se parte en 3-4 líneas. El corte a columna apilada se movía
   antes en 640px, un umbral pensado antes de fijar el ancho de esas dos
   columnas; ahora el contenido necesita romper más arriba, así que el
   breakpoint sube con él en vez de dejar una franja intermedia rota. */
@media (max-width: 820px){
  .schedule-day{ padding: 22px 20px; }
  .sede-panel{ padding: 22px 20px; }
  .schedule-day-title{ margin-bottom: 14px; }
  .schedule-row{ flex-direction: column; align-items: flex-start; gap: 7px; padding: 14px 10px; }
  .schedule-time{ order: -1; flex: 0 0 auto; }
  .schedule-location{ flex: 0 0 auto; }
}

.sedes-list{
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
}
.sede-tag{
  display: inline-block;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  padding: 14px 18px;
  border: 1px solid var(--linea);
  border-radius: var(--radius-pill);
  color: var(--gris-oscuro);
  background: none;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease, transform .15s ease;
}
.sede-tag:hover{ border-color: var(--azul); color: var(--azul); transform: translateY(-1px); }
.sede-tag:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
.sede-tag.is-active{ background: var(--azul); border-color: var(--azul); color: var(--blanco); }
.sede-tag.is-active:hover{ color: var(--blanco); }

.sede-panels{ margin-top: 24px; }
.sede-panel{
  display: none;
  padding: 30px 32px;
  border: 1px solid var(--linea);
  border-radius: var(--radius-lg);
  background: var(--blanco);
}
.sede-panel.is-active{ display: block; animation: sedePanelIn .25s ease; }
.sede-panel .schedule-row{ border-bottom: 1px solid var(--linea); }
.sede-panel .schedule-row:last-child{ border-bottom: none; }
/* .disc-panel reutiliza el mismo componente visual que .sede-panel (misma
   clase aplicada dos veces en el HTML) — .disc-tag/.disc-panel son solo el
   gancho que usa el JS del filtro de disciplina, sin CSS propio, para no
   arriesgar el filtro de sede ya existente. La única diferencia real es esta:
   aquí .schedule-location lleva "Día · Sede" en vez de uno de los dos, así
   que necesita más ancho y poder partirse en dos líneas — a diferencia de
   los paneles de sede (donde solo hay un día, siempre corto) esto puede
   medir hasta "Viernes · Torrejón del Rey (Guadalajara)". */
.disc-panel .schedule-location{ flex-basis: 320px; white-space: normal; line-height: 1.3; }
@media (max-width: 820px){
  .disc-panel .schedule-location{ flex-basis: auto; }
}
@keyframes sedePanelIn{
  from{ opacity: 0; }
  to{ opacity: 1; }
}

/* Tarifas */
.price-list{
  max-width: 640px;
  margin-top: 16px;
  border: 1px solid var(--linea);
  border-radius: var(--radius-lg);
  padding: 4px 28px;
  background: var(--blanco);
}
.price-row{
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 18px 0;
  border-top: 1px solid var(--linea);
}
.price-row:first-child{ border-top: none; }
.price-name{ font-weight: 600; font-size: 16px; color: var(--negro); }
.price-value{
  font-family: var(--font-display);
  font-size: 20px;
  color: var(--azul);
  white-space: nowrap;
}

.price-table-wrap{
  overflow-x: auto;
  margin-top: 16px;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--linea);
  border-radius: var(--radius-lg);
  padding: 8px;
}
.price-table-wrap:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
.price-table{ width: 100%; border-collapse: collapse; min-width: 520px; }
.price-table th, .price-table td{
  padding: 16px 18px;
  text-align: center;
  border-bottom: 1px solid var(--linea);
  font-size: 15px;
}
.price-table thead th{
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blanco);
  background: var(--azul);
  border-bottom: none;
}
.price-table tbody tr:nth-child(even){ background: var(--papel-2); }
.price-table tbody tr{ transition: background .15s ease; }
.price-table tbody tr:hover{ background: rgba(0,176,224,0.1); }
.price-table tbody tr:last-child td{ border-bottom: none; }
.price-table td:first-child, .price-table th:first-child{
  text-align: left;
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--blanco);
}
.price-table td:first-child, .price-table tbody th:first-child{ font-weight: 700; color: var(--negro); }
.price-table thead th:first-child{ background: var(--azul); }
.price-table tbody tr:nth-child(even) td:first-child,
.price-table tbody tr:nth-child(even) th:first-child{ background: var(--papel-2); }
.price-table-hint{ display: none; }
@media (max-width: 640px){
  /* La tabla tiene min-width:520px y no cabe entera en móvil (confirmado
     en critique: 580px de contenido vs ~325px visibles) — sin esta pista
     nada indica que hay más columnas a la derecha. */
  .price-table-hint{
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 10px 2px 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--gris-oscuro);
  }
  .price-table-hint .link-arrow-glyph{ color: var(--azul); }
}
.price-table td.price-value-cell{ font-family: var(--font-display); font-size: 16px; color: var(--azul); }
/* --linea es un token de borde (rgba(215,215,215,0.6)), no de texto — a
   1.26:1 sobre el fondo de la tabla era casi invisible (WCAG 1.4.3 exige
   4.5:1). --gris-oscuro a 0.75 de opacidad mantiene la jerarquía "esto no
   aplica" sin perder legibilidad real. */
.price-table td.price-empty{ color: var(--gris-oscuro); opacity: 0.75; }

.flat-rate-card{
  position: relative;
  overflow: hidden;
  border: none;
  border-radius: var(--radius-lg);
  padding: 48px 40px;
  text-align: center;
  max-width: 480px;
  margin: 16px auto 0;
  background: var(--negro-pista);
}
.flat-rate-card > *{ position: relative; }
.flat-rate-card .path-tag{ margin-bottom: 18px; }
.flat-rate-card .flat-rate-price{
  font-family: var(--font-display);
  /* Mismo coeficiente vw que .page-hero-title (clamp(36px,5.5vw,56px)) +
     4px fijos, para que el precio se mantenga ~1.1x el H1 de la página en
     vez de disparar el ratio en el tramo 600-820px donde antes las dos
     curvas divergían (llegó a pesar 1.56x el H1 con un 9vw suelto). */
  font-size: clamp(40px, 5.5vw + 4px, 56px);
  color: var(--turquesa);
  margin: 14px 0 4px;
}
.flat-rate-card .flat-rate-note{ font-size: 14.5px; color: var(--on-dark-secundario); margin: 0 0 10px; }
.flat-rate-card .flat-rate-compare{ font-size: 13px; font-weight: 700; color: var(--turquesa); margin: 0 0 24px; }
@media (max-width: 640px){
  .flat-rate-card{ padding: 36px 26px; }
  .flat-rate-card::before{ font-size: 180px; right: -10px; bottom: -40px; }
}

/* Formulario de contacto */
.contact-form{
  max-width: 640px;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.form-row{ display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
/* min-width:0 anula el mínimo implícito de un item de grid/flex, que por
   defecto es el ancho de su contenido — sin esto, el <select> de
   "Experiencia previa" (su opción más larga, "Sin experiencia — primera vez
   sobre patines", fija ese mínimo) obligaba a toda la columna a ensancharse
   y el formulario se salía del modal en viewports estrechos. */
.form-group{ display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.form-group label{ font-size: 13px; font-weight: 700; color: var(--negro); }
/* --azul, no --turquesa: el asterisco es texto real (WCAG 1.4.3, mínimo
   4.5:1), no un indicador de UI — turquesa sobre fondo claro solo da 2.53:1
   (mismo motivo que .link-arrow:focus-visible y el foco de .form-group más
   arriba). */
.form-required{ color: var(--azul); }
.form-group input,
.form-group select,
.form-group textarea{
  width: 100%;
  min-width: 0;
  font-family: var(--font-body);
  font-size: 16px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: var(--radius-sm);
  background: var(--blanco);
  color: var(--negro);
  transition: border-color .15s ease, outline-color .15s ease;
}
/* Safari en iOS ignora width:100% en input[type=date] y lo dimensiona a su
   ancho de contenido nativo (día/mes/año + icono) vía -webkit-min-logical-
   width interno — por eso "Fecha de nacimiento" se salía del modal solo en
   iPhone, aunque el resto de campos ya respetaban el ancho del contenedor. */
.form-group input[type="date"]{ -webkit-min-logical-width: 0; }
/* Foco en --azul, no --turquesa: --turquesa sobre fondo claro mide ~2.5:1,
   por debajo del mínimo 3:1 de WCAG 2.2 §1.4.11 para indicadores de foco
   (mismo motivo ya documentado en .link-arrow:focus-visible más arriba). */
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus{
  outline: 2px solid var(--azul);
  outline-offset: 1px;
  border-color: var(--azul);
}
.form-group textarea{ resize: vertical; min-height: 110px; }
.form-honeypot{ display: none; }
.contact-form .form-feedback{ font-size: 14px; font-weight: 600; margin: 12px 0 0; max-width: none; }
.form-feedback.is-success{ color: var(--azul); }
.form-feedback.is-error{ color: var(--error); }

.contact-form .form-error{ font-size: 13px; font-weight: 600; color: var(--error); margin: 0; max-width: none; }
.form-group input.is-invalid,
.form-group select.is-invalid{ border-color: var(--error); }
.form-group input.is-invalid:focus,
.form-group select.is-invalid:focus{ outline-color: var(--error); border-color: var(--error); }

/* padding vertical para que el objetivo táctil de la casilla de privacidad
   llegue a 44px de alto (antes ~22px en una línea) sin tocar el punto de
   alineación (flex-start) que ya funciona bien cuando el texto envuelve. */
.form-group .form-checkbox-label{
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--gris-oscuro);
  cursor: pointer;
}
.form-checkbox-label input[type="checkbox"]{
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  accent-color: var(--turquesa);
}
.form-checkbox-label a{ color: var(--azul); font-weight: 700; }
.form-checkbox-label a:hover{ color: var(--turquesa); }

@media (max-width: 640px){
  .form-row{ grid-template-columns: 1fr; }
}

.calendar-list{
  list-style: none;
  margin: 16px 0 0;
  border: 1px solid var(--linea);
  border-radius: var(--radius-lg);
  padding: 4px 28px;
  background: var(--blanco);
}
.calendar-row{
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  padding: 16px 10px;
  margin: 0 -10px;
  border-top: 1px solid var(--linea);
  border-radius: var(--radius-sm);
  transition: background .15s ease;
}
.calendar-row:hover{ background: rgba(0,0,0,0.035); }
.calendar-row:first-child{ border-top: none; }
.calendar-row-next{ background: rgba(0,176,224,0.06); }
/* :hover (0,2,0) le gana a .calendar-row-next (0,1,0) sin este empate de especificidad. */
.calendar-row.calendar-row-next:hover{ background: rgba(0,176,224,0.1); }
.calendar-details{
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.calendar-details-top{
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.calendar-name{
  font-weight: 700;
  font-size: 15.5px;
  color: var(--negro);
}
/* Solo se renderiza cuando la fila tiene data-location real (sin sedes inventadas).
   Nota de diseño: hoy coincide con la fila "Próxima" (única con sede confirmada);
   al añadir más sedes, evitar que "próxima" y "tiene sede" queden siempre acopladas
   — el objetivo es más información, no una fila que además parezca más importante. */
.calendar-location{
  font-size: 12.5px;
  color: var(--gris-oscuro);
  opacity: 0.75;
}
.calendar-date{
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13.5px;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--azul);
  background: rgba(0,176,224,0.12);
  border-radius: var(--radius-pill);
  padding: 6px 14px;
  white-space: nowrap;
  text-align: center;
}
.calendar-note{
  font-size: 13px;
  font-weight: 600;
  color: var(--gris-oscuro);
  opacity: 0.75;
  margin: 20px 0 0;
}
/* .calendar-note es <p>, así que .content-inner p le gana por especificidad
   (mismo patrón de bug ya visto varias veces esta sesión) — se restaura aquí. */
.content-inner .calendar-note{ font-size: 13px; line-height: normal; }
@media (max-width: 560px){
  .calendar-list{ padding: 4px 16px; }
  .calendar-row{ flex-direction: column; align-items: flex-start; gap: 8px; padding: 16px 10px; }
}

.content-block-dark .calendar-list{
  background: rgba(255,255,255,0.03);
  border-color: rgba(255,255,255,0.14);
}
.content-block-dark .calendar-row{ border-top-color: rgba(255,255,255,0.12); }
.content-block-dark .calendar-row:hover{ background: rgba(255,255,255,0.05); }
.content-block-dark .calendar-row-next{ background: rgba(0,176,224,0.08); }
.content-block-dark .calendar-row.calendar-row-next:hover{ background: rgba(0,176,224,0.1); }
.content-block-dark .calendar-name{ color: var(--blanco); }
.content-block-dark .calendar-location{ color: var(--on-dark-tenue); opacity: 1; }
.content-block-dark .calendar-date{
  color: var(--turquesa);
  background: rgba(0,176,224,0.16);
}
.content-block-dark .calendar-note{ color: var(--on-dark-tenue); opacity: 1; }
.content-block-dark .content-inner .calendar-note{ color: var(--on-dark-tenue); line-height: normal; letter-spacing: normal; }

/* Roster — Patinadores y Palmarés */
.roster-header{
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px 48px;
}
.roster-header-identity{ flex: 1 1 280px; }
.roster-header-controls{ flex: 0 1 400px; max-width: 400px; }
.roster-count{
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--on-dark-tenue);
  margin: 4px 0 20px;
}
.roster-search{
  display: block;
  width: 100%;
  max-width: 360px;
  font-family: var(--font-body);
  font-size: 16px;
  padding: 13px 18px;
  margin: 0 0 16px;
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.04);
  color: var(--blanco);
  -webkit-appearance: none;
  appearance: none;
}
.roster-search::placeholder{ color: var(--on-dark-tenue); }
.roster-search::-webkit-search-cancel-button{ filter: invert(1) opacity(0.6); }
.roster-search:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; border-color: var(--turquesa); }
.roster-empty-state{
  text-align: center;
  padding: 48px 20px;
  color: var(--on-dark-tenue);
  font-size: 14px;
}
.roster-filter-bar{
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 28px;
}
.roster-filter-btn{
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 13px 18px;
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: var(--radius-pill);
  background: none;
  color: var(--on-dark-secundario);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.roster-filter-btn:hover{ border-color: rgba(255,255,255,0.4); color: var(--blanco); }
.roster-filter-btn:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
.roster-filter-btn.is-active{
  background: var(--turquesa);
  border-color: var(--turquesa);
  color: var(--negro-pista);
}
.roster-header-cta{ margin: 24px 0 32px; }
.btn[disabled]{ opacity: 0.4; cursor: default; }
.roster-grid{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  margin-top: 12px;
}
.roster-card-flippable[hidden]{ display: none; }
.roster-card{
  border: 1px solid rgba(255,255,255,0.16);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-align: center;
  display: flex;
  flex-direction: column;
}
.roster-card-flippable{ perspective: 1400px; overflow: visible; }
.roster-flip-inner{
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1;
  transition: transform 0.6s cubic-bezier(0.4, 0.1, 0.2, 1);
  transform-style: preserve-3d;
}
.roster-card-flippable.is-flipped .roster-flip-inner{ transform: rotateY(180deg); }
.roster-flip-front,
.roster-flip-back{
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: var(--radius-md);
  overflow: hidden;
}
.roster-flip-front{ display: flex; flex-direction: column; flex: 1; }
.roster-card-flippable.is-flipped .roster-flip-front{ pointer-events: none; }
.roster-flip-back{
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  display: flex;
  flex-direction: column;
  background: var(--negro-pista);
  border: 1px solid rgba(255,255,255,0.16);
  text-align: left;
  pointer-events: none;
  cursor: pointer;
}
.roster-card-flippable.is-flipped .roster-flip-back{ pointer-events: auto; }
/* Sin borde de foco aquí ni en .roster-back-scroll: ambos llevan tabindex="-1"
   y solo reciben foco por script (backScroll.focus() en script.js), nunca
   tabulando de verdad — :focus-visible no tiene forma fiable de distinguir
   si ese foco programático viene de un clic con ratón o de Intro/Espacio con
   teclado en este patrón concreto, así que el borde aparecía a veces sí, a
   veces no, sin ningún patrón. El propio giro de la tarjeta ya es la señal
   visual de que el foco se ha movido; no hace falta un borde además. */
.roster-flip-back:focus-visible{ outline: none; }
.roster-flip-back::after{
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 26px;
  background: linear-gradient(0deg, var(--negro-pista), rgba(11,12,14,0));
  pointer-events: none;
}
.roster-photo-btn{
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  position: relative;
}
.roster-photo-btn:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: -2px; }
/* Ver comentario junto a photoBtn.classList.add('is-redirected-focus') en
   patinadores-y-palmares.html — desactiva el borde solo cuando el foco llega
   aquí redirigido desde el reverso de la tarjeta, no al tabular de verdad. */
.roster-photo-btn.is-redirected-focus:focus-visible{ outline: none; }
.roster-photo-btn::after{
  content: "Ver palmarés";
  position: absolute;
  inset: auto 0 0 0;
  padding: 8px 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--blanco);
  background: linear-gradient(0deg, rgba(0,0,0,0.72), rgba(0,0,0,0));
  opacity: 0;
  transition: opacity 0.15s ease;
}
.roster-photo-btn:hover::after,
.roster-photo-btn:focus-visible::after{ opacity: 1; }
/* En táctil no hay :hover, así que la pista de "tarjeta interactiva" debe
   verse siempre; si no, nada en la cara frontal indica que se puede tocar. */
@media (hover: none){
  .roster-photo-btn::after{ opacity: 1; }
}
.roster-back-scroll{
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px 16px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
/* Ver comentario junto a .roster-flip-back:focus-visible — mismo motivo. */
.roster-back-scroll:focus-visible{ outline: none; }
.roster-back-scroll::-webkit-scrollbar{ display: none; }
.roster-back-name{
  font-family: var(--font-display);
  font-size: 17px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--blanco);
  margin: 0 0 12px;
}
.roster-back-title{
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--turquesa);
  margin: 10px 0 6px;
}
.roster-back-title:first-of-type{ margin-top: 0; }
.roster-result-list{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.roster-result-row{
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.roster-result-row:last-child{ border-bottom: none; padding-bottom: 0; }
.roster-result-rank{
  flex: 0 0 auto;
  min-width: 30px;
  height: 30px;
  padding: 0 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 12px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255,255,255,0.25);
  color: var(--on-dark-secundario);
}
.roster-result-row-gold .roster-result-rank{
  background: var(--oro);
  border-color: var(--oro);
  color: var(--negro-pista);
}
.roster-result-row-silver .roster-result-rank{
  background: var(--plata);
  border-color: var(--plata);
  color: var(--negro-pista);
}
.roster-result-row-bronze .roster-result-rank{
  background: var(--bronce);
  border-color: var(--bronce);
  color: var(--negro-pista);
}
.roster-result-detail{
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.roster-result-comp{
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--blanco);
}
.roster-result-meta{
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--on-dark-secundario);
}
.roster-mark-grid{
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.roster-mark-card{
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
}
.roster-mark-discipline{
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--turquesa);
  margin: 0 0 4px;
}
.roster-mark-value{
  font-family: var(--font-display);
  font-size: 1.6rem;
  line-height: 1;
  color: var(--blanco);
  margin: 0;
}
.roster-mark-unit{
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--on-dark-secundario);
  margin-left: 4px;
}
.roster-mark-context{
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--on-dark-secundario);
  margin: 3px 0 0;
}
.roster-photo{
  aspect-ratio: 4 / 5;
  background: rgba(255,255,255,0.06);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-dark-tenue);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
img.roster-photo{
  width: 100%;
  object-fit: cover;
}
.roster-body{
  padding: 16px 14px 18px;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.roster-name{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 17px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--blanco);
  margin: 0 0 10px;
}
.roster-disciplines{
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 6px;
  justify-content: center;
  min-height: 53px;
  margin: 0 0 16px;
}
.roster-discipline-tag{
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 4px 9px;
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: var(--radius-pill);
  color: var(--on-dark-secundario);
}
@media (max-width: 1100px){
  .roster-grid{ grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 900px){
  .roster-grid{ grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px){
  .roster-grid{ grid-template-columns: 1fr; }
}

/* Ranking Interno — top 3 por disciplina, generado desde el palmarés de cada patinador */
.ranking-grid{
  display: flex;
  flex-direction: column;
  gap: 32px;
  margin-top: 36px;
}
.ranking-discipline-title{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.3rem;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--blanco);
  margin: 0 0 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
  position: relative;
}
.ranking-discipline-title::after{
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 40px;
  height: 3px;
  background: var(--turquesa);
}
.ranking-gender-grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(460px, 100%), 1fr));
  gap: 20px;
}
.ranking-gender-card{
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: var(--radius-lg);
  padding: 20px 22px 8px;
}
.ranking-gender-label{
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-dark-tenue);
  margin: 0 0 10px;
}
.ranking-list{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.ranking-row-btn{
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 13px 8px;
  margin: 0 -8px;
  border: 0;
  border-bottom: 1px solid rgba(255,255,255,0.07);
  background: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: left;
  transition: background-color 0.15s ease;
}
.ranking-row:last-child .ranking-row-btn{ border-bottom: 0; }
.ranking-row-btn:hover,
.ranking-row-btn:focus-visible{ background: rgba(255,255,255,0.07); }
.ranking-row-btn:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: -2px; }
.ranking-row-top .ranking-row-btn{ background: linear-gradient(90deg, rgba(217,180,74,0.14), rgba(217,180,74,0)); }
.ranking-row-top .ranking-row-btn:hover,
.ranking-row-top .ranking-row-btn:focus-visible{ background: linear-gradient(90deg, rgba(217,180,74,0.22), rgba(217,180,74,0.03)); }
.ranking-rank{
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 14px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.25);
  color: var(--on-dark-secundario);
}
.ranking-rank.is-gold{ background: var(--oro); border-color: var(--oro); color: var(--negro-pista); }
.ranking-rank.is-silver{ background: var(--plata); border-color: var(--plata); color: var(--negro-pista); }
.ranking-rank.is-bronze{ background: var(--bronce); border-color: var(--bronce); color: var(--negro-pista); }
.ranking-name{
  flex: 1;
  min-width: 0;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--blanco);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ranking-value{
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--turquesa);
}
.ranking-value .roster-mark-unit{ font-family: var(--font-body); font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--on-dark-secundario); margin-left: 3px; }
.ranking-empty{ font-size: 13px; color: var(--on-dark-tenue); padding: 10px 0; }
@media (max-width: 560px){
  .ranking-gender-card{ padding: 18px 16px 6px; }
  .ranking-value{ font-size: 1.25rem; }
  .ranking-name{ font-size: 14.5px; }
}

/* Resultados por equipos — ficha de competición (sub-marca Team) */
.team-results-grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  align-items: stretch;
  gap: 24px;
  margin-top: 8px;
}
/* Ligas de menor escala (autonómicas): en vez de estirar las tarjetas a
   pistas de rejilla tan anchas como las de las ligas nacionales — dejando
   huecos residuales a su derecha — se agrupan por su ancho de contenido
   real y se centran como conjunto. Tratamiento permanente: aunque estas
   tarjetas dejen de estar pendientes, la escala más ligera de la liga
   sigue mereciendo un formato más compacto que el de las nacionales. */
.team-results-grid-compact{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
@media (max-width: 1060px){
  .team-results-grid-compact{ flex-direction: column; align-items: center; }
}
.team-result-card{
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* Tope de ancho: en una fila con menos tarjetas que columnas disponibles
     (p.ej. las 2 de "Liga Autonómica" en la misma rejilla que las 3 de
     "Ligas Nacionales"), cada pista de grid crece igualmente y las tarjetas
     se estiran mucho más anchas que sus vecinas reales. Con este tope, la
     tarjeta se queda a su ancho natural dentro de una pista más amplia.
     max-width no cambia cuántas columnas caben (eso lo decide el grid). */
  max-width: 380px;
  background:
    linear-gradient(155deg, rgba(0,75,103,0.5) 0%, rgba(11,12,14,0) 55%),
    var(--negro-pista);
  border-top: 3px solid var(--turquesa);
  clip-path: polygon(0 0, calc(100% - 28px) 0, 100% 28px, 100% 100%, 0 100%);
}
.team-result-card-compact{ border-bottom: 3px solid var(--azul); }
.team-result-card-pending{ border-top-color: rgba(255,255,255,0.25); border-bottom-color: rgba(255,255,255,0.25); }
.team-result-card-pending .team-result-num{ font-size: 2rem; color: var(--on-dark-tenue); }
.team-results-grid + .eyebrow{ margin-top: 48px; }
.team-result-watermark{
  position: absolute;
  z-index: -1;
  right: 6px;
  bottom: 18px;
  height: calc(100% - 36px);
  width: auto;
  max-width: none;
  opacity: 0.07;
  transform: rotate(-8deg);
  transform-origin: bottom right;
  pointer-events: none;
  user-select: none;
}
.team-result-top{ position: relative; z-index: 0; padding: 30px 32px 34px; flex: 1; }
.team-result-card .team-result-name{
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 800;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--blanco);
  margin: 0;
  max-width: none;
  min-height: 2.6em;
}
.team-result-card .team-result-position{
  display: flex;
  align-items: baseline;
  gap: 3px;
  margin: 12px 0 0;
  max-width: none;
}
.team-result-num{
  font-family: var(--font-display);
  font-size: clamp(3.6rem, 7vw, 5.2rem);
  line-height: 0.85;
  color: var(--turquesa);
}
.team-result-num.is-gold{ color: var(--oro); }
.team-result-num.is-silver{ color: var(--plata); }
.team-result-num.is-bronze{ color: var(--bronce); }
.team-result-card .team-result-position-tag{
  font-size: 13px;
  font-weight: 700;
  line-height: 1.5;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--blanco);
  margin: 10px 0 0;
  max-width: none;
}
.team-result-card .team-result-label{
  font-size: 13px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--on-dark-secundario);
  margin: 16px 0 0;
  padding-top: 16px;
  border-top: 1px solid rgba(255,255,255,0.14);
  max-width: none;
}

.team-result-strip{
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 32px;
  background: var(--azul);
  border-top: 3px solid var(--azul);
}
.team-result-strip-text{
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--blanco);
}
.team-result-strip-num{
  display: flex;
  align-items: baseline;
  gap: 2px;
  flex-shrink: 0;
  font-family: var(--font-display);
  font-size: 1.7rem;
  line-height: 1;
  color: var(--blanco);
}
.team-result-strip-highlight{ background: var(--turquesa); }
.team-result-strip-highlight .team-result-strip-num,
.team-result-strip-highlight .team-result-strip-text{ color: var(--negro-pista); }
.team-result-strip-num.is-gold{ color: var(--oro); }
.team-result-strip-num.is-silver{ color: var(--plata); }
.team-result-strip-num.is-bronze{ color: var(--bronce); }
/* Ningún color de medalla pasa 3:1 como texto plano sobre el turquesa de la
   franja destacada (el oro mide 1,28:1; la plata y el bronce fallan igual).
   Aquí se convierte en una insignia circular con el color de medalla como
   fondo y texto oscuro encima — mismo patrón que .ranking-rank/.roster-result-rank
   en otras páginas, y accesible para cualquier metal, no solo el oro. */
.team-result-strip-highlight .team-result-strip-num.is-gold,
.team-result-strip-highlight .team-result-strip-num.is-silver,
.team-result-strip-highlight .team-result-strip-num.is-bronze{
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 1.5rem;
  color: var(--negro-pista);
}
.team-result-strip-highlight .team-result-strip-num.is-gold{ background: var(--oro); }
.team-result-strip-highlight .team-result-strip-num.is-silver{ background: var(--plata); }
.team-result-strip-highlight .team-result-strip-num.is-bronze{ background: var(--bronce); }

/* Por debajo de 1060px, 3 columnas de min. 320px ya no caben en el
   contenedor (max 1180px, 24px de padding a cada lado) y una tarjeta suelta
   queda huérfana en la fila 2 — se salta directo a 1 columna en vez de
   pasar por un estado de 2 columnas apretadas. */
@media (max-width: 1060px){
  .team-results-grid{ grid-template-columns: 1fr; }
  /* En columna única, sin este tope una tarjeta se estira a todo el ancho
     del contenedor (hasta 1011px) y su contenido queda apretado a la
     izquierda con una franja vacía enorme al lado — una tarjeta se limita
     a un ancho legible y se centra, en vez de convertirse en un banner. */
  .team-result-card{ max-width: 640px; margin-left: auto; margin-right: auto; }
}
@media (max-width: 480px){
  .team-result-top{ padding: 26px 24px 30px; }
  .team-result-strip{ padding: 14px 24px; }
}

.team-photo{
  flex-shrink: 0;
  aspect-ratio: 4 / 5;
  background: var(--papel-2);
  border-bottom: 1px solid var(--linea);
  color: var(--negro);
  opacity: 0.9;
  font-family: var(--font-display);
  font-size: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
}
img.team-photo{
  width: 100%;
  object-fit: cover;
  opacity: 1;
}

.team-featured-grid{
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.team-featured{
  display: flex;
  align-items: stretch;
  border: 1px solid var(--linea);
  border-radius: var(--radius-md);
  overflow: hidden;
  max-width: 620px;
  transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.team-featured-grid .team-featured{
  flex: 1 1 380px;
  max-width: calc(50% - 12px);
}
.team-featured:hover{
  transform: translateY(-3px);
  border-color: var(--turquesa);
  box-shadow: 0 8px 20px rgba(0,0,0,0.08);
}
.team-featured .team-photo{
  width: 240px;
  border-bottom: none;
  border-right: 1px solid var(--linea);
  font-size: 40px;
}
.team-featured-body{
  padding: 24px 28px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.team-featured .team-name{ font-size: 20px; }
.team-name{
  font-family: var(--font-display);
  font-size: 17px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--negro);
  margin: 0 0 4px;
}
.team-role{
  font-size: 13px;
  font-weight: 600;
  color: var(--azul);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

.team-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin-top: 12px;
  /* align-items:start evita que el stretch por defecto de grid estire las
     tarjetas con menos credenciales a la altura de la más larga de su fila,
     dejando hueco vacío al final — cada tarjeta ocupa solo su propio alto. */
  align-items: start;
  perspective: 900px;
}
.team-card{
  border: 1px solid var(--linea);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-align: center;
  opacity: 0;
  transform-style: preserve-3d;
  transition: opacity .5s cubic-bezier(0.16, 1, 0.3, 1), transform var(--dur-nudge) var(--ease-carve), border-color .15s ease, box-shadow .15s ease;
}
.reveal.in-view .team-card{ opacity: 1; }
.team-card:hover{
  transform: translateY(-3px);
  border-color: var(--turquesa);
  box-shadow: 0 8px 20px rgba(0,0,0,0.08);
}
.team-card:nth-child(2){ transition-delay: .06s, 0s, 0s, 0s; }
.team-card:nth-child(3){ transition-delay: .12s, 0s, 0s, 0s; }
.team-card:nth-child(4){ transition-delay: .18s, 0s, 0s, 0s; }
.team-card:nth-child(n+5){ transition-delay: .24s, 0s, 0s, 0s; }
.team-card-body{ padding: 16px 16px 20px; }
.team-formacion{
  list-style: none;
  margin: 14px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--linea);
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.team-formacion li{
  font-size: 14px;
  line-height: 1.45;
  color: var(--gris-oscuro);
  padding-left: 15px;
  position: relative;
}
.team-formacion li::before{
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--turquesa);
}
.team-featured-body .team-formacion{ margin-top: 16px; padding-top: 16px; }
.team-featured-body .team-formacion li{ font-size: 15px; }
@media (max-width: 720px){
  .team-grid{ grid-template-columns: repeat(2, 1fr); }
  .team-featured-grid .team-featured{ max-width: 100%; flex-basis: 100%; }
}
@media (max-width: 480px){
  .team-grid{ grid-template-columns: 1fr; }
  .team-featured{ flex-direction: column; }
  .team-featured .team-photo{ width: 100%; aspect-ratio: 16 / 10; border-right: none; border-bottom: 1px solid var(--linea); }
}

/* ==========================================================================
   Footer — "Rutas del club": la navegación se agrupa como el propio
   recorrido de un patinador (Empieza / Compite / Conócenos) en vez de un
   índice plano. Sin lema de marca: las tres rutas ya cuentan esa misma idea
   con la estructura. Rediseño completo, no evolución del footer anterior.
   ========================================================================== */
.site-footer{ background: var(--negro); color: var(--blanco); }
.footer-main{
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 56px 24px 40px;
}
.footer-brand{ margin: 0 0 36px; }
.footer-logo-wordmark{ height: 32px; width: auto; object-fit: contain; }

.footer-routes{
  display: grid;
  grid-template-columns: repeat(3, 1fr) auto;
  gap: 40px;
  align-items: start;
}
.footer-route{ display: flex; flex-direction: column; }
.footer-route-title{
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--turquesa);
  margin: 0 0 16px;
}
.footer-route a{
  font-size: 14px;
  color: var(--on-dark-secundario);
  line-height: 1.9;
}
.footer-route a:hover{ color: var(--turquesa); }

.footer-utility{
  display: flex;
  flex-direction: column;
  gap: 28px;
  border-left: 1px solid rgba(255,255,255,0.14);
  padding-left: 40px;
}
.footer-utility-group{ display: flex; flex-direction: column; font-style: normal; }
.footer-utility-title{
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--on-dark-tenue);
  margin: 0 0 16px;
}
.footer-utility-group a{
  font-size: 14px;
  color: var(--on-dark-secundario);
  line-height: 1.9;
}
.footer-utility-group a:hover{ color: var(--turquesa); }
.footer-cookie-settings{
  font-family: var(--font-body); font-size: 14px; color: var(--on-dark-secundario);
  line-height: 1.9; background: none; border: 0; padding: 0; margin: 0;
  text-align: left; cursor: pointer;
}
.footer-cookie-settings:hover{ color: var(--turquesa); }
.footer-cookie-settings:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }

.footer-bottom{
  border-top: 1px solid rgba(255,255,255,0.1);
}
.footer-bottom-inner{
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 20px 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  align-items: center;
  justify-content: space-between;
}
.footer-copy{ font-size: 12px; color: var(--on-dark-tenue); margin: 0; }

/* El patrocinador pasa de un logo suelto junto al copyright a su propia
   tarjeta con borde: más presencia como crédito, sin convertirse en un
   bloque de venta — sigue en la franja de utilidad, no en el cuerpo. */
.footer-sponsor{
  display: flex;
  align-items: center;
  gap: 11px;
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: 8px;
  padding: 8px 14px;
}
.footer-sponsor-label{ font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--on-dark-tenue); white-space: nowrap; }
.footer-sponsor-logo{ height: 28px; width: auto; }

@media (max-width: 860px){
  .footer-routes{ grid-template-columns: 1fr 1fr; gap: 32px 24px; }
  .footer-utility{
    grid-column: 1 / -1;
    flex-direction: row;
    gap: 60px;
    border-left: none;
    padding-left: 0;
    border-top: 1px solid rgba(255,255,255,0.14);
    padding-top: 28px;
    margin-top: 4px;
  }
}
@media (max-width: 560px){
  .footer-routes{ grid-template-columns: 1fr; gap: 28px; }
  .footer-utility{ flex-direction: column; gap: 28px; }
}

/* Icono de WhatsApp — currentColor para heredar el color del enlace (nunca
   el verde propio de WhatsApp, que rompería con la paleta turquesa/azul
   del resto del sitio). Reutilizado en el footer y en la tarjeta de
   contacto.html. */
.icon-whatsapp{
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  vertical-align: -2px;
  margin-right: 6px;
}
.footer-utility-group a.footer-whatsapp,
.footer-utility-group a.footer-contact-link{ display: inline-flex; align-items: center; }
.link-arrow-whatsapp{ display: inline-flex; align-items: center; }
.link-arrow-whatsapp .icon-whatsapp{ margin-right: 8px; }

/* Iconos de Email/Teléfono/Instagram — mismo tratamiento que .icon-whatsapp,
   reutilizado en contacto.html (para que las 3 tarjetas tengan el mismo
   peso visual) y en el footer (Email/Teléfono/Instagram llevaban texto
   suelto mientras WhatsApp llevaba icono — desequilibrado). El de Instagram
   es el mismo glifo de trazo ya usado en la insignia de noticia-card-badge,
   no relleno como los demás, porque recrearlo como icono sólido perdería
   su forma reconocible a este tamaño. */
.icon-email,
.icon-phone,
.icon-instagram{
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  vertical-align: -2px;
  margin-right: 6px;
}
.link-arrow-email,
.link-arrow-phone{ display: inline-flex; align-items: center; }
.link-arrow-email .icon-email,
.link-arrow-phone .icon-phone{ margin-right: 8px; }

/* ==========================================================================
   Páginas legales (placeholder)
   ========================================================================== */
.legal-page{
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 64px 24px;
}
.legal-page h1{
  font-family: var(--font-display);
  font-size: clamp(28px, 4vw, 40px);
  text-transform: uppercase;
  color: var(--negro);
  margin: 0 0 24px;
}
.legal-page h2{
  font-family: var(--font-display);
  font-size: 19px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--negro);
  margin: 40px 0 14px;
}
.legal-page h2:first-of-type{ margin-top: 0; }
.legal-page p{
  font-size: 15px;
  line-height: 1.65;
  color: var(--gris-oscuro);
  margin: 0 0 16px;
}
.legal-page ul{
  margin: 0 0 16px;
  padding-left: 20px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--gris-oscuro);
}
.legal-page li{ margin-bottom: 8px; }
.legal-page li strong,
.legal-page p strong{ color: var(--negro); }
.legal-page a{ color: var(--azul); font-weight: 600; }
.legal-page a:hover{ color: var(--turquesa); }
.legal-page table{
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 16px;
  font-size: 14px;
}
.legal-page th,
.legal-page td{
  text-align: left;
  padding: 10px 12px;
  border: 1px solid var(--linea);
  vertical-align: top;
}
.legal-page th{
  background: var(--papel-2);
  font-weight: 700;
  color: var(--negro);
}

/* ==========================================================================
   Responsive nav
   ========================================================================== */
@media (max-width: 900px){
  .main-nav{
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    overflow-y: auto;
    background: var(--blanco);
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding: 8px 24px 20px;
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity .15s ease, transform .15s ease;
  }
  .main-nav.open{
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }
  body.nav-open{ overflow: hidden; }
  .main-nav > a{ padding: 12px 0; width: 100%; border-bottom: 1px solid var(--linea); }
  .header-inner{ gap: 12px; }
  .nav-toggle{ display: flex; }
  .logo-wordmark{ height: 42px; }

  .nav-item{ flex-direction: column; align-items: stretch; width: 100%; border-bottom: 1px solid var(--linea); }
  .nav-item-row{ justify-content: space-between; }
  .nav-link{ padding: 12px 0; }
  .nav-caret{ width: 40px; height: 44px; }

  .dropdown{
    display: none;
    position: static;
    border: none;
    padding: 0 0 12px 16px;
    background: transparent;
    opacity: 1;
    transform: none;
    pointer-events: auto;
    transition: none;
  }
  .nav-item.open .dropdown{ display: flex; }
  .dropdown a{ padding: 8px 0; }
}

/* Cabeceras muy estrechas (≤374px, p.ej. iPhone SE 1.ª gen a 320px):
   logo + Apúntate + hamburguesa no caben con el espaciado estándar de móvil. */
@media (max-width: 374px){
  .site-header{ padding: 0 16px; }
  .header-inner{ gap: 8px; }
  .header-actions{ gap: 12px; }
  .nav-cta{ padding: 14px 14px; }
}

/* ==========================================================================
   Transiciones dinámicas — reveal on scroll
   "La línea del patinador": toda entrada traza un arco de 3 puntos, nunca
   una línea recta. Un único timing-function en el shorthand `animation` se
   reaplicaría en CADA tramo entre keyframes — con 3 puntos eso decelera
   hacia el punto medio, vuelve a acelerar y decelera otra vez: un stutter
   perceptible. Fijar animation-timing-function POR keyframe reparte la
   velocidad correctamente: tramo 1 casi lineal (sigue en marcha), tramo 2
   con la frenada real — una sola deceleración, al final.
   ========================================================================== */
@keyframes arcIn{
  0%{ opacity:0; transform: translate(-30px, 26px) rotate(-1.4deg); animation-timing-function: cubic-bezier(0.35,0,0.55,0.4); }
  58%{ opacity:1; transform: translate(-6px, 3px) rotate(-0.15deg); animation-timing-function: var(--ease-glide); }
  100%{ opacity:1; transform: translate(0,0) rotate(0deg); }
}
.reveal{
  /* Las Etapas de la home alternan in-view on/off al subir y bajar (ver
     script.js, revealObserver). Al quitarse in-view, la animation deja de
     aplicarse y el elemento cae a este opacity:0 base — esta transition es
     lo único que lo anima de vuelta, así que la salida no puede ser un
     corte seco. Salida más rápida que la entrada, con --ease-push, no un
     espejo de la llegada. */
  opacity: 0;
  transition: opacity var(--dur-nudge) var(--ease-push);
}
.reveal.in-view{
  animation: arcIn var(--dur-arrival) var(--ease-glide) both;
}
@media (prefers-reduced-motion: reduce){
  .reveal{ opacity: 0; animation: none; transition: opacity 0.4s ease; }
  .reveal.in-view{ opacity: 1; animation: none; transform: none; }
  .value-card, .team-card{ transition: opacity 0.4s ease; transition-delay: 0s; }
}

/* Tipografía cinética — envoltura que script.js añade sobre el titular.
   Sin opacity:0 en el titular base: si el JS no llega a ejecutarse, el
   texto original se queda tal cual, visible; el efecto solo vive en la
   envoltura que el propio JS crea y rellena. */
.kinetic-word{ display: inline-block; overflow: hidden; vertical-align: top; }
.kinetic-word-inner{ display: inline-block; animation: arcIn var(--dur-arrival) var(--ease-glide) both; }

/* ==========================================================================
   Galería — mosaico masonry con lightbox
   ========================================================================== */
.gallery-section{ padding-top: 48px; }

.competitions-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 24px;
  max-width: var(--max-w);
  margin: 12px auto 0;
}
/* Con solo 3 tarjetas, el estado de 2 columnas de auto-fill (672-995px)
   siempre deja la tercera huérfana a media anchura con hueco muerto al
   lado — se salta directo de 1 a 3 columnas en vez de pasar por ahí. */
@media (max-width: 995px){
  .competitions-grid{ grid-template-columns: 1fr; }
}
.competition-card{
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform .15s ease;
}
.competition-card:hover{ transform: translateY(-3px); }
.competition-card:focus-visible{ transform: translateY(-3px); outline: 2px solid var(--turquesa); outline-offset: 2px; }
.competition-card img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  transition: transform .4s cubic-bezier(0.16, 1, 0.3, 1);
}
.competition-card:hover img{ transform: scale(1.04); }
/* El degradado anterior (0% a 40%, 0.88 a 100%) medía 2.2:1 de contraste
   con blanco donde el titular caía sobre una zona clara de la foto (cielo,
   pared, ropa) — muy por debajo del mínimo 4.5:1. Empieza antes y llega más
   oscuro para garantizar contraste incluso en el peor píxel de la foto. */
.competition-card-scrim{
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11,12,14,0) 10%, rgba(11,12,14,0.96) 80%);
}
.competition-card-body{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 22px 24px;
}
.competition-card-name{
  font-family: var(--font-display);
  font-size: 22px;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--blanco);
  margin: 0 0 4px;
}
.competition-card-meta{
  font-size: 13px;
  color: var(--on-dark-secundario);
  margin: 0 0 12px;
}
.competition-card-link{
  font-size: 14px;
  font-weight: 700;
  color: var(--turquesa);
}
.gallery-grid{
  column-width: 280px;
  column-gap: 16px;
  max-width: var(--max-w);
  margin: 0 auto;
}
/* El masonry deja solo 16px (el margin-bottom de .gallery-item) antes del
   CTA de la colección completa — poco aire tras una cuadrícula de fotos
   tan densa. */
.gallery-drive-cta{ margin-top: 40px; }
/* Copia del CTA arriba de la cuadrícula: el enlace a la colección completa
   no debía depender de hacer scroll por todas las fotos para encontrarlo. */
.gallery-drive-cta-top{ margin-top: 0; margin-bottom: 40px; }
.gallery-item{
  display: block;
  width: 100%;
  break-inside: avoid;
  margin: 0 0 16px;
  padding: 0;
  border: none;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: none;
  cursor: zoom-in;
  line-height: 0;
}
.gallery-item img{
  display: block;
  width: 100%;
  height: auto;
  transition: transform .4s cubic-bezier(0.16, 1, 0.3, 1);
}
.gallery-item:hover img{ transform: scale(1.04); }
.gallery-item:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
/* auto-fit + un máximo fijo (no 1fr) + justify-content:center: con una sola
   tarjeta (estado actual, sin API conectada) queda centrada a su tamaño
   natural en vez de estirarse a todo el ancho del contenedor o dejar
   columnas fantasma vacías al lado. Cuando lleguen más posts del feed de
   Instagram, se comporta como una grid normal centrada que envuelve fila. */
.noticias-grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 340px));
  justify-content: center;
  gap: 24px;
  max-width: var(--max-w);
  margin: 12px auto 0;
}
.noticia-card{
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform .15s ease, opacity var(--dur-nudge) var(--ease-push);
}
.noticia-card:hover,
.noticia-card:focus-visible{ transform: translateY(-3px); }
.noticia-card:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
.noticia-card img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .4s cubic-bezier(0.16, 1, 0.3, 1);
}
.noticia-card:hover img{ transform: scale(1.04); }
.noticia-card-scrim{
  position: absolute;
  inset: 0;
  /* Antes el degradado no oscurecía lo suficiente hasta el 35%, así que
     un post con fondo claro (p. ej. la foto de "Nueva web") dejaba el
     texto blanco casi ilegible sobre esa zona. Oscurece antes y más
     rápido para garantizar contraste pase lo que pase debajo. */
  background: linear-gradient(180deg, rgba(11,12,14,0) 20%, rgba(11,12,14,0.82) 52%, rgba(11,12,14,0.97) 72%, rgba(11,12,14,0.97) 100%);
}
.noticia-card-badge{
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  background: rgba(11,12,14,0.6);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--blanco);
}
.noticia-card-badge svg{ width: 14px; height: 14px; flex-shrink: 0; }
.noticia-card-body{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 22px 24px;
}
.noticia-card-date{
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--turquesa);
  margin: 0 0 8px;
}
.noticia-card-text{
  font-size: 14px;
  line-height: 1.5;
  color: var(--blanco);
  margin: 0 0 12px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.noticia-card-link{
  font-size: 13px;
  font-weight: 700;
  color: var(--turquesa);
}

@media (max-width: 480px){
  .gallery-grid{ column-width: 150px; column-gap: 10px; }
  .gallery-item{ margin-bottom: 10px; border-radius: var(--radius-sm); }
}

.lightbox{
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(11,12,14,0.94);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease;
  padding: 24px;
}
.lightbox.is-open{ opacity: 1; visibility: visible; }
body.lightbox-open{ overflow: hidden; }

.lightbox-figure{
  max-width: min(1100px, 100%);
  max-height: 100%;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.lightbox-img{
  display: block;
  max-width: 100%;
  max-height: 82vh;
  width: auto;
  height: auto;
  border-radius: var(--radius-sm);
}
.lightbox-counter{
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--on-dark-tenue);
}

.lightbox-close,
.lightbox-nav{
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255,255,255,0.2);
  background: rgba(255,255,255,0.06);
  color: var(--blanco);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.lightbox-close:hover,
.lightbox-nav:hover{ background: rgba(255,255,255,0.16); border-color: rgba(255,255,255,0.4); }
.lightbox-close svg,
.lightbox-nav svg{ width: 20px; height: 20px; }

.lightbox-close{ top: 20px; right: 20px; }
.lightbox-prev{ left: 20px; top: 50%; transform: translateY(-50%); }
.lightbox-next{ right: 20px; top: 50%; transform: translateY(-50%); }

@media (max-width: 640px){
  .lightbox{ padding: 16px; }
  .lightbox-close{ top: 12px; right: 12px; }
  .lightbox-prev{ left: 12px; }
  .lightbox-next{ right: 12px; }
}

/* ==========================================================================
   Pop-up de Apúntate — carga el formulario real de apuntate.html
   ========================================================================== */
.apuntate-modal{
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  background: rgba(11,12,14,0.72);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease;
  padding: 40px 24px;
  overflow-y: auto;
}
.apuntate-modal.is-open{ opacity: 1; visibility: visible; }
body.apuntate-modal-open{ overflow: hidden; }

.apuntate-modal-panel{
  position: relative;
  background: var(--papel);
  border-radius: var(--radius-lg);
  max-width: 680px;
  width: 100%;
  padding: 40px 32px;
  margin: auto;
}
.apuntate-modal-close{
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--linea);
  background: var(--papel-2);
  color: var(--negro);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.apuntate-modal-close:hover{ background: var(--blanco); border-color: var(--gris-oscuro); }
.apuntate-modal-close svg{ display: block; width: 18px; height: 18px; }

.apuntate-modal-title{
  font-family: var(--font-display);
  font-size: clamp(24px, 3vw, 30px);
  text-transform: uppercase;
  color: var(--negro);
  margin: 0 32px 10px 0;
}
.apuntate-modal-lead{
  font-size: 15px;
  line-height: 1.5;
  color: var(--gris-oscuro);
  margin: 0 0 20px;
  max-width: 52ch;
}
.apuntate-modal-loading{
  font-size: 15px;
  color: var(--gris-oscuro);
  text-align: center;
  padding: 32px 0;
}
.apuntate-modal-loading a{ color: var(--azul); font-weight: 600; }

@media (max-width: 640px){
  .apuntate-modal{ padding: 20px 16px; }
  .apuntate-modal-panel{ padding: 28px 20px; }
}

/* ==========================================================================
   Banner de cookies — aparece en la primera página que visite cada persona
   (no solo en la home: quien entra directo a otra página por un buscador
   también tiene que poder decidir) y se queda hasta que elige. No hay botón
   para cerrarlo sin decidir: la inacción nunca se interpreta como
   aceptación (RGPD considerando 32 / guía de cookies de la AEPD). z-index
   150: por encima del header (100) y los desplegables (60), por debajo del
   lightbox (200) y el pop-up de Apúntate (300), que sí son tareas que piden
   atención completa.
   ========================================================================== */
.cookie-banner{
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 150;
  background: var(--negro-pista);
  color: var(--blanco);
  font-family: var(--font-body);
  /* Antes esto era display:none → block, un corte seco sin transición. El
     botón "Configurar cookies" del footer reabre este mismo banner sobre un
     fondo igual de oscuro que el propio footer: sin animación, el cambio
     pasaba desapercibido y parecía que el botón no hacía nada. */
  transform: translateY(100%);
  opacity: 0;
  visibility: hidden;
  transition: transform 0.32s var(--ease-carve), opacity 0.32s ease, visibility 0s linear 0.32s;
}
.cookie-banner.is-visible{
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
  transition: transform 0.32s var(--ease-carve), opacity 0.32s ease, visibility 0s linear 0s;
}
@media (prefers-reduced-motion: reduce){
  .cookie-banner{ transition: opacity 0.2s ease, visibility 0s linear 0.2s; transform: none; }
  .cookie-banner.is-visible{ transition: opacity 0.2s ease; }
}
.cookie-banner-row{
  padding: 14px 28px;
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  max-width: 1180px;
  margin: 0 auto;
}
.cookie-banner-text{ flex: 1; min-width: 220px; font-size: 12.5px; line-height: 1.5; color: rgba(255,255,255,0.82); margin: 0; }
.cookie-banner-text a{ color: var(--turquesa); font-weight: 700; text-decoration: underline; }
.cookie-banner-actions{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cookie-btn{
  font-family: var(--font-body); font-weight: 700; font-size: 12.5px; letter-spacing: 0.01em;
  padding: 9px 16px; border-radius: var(--radius-pill); border: 0; cursor: pointer;
}
.cookie-btn-primary{ background: var(--turquesa); color: var(--negro-pista); }
.cookie-btn-primary:hover{ background: var(--blanco); }
.cookie-btn-ghost{ background: transparent; border: 1px solid rgba(255,255,255,0.32); color: var(--blanco); }
.cookie-btn-ghost:hover{ border-color: var(--turquesa); color: var(--turquesa); }
.cookie-btn:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
.cookie-link{
  background: none; border: 0; color: rgba(255,255,255,0.75); font-family: var(--font-body);
  font-size: 12.5px; font-weight: 700; text-decoration: underline; cursor: pointer; padding: 9px 2px;
}
.cookie-link:hover, .cookie-link[aria-expanded="true"]{ color: var(--turquesa); }
.cookie-link:focus-visible{ outline: 2px solid var(--turquesa); outline-offset: 2px; }

/* grid-template-rows en vez de max-height: anima el despliegue sin obligar
   al navegador a recalcular el layout en cada fotograma. */
.cookie-panel{
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.28s ease, border-top-color 0.28s ease;
  border-top: 1px solid rgba(255,255,255,0);
}
.cookie-panel.is-open{ grid-template-rows: 1fr; border-top-color: rgba(255,255,255,0.12); }
/* El padding vive en .cookie-panel-content, no aquí: si estuviera en el
   propio elemento con overflow:hidden, ese padding cuenta igualmente como
   tamaño mínimo del carril de grid aunque el contenido esté colapsado a
   0fr, y el panel se quedaba con foco de teclado "fantasma" en un botón
   visualmente invisible pero con 22px reales de alto. */
.cookie-panel-inner{ overflow: hidden; min-height: 0; }
.cookie-panel-content{ padding: 4px 28px 18px; max-width: 1180px; margin: 0 auto; }
.cookie-cat{ display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 12px 0; }
.cookie-cat + .cookie-cat{ border-top: 1px solid rgba(255,255,255,0.1); }
.cookie-cat-name{ font-weight: 700; font-size: 12.5px; color: var(--blanco); margin: 0 0 2px; }
.cookie-cat-desc{ font-size: 11.5px; color: rgba(255,255,255,0.62); margin: 0; max-width: 440px; line-height: 1.5; }
.cookie-cat-fixed{ font-size: 10.5px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--turquesa); white-space: nowrap; padding-top: 2px; }
.cookie-toggle{ position: relative; width: 36px; height: 20px; flex-shrink: 0; }
.cookie-toggle input{ position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.cookie-toggle-track{ position: absolute; inset: 0; background: rgba(255,255,255,0.18); border-radius: var(--radius-pill); transition: background 0.15s; }
.cookie-toggle input:checked + .cookie-toggle-track{ background: var(--turquesa); }
.cookie-toggle-thumb{ position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--blanco); transition: transform 0.15s; pointer-events: none; }
.cookie-toggle input:checked ~ .cookie-toggle-thumb{ transform: translateX(16px); }
.cookie-toggle input:focus-visible ~ .cookie-toggle-track{ outline: 2px solid var(--turquesa); outline-offset: 2px; }
.cookie-panel-actions{ display: flex; justify-content: flex-end; margin-top: 4px; }

@media (prefers-reduced-motion: reduce){
  .cookie-panel{ transition: none; }
  .cookie-toggle-track, .cookie-toggle-thumb{ transition: none; }
}

@media (max-width: 640px){
  .cookie-banner-row{ flex-direction: column; align-items: stretch; }
  .cookie-banner-actions{ justify-content: flex-end; }
}
