/* ==========================================================================
   BIELA · catálogo técnico: papel de delineante, cotas en cobalto, ancha y seca.
   Tokens en :root. El acento vive en UNA línea (--cobalto).
   Radios: 0 en todo lo rectangular; solo son redondos las muestras de color y los puntos.
   ========================================================================== */
@font-face { font-family: "Archivo"; src: url(../fuentes/archivo.woff2) format("woff2"); font-weight: 100 900; font-stretch: 62% 125%; font-display: swap; }
@font-face { font-family: "Plex Mono"; src: url(../fuentes/plex-mono-400.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Plex Mono"; src: url(../fuentes/plex-mono-500.woff2) format("woff2"); font-weight: 500; font-display: swap; }

:root {
  --papel: #EEF0F2;
  --blanco: #FFFFFF;
  --tinta: #0F1115;
  --tinta-2: #4A515C;
  --cobalto: #1F3BFF;
  --cobalto-texto: #1A2FD6;   /* el mismo azul, un punto más hondo, para texto pequeño sobre la rejilla (≥7:1) */
  --linea: rgb(15 17 21 / .14);
  --rejilla: rgb(31 59 255 / .07);
  --rejilla-fuerte: rgb(31 59 255 / .12);

  --f-texto: "Archivo", system-ui, sans-serif;
  --f-dato: "Plex Mono", ui-monospace, monospace;

  --e1: 0 1px 2px rgb(20 30 70 / .08), 0 2px 6px -2px rgb(20 30 70 / .10);
  --e2: 0 2px 4px rgb(20 30 70 / .08), 0 12px 28px -10px rgb(20 30 70 / .22);
  --e3: 0 4px 8px rgb(20 30 70 / .10), 0 28px 60px -18px rgb(20 30 70 / .32);

  --ease: cubic-bezier(0.23, 1, 0.32, 1);
  --muelle: cubic-bezier(0.34, 1.56, 0.64, 1);
  --cajon: cubic-bezier(0.32, 0.72, 0, 1);
  --plotter: cubic-bezier(0.76, 0, 0.24, 1);   /* arranque y frenada secos, como el cabezal de un plóter */
  --d-rapido: 140ms;
  --d-base: 220ms;

  --margen: clamp(1rem, 4vw, 3.5rem);
  --cabecera: 4rem;
}

/* [hidden] manda siempre: un display de clase no puede resucitar lo que el HTML esconde */
[hidden] { display: none !important; }

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--cabecera) + 1rem); -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background-color: var(--papel); color: var(--tinta);
  font-family: var(--f-texto); font-size: 1rem; line-height: 1.55; font-stretch: 100%;
  /* papel de delineante: rejilla fina de 24 px y gruesa de 120 px */
  background-image:
    linear-gradient(var(--rejilla-fuerte) 1px, transparent 1px), linear-gradient(90deg, var(--rejilla-fuerte) 1px, transparent 1px),
    linear-gradient(var(--rejilla) 1px, transparent 1px), linear-gradient(90deg, var(--rejilla) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
}
img, svg { display: block; max-width: 100%; }
button, input, select { font: inherit; color: inherit; }
::selection { background: var(--cobalto); color: var(--blanco); }
:focus-visible { outline: 2px solid var(--cobalto); outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.saltar { position: fixed; left: 1rem; top: -4rem; z-index: 100; background: var(--tinta); color: var(--blanco); padding: .75rem 1rem; }
.saltar:focus { top: 1rem; }
.dato { font-family: var(--f-dato); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); margin: 0; }

/* ------------------------------------------------------------ aviso de envío (cinta) */
.aviso-envio { display: flex; align-items: center; background: var(--cobalto); color: var(--blanco); overflow: hidden; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .06em; }
.aviso-envio__carril { flex: 1; min-width: 0; overflow: hidden; }
.aviso-envio__cinta { display: flex; width: max-content; animation: cinta 36s linear infinite; }
.aviso-envio__cinta span { padding: .55rem 2.5rem; white-space: nowrap; }
.aviso-envio__cinta span::before { content: "+"; margin-right: .75rem; opacity: .7; }
@keyframes cinta { to { transform: translateX(-50%); } }

/* ------------------------------------------------------------ cabecera */
.cabecera {
  position: sticky; top: 0; z-index: 30; height: var(--cabecera);
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 2rem;
  padding: 0 var(--margen); background: var(--papel); border-bottom: 1px solid var(--linea);
}
.logo { display: inline-flex; align-items: center; gap: .6rem; color: var(--tinta); text-decoration: none; }
.logo span, .pie__marca span { font-stretch: 125%; font-weight: 900; font-size: 1.375rem; letter-spacing: .06em; }
.logo__biela { flex: none; width: 2.4rem; height: auto; color: var(--cobalto); } /* nunca se encoge: a 320 quedaba en 3 px */
.logo:hover .logo__biela { transform: rotate(-24deg); }
.logo__biela { transform-origin: 22.5% 62.5%; transition: transform 420ms var(--muelle); }
.menu { display: flex; justify-content: center; gap: .25rem; }
.menu a {
  position: relative; padding: .5rem .75rem; color: var(--tinta); text-decoration: none;
  font-stretch: 112%; font-weight: 600; font-size: .9375rem;
}
.menu a::after { content: ""; position: absolute; left: .75rem; right: .75rem; bottom: .2rem; height: 2px; background: var(--cobalto); transform: scaleX(0); transform-origin: 0 50%; transition: transform var(--d-base) var(--ease); }
.menu a:hover::after, .menu a:focus-visible::after { transform: scaleX(1); }
.cabecera__acciones { display: flex; align-items: center; gap: 1rem; }
.cabecera__talla { color: var(--tinta); font-weight: 600; font-size: .9375rem; text-underline-offset: .25em; }
.boton-cesta {
  display: inline-flex; align-items: center; gap: .5rem; height: 2.75rem; padding: 0 1rem;
  background: var(--tinta); color: var(--blanco); border: 0; cursor: pointer; font-weight: 600; font-size: .9375rem;
  transition: background-color var(--d-rapido) var(--ease);
}
.boton-cesta:hover { background: var(--cobalto); }
.boton-cesta svg { flex: none; width: 1.3rem; height: 1.3rem; } /* a 320 se encogía hasta ser un punto */
.boton-cesta__n { min-width: 1.5rem; height: 1.5rem; display: inline-grid; place-items: center; background: var(--cobalto); color: var(--blanco); font-family: var(--f-dato); font-size: .8125rem; }
.boton-cesta:hover .boton-cesta__n { background: var(--blanco); color: var(--cobalto); }
@keyframes golpe { 0% { transform: scale(1); } 30% { transform: scale(1.5); } 100% { transform: scale(1); } }

/* ------------------------------------------------------------ botones */
.boton {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem; min-height: 3rem; padding: 0 1.4rem;
  background: var(--cobalto); color: var(--blanco); border: 0; border-radius: 0; cursor: pointer; text-decoration: none;
  font-stretch: 112%; font-weight: 700; font-size: .9375rem; letter-spacing: .04em; text-transform: uppercase;
  transition: background-color var(--d-rapido) var(--ease), color var(--d-rapido) var(--ease), box-shadow var(--d-rapido) var(--ease), transform var(--d-rapido) var(--ease);
}
.boton:hover { background: var(--tinta); }
.boton:active { transform: translateY(1px); }
.boton:disabled { opacity: .45; cursor: not-allowed; }
.boton--grande { min-height: 3.75rem; padding: 0 2rem; font-size: 1rem; }
.boton--linea { background: transparent; color: var(--tinta); box-shadow: inset 0 0 0 1.5px var(--tinta); }
.boton--linea:hover { background: var(--tinta); color: var(--blanco); }
.boton--claro { background: var(--blanco); color: var(--tinta); }
.boton--claro:hover { background: var(--cobalto); color: var(--blanco); }
.enlace { background: none; border: 0; padding: 0; color: var(--cobalto-texto); font-weight: 700; text-decoration: underline; text-underline-offset: .2em; cursor: pointer; }

/* ------------------------------------------------------------ héroe */
.heroe {
  display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(20rem, 1fr); gap: clamp(1.5rem, 3vw, 3.5rem);
  align-items: center; min-height: min(calc(100svh - 108px), 62rem); max-height: max(calc(100svh - 108px), 34rem);
  padding: clamp(.75rem, 2svh, 2rem) var(--margen) clamp(.75rem, 2svh, 2rem);
}
.heroe__plano { position: relative; display: grid; justify-items: center; }
/* la foto se limita por el ancho de su columna Y por el alto de la pantalla (cinta + cabecera = 100 px) */
.heroe__foto { position: relative; aspect-ratio: 1448 / 1086; width: min(100%, calc((100svh - 108px - 2 * clamp(.75rem, 2svh, 2rem)) * 1.3333)); }
.heroe__cifra { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; padding-bottom: 6%; overflow: hidden; font-stretch: 62%; font-weight: 800; font-size: clamp(8rem, 22vw, 20rem); line-height: .8; letter-spacing: -.02em; color: rgb(31 59 255 / .1); font-variant-numeric: tabular-nums; white-space: nowrap; pointer-events: none; user-select: none; }
.heroe__cifra span { display: block; }
/* sin z-index en la foto: un contexto de apilamiento aislaría su «multiply» y el blanco del render se vería como una caja */
.heroe__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; mix-blend-mode: multiply; opacity: 0; transition: opacity 420ms var(--ease), transform 620ms var(--ease); }
.heroe__img.es-visible { opacity: 1; }
.cotas { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.cotas path { fill: none; vector-effect: non-scaling-stroke; }
.cota__linea, .cota__marca { stroke: var(--cobalto); stroke-width: 1.5; }
.cota__ext { stroke: var(--tinta-2); stroke-width: 1; stroke-dasharray: 4 5; opacity: .45; }
.cotas circle { fill: var(--cobalto); }
.cotas text { font-family: var(--f-dato); font-size: 24px; fill: var(--cobalto-texto); font-weight: 500; letter-spacing: .02em; paint-order: stroke; stroke: var(--papel); stroke-width: 8px; stroke-linejoin: round; }

.heroe__ficha { position: relative; z-index: 2; }
.heroe__titulo {
  margin: .75rem 0 1rem; font-stretch: 125%; font-weight: 800; text-transform: uppercase;
  font-size: clamp(2.3rem, 3.9vw, 4.1rem); line-height: .96; letter-spacing: -.01em;
}
.heroe__titulo .linea { display: block; }
.heroe__titulo .linea:first-child { padding-bottom: .09em; } /* la coma de «TRAMO,» no roza la L de GRAVEL */
.heroe__titulo { font-size: clamp(2.3rem, min(3.9vw, 7.4svh), 4.1rem); }
.heroe__texto { max-width: 34ch; margin: 0 0 clamp(1rem, 2.4svh, 1.5rem); color: var(--tinta-2); font-size: 1.0625rem; }
.heroe__paga { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1.5rem; margin-bottom: clamp(1rem, 2.4svh, 1.5rem); }
.heroe__paga .precio { margin: 0; }
.heroe__elige { display: flex; flex-wrap: wrap; align-items: end; gap: .75rem 1.5rem; }
.heroe__elige .elige { margin: 0; }
.heroe__elige .elige--talla { flex: 1 1 13rem; }
.precio { margin: 0 0 1.5rem; font-stretch: 125%; font-weight: 700; font-size: 2rem; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }

.elige { border: 0; padding: 0; margin: 0 0 1.5rem; }
.elige legend { padding: 0; margin-bottom: .6rem; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); width: 100%; display: flex; justify-content: space-between; gap: 1rem; }
.elige__valor { color: var(--tinta); }
.elige__ayuda { color: var(--cobalto-texto); text-transform: none; letter-spacing: 0; font-family: var(--f-texto); font-weight: 600; font-size: .875rem; }
.elige--color { display: flex; gap: .75rem; flex-wrap: wrap; }
.muestra { position: relative; width: 2.5rem; height: 2.5rem; border-radius: 50%; background: var(--muestra); cursor: pointer; box-shadow: inset 0 0 0 1px rgb(0 0 0 / .12); transition: transform var(--d-base) var(--muelle); }
.muestra input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.muestra::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; box-shadow: 0 0 0 2px var(--tinta); opacity: 0; transform: scale(.8); transition: opacity var(--d-base) var(--ease), transform var(--d-base) var(--muelle); }
.muestra:has(input:checked)::after { opacity: 1; transform: none; }
.muestra:has(input:focus-visible)::after { box-shadow: 0 0 0 2px var(--cobalto); opacity: 1; transform: none; }
.muestra:hover { transform: scale(1.08); }

.tallas { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); box-shadow: inset 0 0 0 1.5px var(--tinta); }
.tallas label { position: relative; z-index: 1; display: grid; place-items: center; height: 3rem; cursor: pointer; font-stretch: 112%; font-weight: 700; transition: color var(--d-base) var(--ease); }
.tallas input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.tallas label:has(input:checked) { color: var(--blanco); }
.tallas label:has(input:focus-visible) { outline: 2px solid var(--cobalto); outline-offset: -5px; }
.tallas__marca { position: absolute; z-index: 0; top: 0; bottom: 0; left: 0; width: var(--w, 25%); background: var(--tinta); transform: translateX(var(--x, 100%)); transition: transform 360ms var(--muelle); }
.heroe__plazo { margin: .9rem 0 0; font-family: var(--f-dato); font-size: .75rem; color: var(--tinta-2); letter-spacing: .04em; }

/* cinta de especificaciones */
.cinta-specs { background: var(--tinta); color: var(--papel); overflow: hidden; }
.cinta-specs__pista { display: flex; width: max-content; animation: cinta 48s linear infinite; }
.cinta-specs span { font-family: var(--f-dato); font-size: .8125rem; letter-spacing: .1em; text-transform: uppercase; padding: 1.1rem 0; white-space: nowrap; }
.cinta-specs span::after { content: "/"; color: var(--cobalto); margin: 0 1.75rem; font-weight: 500; }

/* ------------------------------------------------------------ títulos de sección */
.corte { display: block; text-wrap: pretty; } /* cortes decididos; dentro de cada uno, sin palabra colgando */
.titulo-seccion { margin: 0; font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: clamp(1.9rem, 3.6vw, 3.4rem); line-height: .98; letter-spacing: -.01em; max-width: 22ch; text-wrap: balance; }

/* ------------------------------------------------------------ catálogo */
.catalogo { padding: clamp(4rem, 9vw, 8rem) var(--margen) clamp(3rem, 6vw, 5rem); }
.catalogo__cabeza { display: grid; grid-template-columns: 1fr auto; gap: 1.5rem 2rem; align-items: end; margin-bottom: 2rem; }
.filtros { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: .5rem; }
.filtro {
  display: inline-flex; align-items: center; gap: .5rem; height: 2.5rem; padding: 0 1rem; cursor: pointer;
  background: var(--blanco); border: 0; box-shadow: inset 0 0 0 1px var(--linea);
  font-family: var(--f-dato); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase;
  transition: background-color var(--d-rapido) var(--ease), color var(--d-rapido) var(--ease), box-shadow var(--d-rapido) var(--ease);
}
.filtro span { color: var(--tinta-2); }
.filtro:hover { box-shadow: inset 0 0 0 1.5px var(--tinta); }
.filtro[aria-pressed="true"] { background: var(--tinta); color: var(--blanco); box-shadow: none; }
.filtro[aria-pressed="true"] span { color: #AEB6C4; }
.orden { grid-row: 1; grid-column: 2; display: flex; gap: 1.5rem; align-items: end; }
.orden__abre { display: none; }
.orden__campo { display: grid; gap: .35rem; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); }
.orden__campo output { color: var(--tinta); }
.orden select { height: 2.5rem; padding: 0 2.25rem 0 .75rem; border: 0; border-radius: 0; background: var(--blanco) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%230F1115' stroke-width='1.6'/%3E%3C/svg%3E") no-repeat right .75rem center / .7rem; box-shadow: inset 0 0 0 1px var(--linea); appearance: none; font-family: var(--f-texto); font-size: .9375rem; text-transform: none; letter-spacing: 0; color: var(--tinta); cursor: pointer; }
.orden__campo--rango input { width: 12rem; }

input[type="range"] { -webkit-appearance: none; appearance: none; height: 2.5rem; background: transparent; cursor: pointer; margin: 0; }
input[type="range"]::-webkit-slider-runnable-track { height: 2px; background: var(--tinta); }
input[type="range"]::-moz-range-track { height: 2px; background: var(--tinta); }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 1.25rem; height: 1.25rem; margin-top: -.59rem; background: var(--cobalto); border: 3px solid var(--blanco); border-radius: 50%; box-shadow: 0 0 0 1px var(--cobalto), var(--e1); transition: transform var(--d-rapido) var(--muelle); }
input[type="range"]::-moz-range-thumb { width: 1.25rem; height: 1.25rem; background: var(--cobalto); border: 3px solid var(--blanco); border-radius: 50%; box-shadow: 0 0 0 1px var(--cobalto); }
input[type="range"]:active::-webkit-slider-thumb { transform: scale(1.25); }

.rejilla { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem; grid-auto-flow: dense; }
.bici[hidden] { display: none; }
.bici--grande { grid-column: span 2; grid-row: span 2; }
.rejilla[data-n="1"] { grid-template-columns: minmax(0, 56rem); justify-content: center; }
.rejilla[data-n="1"] .bici--grande, .rejilla[data-n="2"] .bici--grande { grid-column: auto; grid-row: auto; }
.rejilla[data-n="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.bici article {
  height: 100%; display: grid; grid-template-columns: 1fr auto; grid-template-rows: 1fr auto auto auto; column-gap: 1rem;
  background: var(--blanco); padding: 1.25rem; box-shadow: var(--e1);
  transition: box-shadow var(--d-base) var(--ease), transform var(--d-base) var(--ease);
}
.bici article:hover { box-shadow: var(--e3); transform: translateY(-3px); }
.bici__foto { grid-column: 1 / -1; position: relative; display: block; width: 100%; margin: 0 0 1rem; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: inherit; overflow: hidden; cursor: zoom-in; }
.bici:not(.bici--grande) article { cursor: zoom-in; }
.bici--grande .bici__foto { cursor: default; }
/* foto y cota van en la misma lámina: al pasar el ratón se desplazan juntas (la cota no se queda atrás) */
.bici__lamina { position: relative; display: block; transition: transform 700ms var(--ease); }
.bici__foto img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: contain; }
.bici--grande article { align-content: space-between; }
.bici article:hover .bici__lamina { transform: translateX(3.5%); }
.bici .dato { grid-column: 1; }
.bici__nombre { grid-column: 1; margin: .2rem 0 .1rem; font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: clamp(1.4rem, 2vw, 1.75rem); line-height: 1; letter-spacing: -.005em; }
.bici--grande .bici__nombre { font-size: clamp(2rem, 3.4vw, 3.2rem); }
.bici__specs { grid-column: 1; margin: .4rem 0 0; font-family: var(--f-dato); font-size: .8125rem; color: var(--tinta-2); }
.bici__specs { display: flex; flex-wrap: wrap; column-gap: .55em; }
.bici__specs span { white-space: nowrap; }
.bici__specs span + span::before { content: "·"; margin-right: .55em; }
.bici__precio { grid-column: 2; grid-row: 2 / span 2; align-self: start; margin: 0; font-stretch: 125%; font-weight: 700; font-size: 1.25rem; font-variant-numeric: tabular-nums; text-align: right; }
/* los precios son finales (venta a consumidor, TRLGDCU art. 20 y 60) y se dice. Va en ::after porque el JS reescribe la
   cifra (configurador, cuenta del total) y el rótulo tiene que quedarse; mismo color que la cifra: no ensucia el contraste */
.bici__precio::after, .heroe .precio::after { content: "IVA incluido"; display: block; margin-top: .3rem; font-family: var(--f-dato); font-size: .6875rem; font-stretch: 100%; font-weight: 400; letter-spacing: .08em; line-height: 1.2; text-transform: uppercase; color: inherit; }
.cesta__iva { margin-left: .45em; font-family: var(--f-dato); font-size: .6875rem; font-weight: 400; letter-spacing: .08em; text-transform: uppercase; }
.bici .boton { grid-column: 2; grid-row: 4; justify-self: end; align-self: end; min-height: 2.5rem; padding: 0 1rem; }
/* la ficha técnica: solo la lleva la grande (dibujo a la escala común de las seis + sus datos) */
.bici__ficha { display: none; }
.bici--grande article { grid-template-rows: auto auto auto auto auto auto auto; }
.bici--grande .bici__ficha { grid-column: 1 / -1; grid-row: 7; display: grid; grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); gap: 1rem 1.75rem; align-items: center; margin: 1.25rem 0; padding-top: 1.25rem; border-top: 1px solid var(--linea); }
.bici--grande .boton { grid-row: 6; }
/* ------------------------------------------------------------ el configurador (solo en la ficha grande)
   El visor va encima del render, con la base reencuadrada a su mismo encuadre (--s, --tx, --ty): hasta que la base
   está decodificada se ve el render de debajo y, cuando entra, no se nota el cambio. Las capas se apilan en la caja
   que da el manifiesto (% de la base). Los ¾ son fotos enteras encima. */
.visor, .bici__config { display: none; }
.js .bici--grande .visor { display: block; }
.bici--grande article:hover, .bici--grande article:hover .bici__lamina { transform: none; } /* la grande no se desplaza ni se levanta: se está configurando (y su foto, pegada en el teléfono, no se mete bajo la cabecera) */
.visor { position: absolute; inset: 0; overflow: hidden; background: #FEFEFE; opacity: 0; transition: opacity 240ms var(--ease); } /* la base es otra foto: se funde sobre el render, no salta */
.visor.es-lista { opacity: 1; }
.bici.es-aterrizando .visor { opacity: 0; }
.visor__lienzo { position: absolute; left: 0; top: 0; width: 100%; height: 100%; transform-origin: 0 0; transform: translate(calc(var(--tx) * 1%), calc(var(--ty) * 1%)) scale(var(--s)); }
.bici .bici__foto .visor img:is(.visor__base, .visor__capa, .visor__angulo) { position: absolute; max-width: none; aspect-ratio: auto; object-fit: fill; opacity: 1; transition: none; }
.bici .bici__foto .visor .visor__base { inset: 0; width: 100%; height: 100%; }
.bici .bici__foto .visor .visor__capa { left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); width: calc(var(--w) * 1%); height: calc(var(--h) * 1%); }
.bici .bici__foto .visor .visor__angulo { inset: 0; width: 100%; height: 100%; object-fit: contain; background: #FEFEFE; }
.visor__marco, .visor__guia { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.visor__marco path { fill: none; stroke: var(--cobalto); stroke-width: .35; stroke-dasharray: 1; stroke-dashoffset: 1; }
.visor__guia path { fill: none; stroke: var(--cobalto); stroke-width: .28; stroke-dasharray: 1; stroke-dashoffset: 1; }
.visor__guia.es-vista path { stroke-dashoffset: 0; }
.visor__cota { position: absolute; left: calc(var(--cx) * 1%); top: calc(var(--cy) * 1%); translate: -50% -50%; z-index: 1; padding: .28rem .6rem; background: var(--blanco); color: var(--tinta); box-shadow: inset 0 0 0 1px var(--cobalto); font-family: var(--f-dato); font-size: .75rem; letter-spacing: .02em; width: max-content; max-width: calc(100% - 1rem); text-align: center; line-height: 1.35; }
.visor__cota b { font-weight: 500; color: var(--cobalto-texto); }
.visor:not([data-vista="lateral"]) .visor__cota, .visor:not([data-vista="lateral"]) .visor__guia { display: none; }
.bici.es-angulo .bici__cota, .bici.es-cota-abajo .bici__cota { display: none; } /* la batalla solo mide en la lateral; y deja sitio a la cota de una pieza de abajo */
.visor__aviso { position: absolute; left: .75rem; bottom: .6rem; margin: 0; padding: .22rem .5rem; background: var(--blanco); color: var(--tinta-2); box-shadow: inset 0 0 0 1px var(--linea); font-family: var(--f-dato); font-size: .6875rem; display: none; }
.visor.con-opciones:not([data-vista="lateral"]) .visor__aviso { display: block; }
.js .bici--grande .bici__config { grid-column: 1 / -1; grid-row: 5; display: grid; gap: 1.1rem; margin: 1.25rem 0 0; padding-top: 1.25rem; border-top: 1px solid var(--linea); }
/* escritorio: foto a la izquierda y el configurador a su lado (se ve cambiar la bici mientras eliges); debajo el nombre,
   el precio y «Añadir»; la ficha técnica a todo lo ancho al final. En ≤ 900 px, todo apilado */
@media (min-width: 901px) {
  /* la columna de la izquierda (foto, nombre) va seguida; lo que la derecha (opciones) mide de más cae en la fila
     elástica de abajo, no entre la foto y el nombre */
  .js .bici--grande article { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); column-gap: 2rem; grid-template-rows: auto auto auto auto 1fr auto auto auto; }
  .js .bici--grande .bici__foto { grid-column: 1; grid-row: 1; align-self: start; }
  .js .bici--grande .bici__config { grid-column: 2; grid-row: 1 / 6; align-self: start; margin: 0; padding: 0; border: 0; }
  .js .bici--grande .config__grupos { grid-template-columns: minmax(0, 1fr); gap: .9rem; }
  .js .bici--grande .dato { grid-row: 2; }
  .js .bici--grande .bici__nombre { grid-row: 3; }
  .js .bici--grande .bici__specs { grid-row: 4; }
  .js .bici--grande .bici__precio { grid-column: 2; grid-row: 6; text-align: left; font-size: 1.75rem; margin-top: 1rem; }
  .js .bici--grande .boton { grid-column: 2; grid-row: 7; justify-self: start; }
  .js .bici--grande .bici__ficha { grid-row: 8; }
}
.config__vistas, .config__grupo { min-width: 0; margin: 0; padding: 0; border: 0; }
.config__rotulo { padding: 0; margin: 0 0 .5rem; font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); }
.vistas { display: flex; gap: .75rem; }
.vista { position: relative; flex: none; display: grid; gap: .3rem; cursor: pointer; }
.vista input, .opcion input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; }
.vista img { width: 5.75rem; height: auto; aspect-ratio: 4 / 3; object-fit: contain; background: #FEFEFE; box-shadow: inset 0 0 0 1px var(--linea); transition: box-shadow var(--d-rapido) var(--ease); }
.vista span { font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .04em; color: var(--tinta-2); }
.vista:has(input:checked) img { box-shadow: inset 0 0 0 2px var(--cobalto); }
.vista:has(input:checked) span { color: var(--cobalto-texto); }
.vista:has(input:focus-visible), .opcion:has(input:focus-visible) { outline: 2px solid var(--cobalto); outline-offset: 3px; }
.config__grupos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.75rem; }
/* cada opción es un rótulo; la elegida lleva debajo una cota (línea con sus dos topes) que se traza */
.opcion { position: relative; display: flex; justify-content: space-between; align-items: baseline; gap: .75rem; padding: .45rem 0 .6rem; cursor: pointer; font-size: .875rem; line-height: 1.3; color: var(--tinta-2); }
.opcion__precio { flex: none; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .02em; white-space: nowrap; }
.opcion::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 7px; border-inline: 1.5px solid var(--cobalto); background: linear-gradient(var(--cobalto), var(--cobalto)) 0 50% / 100% 1.5px no-repeat; transform: scaleX(0); transform-origin: 0 50%; transition: transform 420ms var(--plotter); }
.opcion:hover { color: var(--tinta); }
.opcion:has(input:checked) { color: var(--tinta); font-weight: 600; }
.opcion:has(input:checked) .opcion__precio { color: var(--cobalto-texto); font-weight: 500; }
.opcion:has(input:checked)::after { transform: scaleX(1); }
.bici__geo { width: 100%; height: auto; overflow: visible; }
.gb-tubo { fill: none; stroke: var(--tinta); stroke-width: 10; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; }
.gb-sillin { fill: var(--tinta); }
.gb-cota { fill: none; stroke: var(--cobalto); stroke-width: 6; stroke-dasharray: 1; }
.bici__datos { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem 1.25rem; }
.bici__datos div { display: grid; gap: .1rem; align-content: start; }
.bici__datos dt { font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); }
.bici__datos dd { margin: 0; font-size: .9375rem; font-weight: 600; line-height: 1.3; font-variant-numeric: tabular-nums; }
.vacio { padding: 3rem 0; }
.vacio__titulo { font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: 1.5rem; margin: 0 0 .5rem; }

/* ------------------------------------------------------------ la talla, dibujada */
.talla { display: grid; grid-template-columns: minmax(18rem, .8fr) minmax(0, 1.2fr); gap: clamp(2rem, 5vw, 5rem); align-items: start; padding: clamp(3rem, 5vw, 4.5rem) var(--margen); background: linear-gradient(rgb(255 255 255 / 0), var(--blanco) clamp(5rem, 9vw, 9rem)); border-bottom: 1px solid var(--linea); }
.talla__texto > p { max-width: 42ch; color: var(--tinta-2); margin: 1.25rem 0 2rem; }
.deslizador { display: grid; gap: .25rem; margin-bottom: 1.25rem; }
.deslizador label { display: flex; justify-content: space-between; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); }
.deslizador output { color: var(--tinta); font-weight: 500; }
.resultado { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.5rem; margin: 2rem 0; padding: 1.5rem 0; border-block: 1px solid var(--linea); }
.resultado div { display: grid; gap: .2rem; }
.resultado dt { font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); }
.resultado dd { margin: 0; font-stretch: 125%; font-weight: 800; font-size: 1.375rem; font-variant-numeric: tabular-nums; }
.resultado__talla { color: var(--cobalto); font-size: 2.75rem !important; line-height: 1; }
.resultado__talla.es-cambio { animation: golpe 520ms var(--muelle); }
.talla__nota { font-size: .875rem; color: var(--tinta-2); max-width: 42ch; margin: 1rem 0 0; }
.talla__plano { margin: 0; }
.geo { width: 100%; height: auto; overflow: visible; }
.geo__rejilla line { stroke: var(--rejilla-fuerte); stroke-width: 1.5; }
.geo__rueda { fill: none; stroke: var(--tinta); stroke-width: 9; }
.geo__llanta { fill: none; stroke: var(--tinta-2); stroke-width: 3; stroke-dasharray: 10 14; }
.geo__plato { fill: none; stroke: var(--tinta); stroke-width: 6; }
.geo__tubo { fill: none; stroke: var(--tinta); stroke-width: 15; stroke-linecap: round; stroke-linejoin: round; }
.geo__tubo--fino { stroke-width: 9; }
.geo__sillin { fill: var(--tinta); }
.geo__cota { fill: none; stroke: var(--cobalto); stroke-width: 3; }
.geo__cota--acento { stroke: var(--tinta); stroke-dasharray: 12 8; }
.geo text { font-family: var(--f-dato); font-size: 44px; fill: var(--cobalto-texto); font-weight: 500; paint-order: stroke; stroke: var(--blanco); stroke-width: 10px; }
.geo .geo__txt-acento { fill: var(--tinta); }
.talla__plano figcaption { margin-top: 1rem; }

/* ------------------------------------------------------------ rótulos de sección («03 · Detalle A») */
.seccion-n { display: flex; align-items: center; gap: .65rem; margin-bottom: 1rem; color: var(--cobalto-texto); }
.seccion-n::before { content: ""; width: 1.75rem; height: 1.5px; background: var(--cobalto); flex: none; }

/* ------------------------------------------------------------ detalle A: la transmisión a escala 2:1 */
.detalle { display: grid; grid-template-columns: minmax(16rem, .62fr) minmax(0, 1.38fr); gap: clamp(2rem, 5vw, 5rem); align-items: center; padding: clamp(4rem, 8vw, 7rem) var(--margen); }
.detalle__texto > p:not(.seccion-n):not(.detalle__escala) { max-width: 38ch; color: var(--tinta-2); margin: 1.25rem 0 0; }
.detalle__escala { display: flex; align-items: baseline; gap: .75rem; margin: 2.5rem 0 0; padding-top: 1rem; border-top: 1px solid var(--linea); }
.detalle__escala-n { font-stretch: 125%; font-weight: 800; font-size: clamp(2.4rem, 4.4vw, 4rem); line-height: 1; font-variant-numeric: tabular-nums; color: var(--cobalto); }
/* la figura es contenedor: las llamadas se colocan en unidades de su ancho (cqw), sin medir en JS */
.detalle__foto { position: relative; margin: 0; container-type: inline-size; aspect-ratio: 4 / 3; box-shadow: var(--e2); background: var(--tinta); --z: 0; --s: calc(1 + (var(--escala, 2) - 1) * var(--z)); }
.detalle__zoom { position: absolute; inset: 0; overflow: hidden; }
.detalle__zoom > * { position: absolute; inset: 0; width: 100%; height: 100%; transform: scale(var(--s)); transform-origin: var(--ox, 50%) var(--oy, 50%); }
.detalle__zoom img { object-fit: cover; }
.detalle__circulo { overflow: visible; pointer-events: none; display: none; }
.detalle__circulo circle { fill: none; stroke: var(--cobalto); stroke-width: .3; }
.detalle__circulo text { font-family: var(--f-dato); font-size: 3.6px; font-weight: 500; fill: var(--cobalto-texto); paint-order: stroke; stroke: var(--blanco); stroke-width: .9px; stroke-linejoin: round; }
.detalle__llamadas { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; display: none; }
.detalle__llamadas path { fill: none; stroke: var(--cobalto); stroke-width: .25; }
.llamada { position: absolute; z-index: 1; left: calc(var(--lx) * 1%); top: calc(var(--ly) * .75cqw); translate: 0 -50%; max-width: 13rem; margin: 0; padding: .3rem .55rem; background: var(--blanco); color: var(--tinta); font-family: var(--f-dato); font-size: .75rem; line-height: 1.3; letter-spacing: .04em; pointer-events: none; }
/* la que sale hacia la izquierda se ancla por la derecha: así, si no cabe, parte línea en vez de salirse */
.llamada--izq { left: auto; right: calc(100% - var(--lx) * 1%); }
.detalle__pie { position: absolute; top: 100%; left: 0; margin-top: .9rem; }
.punto { position: absolute; left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); z-index: 2; width: 2rem; height: 2rem; margin: -1rem 0 0 -1rem; border-radius: 50%; border: 0; background: var(--cobalto); color: var(--blanco); cursor: pointer; display: grid; place-items: center; box-shadow: 0 0 0 3px var(--blanco); transition: transform var(--d-base) var(--muelle), background-color var(--d-rapido);
  /* con zoom, el punto viaja con su pieza: (destino − origen) × --z, en unidades del ancho de la figura */
  translate: calc((var(--zx, var(--x)) - var(--x)) * var(--z) * 1cqw) calc((var(--zy, var(--y)) - var(--y)) * var(--z) * .75cqw); }
.punto::before { content: "+"; font-weight: 700; font-size: 1.25rem; line-height: 1; transition: transform var(--d-base) var(--muelle); }
.punto::after { content: ""; position: absolute; inset: 0; border-radius: 50%; box-shadow: 0 0 0 2px var(--cobalto); animation: pulso 2.2s var(--ease) infinite; }
.punto[aria-expanded="true"] { background: var(--tinta); }
.punto[aria-expanded="true"]::before { transform: rotate(45deg); }
.punto:hover { transform: scale(1.12); }
@keyframes pulso { 0% { transform: scale(1); opacity: .8; } 100% { transform: scale(2.4); opacity: 0; } }
.punto__nota {
  position: absolute; left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); z-index: 3; margin: 1.5rem 0 0 -1rem; max-width: 16rem; padding: .75rem 1rem;
  background: var(--tinta); color: var(--blanco); font-size: .875rem; line-height: 1.4; box-shadow: var(--e2);
  translate: calc((var(--zx, var(--x)) - var(--x)) * var(--z) * 1cqw) calc((var(--zy, var(--y)) - var(--y)) * var(--z) * .75cqw);
  opacity: 0; transform: translateY(-6px) scale(.96); transform-origin: 1rem 0; pointer-events: none;
  transition: opacity var(--d-base) var(--ease), transform var(--d-base) var(--ease);
}
.punto[aria-expanded="true"] + .punto__nota { opacity: 1; transform: none; pointer-events: auto; }
.punto__nota--izq { left: auto; right: calc(100% - var(--x) * 1%); margin: 1.5rem -1rem 0 0; transform-origin: calc(100% - 1rem) 0; }

/* ------------------------------------------------------------ el taller: la Tramo se monta pieza a pieza */
.taller { padding: 0 var(--margen); border-top: 1px solid var(--linea); }
.taller__fijo { display: grid; grid-template-columns: minmax(17rem, 24rem) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; gap: 1.5rem clamp(2rem, 4vw, 4rem); padding: clamp(3rem, 6vw, 5rem) 0 2rem; }
.taller__texto { align-self: center; }
/* titulares en columnas estrechas: cada corte cabe entero en su línea (lab/cortes.mjs lo mide a 5 anchos) */
.detalle .titulo-seccion { font-size: clamp(1.5rem, 2.45vw, 2.5rem); }
.taller .titulo-seccion { font-size: clamp(1.5rem, 2.2vw, 2.05rem); } /* tope: «SALE DEL TALLER» cabe en la columna de 24rem */
.carta .titulo-seccion { font-size: clamp(1.6rem, 2.85vw, 3.4rem); }
.montaje { list-style: none; margin: 2rem 0 0; padding: 0; }
.montaje li { display: grid; grid-template-columns: 2.25rem minmax(0, 1fr); column-gap: .85rem; align-items: baseline; padding: .5rem 0; border-top: 1px solid var(--linea); }
.montaje li:last-child { border-bottom: 1px solid var(--linea); }
.montaje__n { grid-row: span 2; align-self: center; display: grid; place-items: center; height: 1.6rem; font-family: var(--f-dato); font-size: .75rem; font-weight: 500; color: var(--blanco); background: var(--tinta); }
.montaje__que { font-stretch: 112%; font-weight: 700; font-size: .9375rem; line-height: 1.25; }
.montaje__spec { font-family: var(--f-dato); font-size: .75rem; color: var(--tinta-2); }
/* con movimiento, la hoja de montaje sigue al dibujo: pendiente (hueco), en curso (cobalto), hecho (tinta) */
.mov .montaje li .montaje__n { background: transparent; color: var(--tinta-2); box-shadow: inset 0 0 0 1px var(--tinta-2); }
.mov .montaje li.es-actual .montaje__n { background: var(--cobalto); color: var(--blanco); box-shadow: none; }
.mov .montaje li.es-hecho .montaje__n { background: var(--tinta); color: var(--blanco); box-shadow: none; }
/* la caja del dibujo es suya y de nadie más: el SVG la llena exactamente (se escala por el lado que mande) y nada
   sale de ella; su viewBox abarca la extensión medida de TODA la línea de tiempo (despiece, rótulos y el zum del
   final), así que el recorte nunca corta el dibujo. El margen con la columna y con la lista es el hueco de la rejilla */
.taller__plano { position: relative; min-height: 0; min-width: 0; overflow: hidden; }
.taller__dibujo { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden; }
.taller__lectura { position: absolute; top: 0; right: 0; margin: 0; display: flex; align-items: baseline; gap: .6rem; }
.taller__paso { font-stretch: 125%; font-weight: 800; font-size: 1.75rem; line-height: 1; font-variant-numeric: tabular-nums; color: var(--cobalto); }
.taller__rodillo { position: absolute; right: 0; bottom: 0; margin: 0; display: flex; align-items: baseline; gap: .6rem; }
.taller__rodillo-n { font-stretch: 125%; font-weight: 800; font-size: 2.5rem; line-height: 1; font-variant-numeric: tabular-nums; }
.t-borde { fill: none; stroke: var(--tinta); stroke-width: 22; stroke-linecap: round; stroke-linejoin: round; }
.t-alma { fill: none; stroke: var(--papel); stroke-width: 11; stroke-linecap: round; stroke-linejoin: round; }
.t-borde.t-fino { stroke-width: 15; } .t-alma.t-fino { stroke-width: 6; }
.r-cubierta { fill: none; stroke: var(--tinta); stroke-width: 7; }
.r-taco { fill: none; stroke: var(--tinta); stroke-width: 24; stroke-dasharray: 6 10; }
.r-flanco { fill: none; stroke: var(--tinta); stroke-width: 3; }
.r-llanta { fill: none; stroke: var(--tinta-2); stroke-width: 5; }
.r-radios { fill: none; stroke: var(--tinta-2); stroke-width: 2; }
.r-disco { fill: none; stroke: var(--tinta); stroke-width: 5; stroke-dasharray: 14 6; }
.r-buje { fill: var(--papel); stroke: var(--tinta); stroke-width: 5; }
.r-eje { fill: var(--cobalto); }
.x-plato { fill: none; stroke: var(--tinta); stroke-width: 7; }
.x-dientes { fill: none; stroke: var(--tinta); stroke-width: 11; stroke-dasharray: 4 5; }
.x-arana { fill: none; stroke: var(--tinta); stroke-width: 7; stroke-linecap: round; }
.x-cassette { fill: none; stroke: var(--tinta); stroke-width: 3; }
.x-cadena { fill: none; stroke: var(--tinta-2); stroke-width: 7; stroke-dasharray: 9 5; }
.x-jaula { fill: none; stroke: var(--tinta); stroke-width: 7; stroke-linejoin: round; }
.x-polea { fill: var(--papel); stroke: var(--tinta); stroke-width: 4; }
.x-sillin { fill: var(--tinta); }
.pieza__rotulo { opacity: 0; }
/* el plano del héroe dentro del taller: solo existe con la capa de movimiento (sin ella, el taller se ve montado) */
.taller__plano-heroe { display: none; }
.mov .taller__plano-heroe { display: inline; }
.taller__plano-heroe path { fill: none; stroke: var(--cobalto); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.taller__plano-heroe .trazo__fino { stroke-width: 2; }
.rotulo__guia { fill: none; stroke: var(--cobalto); stroke-width: 3; }
.rotulo__punto { fill: var(--cobalto); }
.pieza__rotulo text { font-family: var(--f-dato); font-size: 38px; font-weight: 500; fill: var(--tinta); paint-order: stroke; stroke: var(--papel); stroke-width: 12px; stroke-linejoin: round; }
.pieza__rotulo .rotulo__num { fill: var(--cobalto-texto); }
.pieza__rotulo .rotulo__spec { font-size: 30px; font-weight: 400; fill: var(--tinta-2); }
.servicios { grid-column: 1 / -1; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 2rem; border-top: 1.5px solid var(--tinta); }
.servicios li { display: flex; flex-direction: column; gap: .35rem; padding: .9rem 0 0; font-size: .9375rem; line-height: 1.35; }
.servicios__precio { font-family: var(--f-dato); font-size: .8125rem; letter-spacing: .06em; text-transform: uppercase; color: var(--cobalto-texto); font-weight: 500; }
.servicios__iva { margin-left: .35em; font-size: .6875rem; font-weight: 400; letter-spacing: .08em; } /* como el «IVA incluido» de los precios de bici: mismo color que la cifra */

/* ------------------------------------------------------------ del taller a la pista: galería horizontal */
.ruta { border-top: 1px solid var(--linea); }
.ruta__fijo { display: grid; grid-template-rows: auto minmax(0, 1fr); padding: clamp(3rem, 6vw, 5rem) 0 2rem; }
.ruta__cabeza { display: flex; justify-content: space-between; align-items: end; gap: 2rem; padding: 0 var(--margen) 2rem; }
.ruta__contador { margin: 0; display: flex; align-items: baseline; gap: .4rem; line-height: 1; }
.ruta__km { display: inline-block; text-align: left; font-stretch: 125%; font-weight: 800; font-size: clamp(3.5rem, 8vw, 7.5rem); line-height: .8; font-variant-numeric: tabular-nums; color: var(--cobalto); contain: layout paint; }
.ruta__ventana { position: relative; overflow: hidden; outline-offset: -3px; }
.ruta__carril { width: max-content; padding: 0 var(--margen); }
.ruta__pista { list-style: none; margin: 0; padding: 0; display: flex; align-items: start; gap: clamp(1.5rem, 3vw, 3rem); }
.foto-ruta figure { margin: 0; }
.foto-ruta__marco { position: relative; overflow: hidden; height: var(--h-ruta, min(52vh, 32vw)); aspect-ratio: 4 / 3; background: var(--tinta); box-shadow: var(--e2); }
.foto-ruta__lienzo { position: absolute; left: calc(var(--px) * 100%); top: calc(var(--py) * 100%); translate: calc(var(--px) * -100%) calc(var(--py) * -100%);
  width: max(116%, calc(100% * var(--ar) * .75)); aspect-ratio: var(--ar); }
.foto-ruta__capa { position: absolute; inset: 0; } /* la capa es la que se desliza (paralaje); el lienzo solo coloca */
.foto-ruta__lienzo img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; }
.foto-ruta figcaption { max-width: 34ch; margin-top: .9rem; font-size: .9375rem; line-height: 1.4; color: var(--tinta); }
.foto-ruta figcaption .dato { display: block; margin-bottom: .25rem; color: var(--cobalto-texto); }
/* la regla de la ruta: de margen a margen, se llena con el avance real del carril; sus marcas son los km de cada foto */
.ruta__regla { position: relative; height: 2.6rem; margin: 1.25rem var(--margen) 0; border-top: 1.5px solid var(--tinta);
  background-image: linear-gradient(90deg, var(--tinta-2) 1px, transparent 1px); background-size: 24px .6rem; background-repeat: repeat-x; }
.ruta__avance { position: absolute; left: 0; right: 0; top: -1.5px; height: 3px; background: var(--cobalto); transform: scaleX(var(--avance, 1)); transform-origin: 0 50%; }
.ruta__marca { position: absolute; top: .85rem; left: calc(var(--p) * 100%); translate: calc(var(--p) * -100%) 0; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .06em; color: var(--tinta-2); }
.ruta__marca::before { content: ""; position: absolute; left: calc(var(--p) * 100%); top: -.85rem; width: 1.5px; height: .7rem; background: var(--tinta); }

/* ------------------------------------------------------------ fotos anotadas como un plano */
.anota { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.anota__linea { fill: none; stroke: var(--blanco); stroke-width: 2.5; stroke-linecap: square; }
.anota__punto { fill: var(--blanco); stroke: var(--cobalto); stroke-width: 3; }
.anota__rotulo { position: absolute; left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); translate: 0 -50%; margin: 0; padding: .22rem .5rem; background: var(--blanco); color: var(--tinta); font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .04em; line-height: 1.3; white-space: nowrap; pointer-events: none; box-shadow: inset 2px 0 0 var(--cobalto); }
.anota__rotulo--izq { translate: -100% -50%; box-shadow: inset -2px 0 0 var(--cobalto); }
.anota__rotulo--cen { translate: -50% -50%; box-shadow: none; }
.mov .anota__linea { stroke-dasharray: 1; stroke-dashoffset: 1; }
.mov .anota__punto, .mov .anota__rotulo { opacity: 0; }

/* ------------------------------------------------------------ la pista: meseta a sangre y su perfil */
.pista { position: relative; height: max(40rem, 100vh); overflow: hidden; display: grid; align-content: start; justify-items: start; }
.pista__foto { --alto: max(40rem, 100vh); position: absolute; inset: 0; overflow: hidden; }
/* el lienzo mide lo que la foto entera cubriendo la sección (el alto se conoce: --alto) y la encuadra con --px/--py */
.pista__lienzo { --px: .5; --py: .5; position: absolute; left: calc(var(--px) * 100%); top: calc(var(--py) * 100%); translate: calc(var(--px) * -100%) calc(var(--py) * -100%);
  width: max(100%, calc(var(--alto) * 1.7778)); aspect-ratio: 2048 / 1152; }
.pista__capa { position: absolute; inset: 0; transform-origin: 78% 70%; }
.pista__img { position: absolute; inset: 0; width: 100%; height: 100%; }
.pista__texto { position: relative; z-index: 2; margin: calc(var(--cabecera) + 1rem) var(--margen) 0; max-width: 30rem; padding: 2rem; background: var(--blanco); box-shadow: var(--e3); }
.pista__titulo { margin: 0 0 1rem; font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: clamp(1.6rem, 2.3vw, 2.1rem); line-height: .98; } /* tope: «PRUÉBALA ANTES» cabe en la tarjeta de 30rem */
.pista__texto > p:not(.seccion-n) { margin: 0 0 1.5rem; color: var(--tinta-2); }
.pista__texto .boton--claro { background: var(--cobalto); color: var(--blanco); }
.pista__texto .boton--claro:hover { background: var(--tinta); }
.pista__perfil { position: absolute; left: 0; right: 0; bottom: -1px; height: 34vh; min-height: 15rem; z-index: 1; }
.perfil__lienzo { position: absolute; inset: 0; }
.perfil { position: absolute; inset: 0; width: 100%; height: 100%; }
.perfil__relleno { fill: var(--papel); }
.perfil__niveles, .perfil__km { fill: none; stroke: var(--cobalto); stroke-width: 1; opacity: .16; vector-effect: non-scaling-stroke; }
.perfil__linea { fill: none; stroke: var(--cobalto); stroke-width: 2.5; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.perfil__rotulos { position: absolute; left: 0; right: 0; bottom: .6rem; margin: 0; height: 1rem; font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .06em; color: var(--tinta-2); }
.perfil__rotulos span { position: absolute; left: calc(var(--x) * 1%); translate: -50% 0; }
.perfil__pluma { position: absolute; left: 0; top: 0; width: .8rem; height: .8rem; margin: -.4rem 0 0 -.4rem; border-radius: 50%; background: var(--cobalto); box-shadow: 0 0 0 3px var(--papel); display: none; }
.pista__cifras { position: absolute; right: var(--margen); bottom: .9rem; z-index: 2; margin: 0; display: grid; grid-template-columns: repeat(3, auto); background: var(--papel); box-shadow: inset 0 0 0 1.5px var(--tinta); }
.pista__cifras div { display: grid; gap: .25rem; padding: .7rem 1.25rem .8rem; }
.pista__cifras div + div { box-shadow: inset 1px 0 0 var(--tinta); }
.pista__cifras dt { font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); }
.perfil__rotulos span:nth-child(n+3) { display: none; } /* 60 y 80 km quedarían bajo el cajetín */
.pista__cifras dd { margin: 0; display: flex; align-items: baseline; gap: .35rem; white-space: nowrap; }
.pista__u { font-family: var(--f-dato); font-size: .8125rem; font-weight: 500; color: var(--tinta-2); }
.pista__n { display: inline-block; min-width: 2ch; font-family: var(--f-texto); font-stretch: 125%; font-weight: 800; font-size: clamp(2rem, 3.2vw, 3rem); line-height: 1; font-variant-numeric: tabular-nums; text-align: right; color: var(--tinta); contain: layout paint; }

/* ------------------------------------------------------------ la carta: una postal con la ruta del mes y su sello */
.carta { padding: clamp(4rem, 8vw, 7rem) var(--margen); display: grid; grid-template-columns: minmax(0, .85fr) minmax(20rem, 1.15fr); gap: 2.5rem clamp(2rem, 5vw, 5rem); align-items: center; }
.carta__texto > p:not(.seccion-n) { max-width: 38ch; color: var(--tinta-2); margin: 1.25rem 0 0; }
.postal { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); min-height: clamp(19rem, 27vw, 23rem); background: var(--blanco); box-shadow: var(--e2); }
.postal__ruta { display: grid; align-content: space-between; gap: 1.25rem; padding: 1.5rem clamp(1.25rem, 2.5vw, 2rem); border-right: 1.5px dashed rgb(15 17 21 / .28); }
.postal__remite { margin: 0; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .04em; color: var(--tinta-2); }
.postal__perfil { width: 100%; height: 6rem; overflow: visible; }
.postal__rejilla { fill: none; stroke: var(--cobalto); stroke-width: 1; opacity: .16; vector-effect: non-scaling-stroke; }
.postal__relleno { fill: rgb(31 59 255 / .06); }
.postal__linea { fill: none; stroke: var(--cobalto); stroke-width: 2; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.postal__datos { display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; margin: 0; }
.postal__datos div { display: grid; gap: .1rem; }
.postal__datos dt { font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); }
.postal__datos dd { margin: 0; font-stretch: 125%; font-weight: 800; font-size: 1.125rem; font-variant-numeric: tabular-nums; }
.postal__destino { position: relative; display: grid; align-content: end; padding: 7.5rem clamp(1.25rem, 2.5vw, 2rem) 1.25rem; }
.postal .carta__fila { flex-direction: column; align-items: flex-start; gap: .9rem; }
.postal .carta__fila input { flex: none; width: 100%; }
.postal__sello { position: absolute; top: 1.25rem; right: 1.25rem; width: 5.25rem; padding: 5px; background: var(--cobalto); transform: rotate(3deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, radial-gradient(circle 3px, #0000 96%, #000) -4px -4px / 8px 8px round; mask: linear-gradient(#000 0 0) content-box, radial-gradient(circle 3px, #0000 96%, #000) -4px -4px / 8px 8px round; }
.postal__sello svg { width: 100%; height: auto; }
.sello__papel { fill: var(--cobalto); } .sello__marco { fill: none; stroke: var(--blanco); stroke-width: 1.5; }
.sello__rueda { fill: none; stroke: var(--blanco); stroke-width: 3.5; } .sello__biela { stroke: var(--blanco); stroke-width: 4; stroke-linecap: round; } .sello__eje { fill: var(--blanco); }
.postal__sello text { font-family: var(--f-texto); font-stretch: 125%; font-weight: 800; font-size: 12px; letter-spacing: .06em; fill: var(--blanco); }
.postal__sello .sello__valor { font-family: var(--f-dato); font-weight: 500; font-size: 8px; font-stretch: 100%; }
.postal__matasellos { position: absolute; top: .6rem; right: 3.4rem; width: 9.5rem; pointer-events: none; opacity: 0; transform: rotate(-9deg); }
.postal__matasellos svg { width: 100%; height: auto; overflow: visible; }
.postal__matasellos circle, .postal__matasellos path { fill: none; stroke: var(--tinta); stroke-width: 2.2; }
.postal__matasellos text { font-family: var(--f-dato); font-size: 10px; font-weight: 500; letter-spacing: .06em; fill: var(--tinta); }
.postal.es-sellado .postal__matasellos { opacity: .88; }
.carta__form label { display: block; font-family: var(--f-dato); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-2); margin-bottom: .25rem; }
.carta__fila { display: flex; align-items: end; gap: 1rem; }
.carta__fila input { flex: 1; min-width: 0; height: 3rem; padding: 0 .25rem; border: 0; border-radius: 0; background: transparent; box-shadow: inset 0 -1.5px 0 var(--tinta); font-family: var(--f-dato); font-size: 1.0625rem; }
.carta__fila input::placeholder { color: #6B7280; }
.carta__fila input:focus-visible { outline: 2px solid var(--cobalto); outline-offset: 2px; }
.carta__fila input[aria-invalid="true"] { box-shadow: inset 0 -2px 0 #B3261E; }
.carta__estado { min-height: 1.5rem; margin: .6rem 0 0; font-size: .9375rem; }
.carta__estado.es-error { color: #B3261E; }
.carta__estado.es-ok { color: var(--cobalto-texto); font-weight: 600; }
.carta__form.es-temblor .carta__fila { animation: temblor 420ms var(--ease); }
@keyframes temblor { 20% { transform: translateX(-8px); } 40% { transform: translateX(7px); } 60% { transform: translateX(-4px); } 80% { transform: translateX(2px); } }

/* ------------------------------------------------------------ pie */
.pie { background: var(--tinta); color: #C8CDD6; padding: clamp(3rem, 6vw, 5rem) var(--margen) 5rem; display: grid; grid-template-columns: auto 1fr; gap: 1.5rem 4rem; }
.pie__marca { display: flex; align-items: center; gap: .6rem; color: var(--blanco); grid-row: span 3; align-self: start; }
.pie__marca .logo__biela { color: var(--blanco); }
.pie__lista { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem 2rem; font-family: var(--f-dato); font-size: .8125rem; }
.pie__legal { margin: 0; max-width: 70ch; font-size: .9375rem; color: var(--blanco); } /* una sola tinta: los enlaces se distinguen por el subrayado */
.pie .pie__legal a { color: inherit; text-decoration: underline; text-underline-offset: .2em; }
.pie a { color: var(--blanco); font-weight: 600; }


/* ------------------------------------------------------------ cesta */
.velo { position: fixed; inset: 0; z-index: 40; background: rgb(15 17 21 / .45); opacity: 0; transition: opacity 300ms var(--ease); }
.velo.es-visible { opacity: 1; }
.cesta {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 50; width: min(28rem, 100vw);
  display: grid; grid-template-rows: auto auto 1fr auto; background: var(--blanco); box-shadow: var(--e3);
  transform: translateX(104%); transition: transform 460ms var(--cajon); visibility: hidden;
}
.cesta.es-abierta { transform: none; visibility: visible; }
.cesta__cabeza { display: flex; justify-content: space-between; align-items: center; padding: 1.25rem 1.5rem; border-bottom: 1px solid var(--linea); }
.cesta__cabeza h2 { margin: 0; font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: 1.375rem; }
.cesta__cerrar { width: 2.75rem; height: 2.75rem; display: grid; place-items: center; background: none; border: 0; cursor: pointer; }
.cesta__cerrar svg { width: 1.4rem; height: 1.4rem; transition: transform 300ms var(--muelle); }
.cesta__cerrar:hover svg { transform: rotate(90deg); }
.cesta__envio { padding: 1rem 1.5rem; border-bottom: 1px solid var(--linea); font-size: .875rem; }
.cesta__envio p { margin: 0 0 .6rem; }
.cesta__barra { height: 4px; background: var(--papel); overflow: hidden; }
.cesta__barra span { display: block; height: 100%; background: var(--cobalto); transform: scaleX(var(--avance, 0)); transform-origin: 0 50%; transition: transform 600ms var(--ease); }
.cesta__lista { list-style: none; margin: 0; padding: .5rem 1.5rem; overflow-y: auto; }
.linea-cesta { display: grid; grid-template-columns: 6rem 1fr auto; gap: 1rem; align-items: start; padding: 1rem 0; border-bottom: 1px solid var(--linea); animation: entra-linea 420ms var(--ease) both; }
@keyframes entra-linea { from { opacity: 0; transform: translateX(24px); } }
.linea-cesta img { width: 6rem; height: auto; background: var(--papel); }
.linea-cesta__nombre { margin: 0; font-stretch: 125%; font-weight: 800; text-transform: uppercase; }
.linea-cesta__variante { margin: .15rem 0 .6rem; font-family: var(--f-dato); font-size: .75rem; color: var(--tinta-2); }
.linea-cesta__opciones { list-style: none; margin: -.3rem 0 .7rem; padding: 0; display: grid; gap: .2rem; font-size: .8125rem; line-height: 1.3; color: var(--tinta); }
.linea-cesta__opciones li::before { content: "+ "; color: var(--cobalto-texto); font-family: var(--f-dato); }
.linea-cesta__opciones span { font-family: var(--f-dato); font-size: .75rem; color: var(--cobalto-texto); white-space: nowrap; }
.linea-cesta__precio { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; }
.paso { display: inline-flex; align-items: center; box-shadow: inset 0 0 0 1px var(--linea); }
.paso button { width: 2rem; height: 2rem; border: 0; background: none; cursor: pointer; font-size: 1.1rem; }
.paso button:hover { background: var(--papel); }
.paso output { min-width: 2rem; text-align: center; font-family: var(--f-dato); font-size: .875rem; }
.linea-cesta__quitar { display: block; margin-top: .5rem; background: none; border: 0; padding: 0; font-size: .8125rem; color: var(--tinta-2); text-decoration: underline; text-underline-offset: .2em; cursor: pointer; }
.linea-cesta__quitar:hover { color: var(--tinta); }
.cesta__vacia { padding: 2.5rem 1.5rem; }
.cesta__vacia[hidden] { display: none; }
.cesta__vacia-titulo { font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: 1.25rem; margin: 0 0 .5rem; }
.cesta__vacia a { color: var(--cobalto-texto); font-weight: 600; }
.cesta__pie { padding: 1.25rem 1.5rem 1.5rem; border-top: 1px solid var(--linea); background: var(--papel); }
.cesta__totales { margin: 0 0 1rem; }
.cesta__totales div { display: flex; justify-content: space-between; padding: .25rem 0; }
.cesta__totales dt { color: var(--tinta-2); }
.cesta__totales dd { margin: 0; font-variant-numeric: tabular-nums; }
.cesta__total { font-weight: 700; font-size: 1.125rem; padding-top: .5rem !important; margin-top: .25rem; border-top: 1px solid var(--linea); }
.cesta__total dt { color: var(--tinta) !important; }
.cesta__pie .boton { width: 100%; }

/* la bici que vuela a la cesta: primero en X, luego en Y, como el cabezal de un plóter, dejando su trazo */
.vuelo { position: fixed; z-index: 60; pointer-events: none; mix-blend-mode: multiply; }
/* la foto que viaja a la ficha grande: en coordenadas de la página, por debajo de la cabecera */
.vuelo--ficha { position: absolute; z-index: 3; transform-origin: 0 0; }
/* miniatura que vuela a la cesta: opaca, sobre el texto; la foto multiplica sobre su papel */
.vuelo--mini { width: 88px; height: 66px; padding: 4px; background: var(--papel); box-shadow: inset 0 0 0 1px var(--cobalto), var(--e2); mix-blend-mode: normal; transform-origin: 50% 50%; }
.vuelo--mini img { display: block; width: 100%; height: 100%; object-fit: contain; mix-blend-mode: multiply; }
/* la selección del catálogo: la ficha fantasma (papel con contorno cobalto) viaja por debajo de las fichas; el hueco
   que deja la elegida se marca con un contorno punteado hasta que aterriza */
.rejilla { position: relative; }
.rejilla > .bici { z-index: 1; }
.ficha-fantasma { position: absolute; z-index: 0; pointer-events: none; }
.ficha-fantasma > i { position: absolute; inset: 0; }
.ficha-fantasma__borde { background: var(--cobalto); }
.ficha-fantasma__papel { background: var(--blanco); }
.bici.es-hueco::after { content: ""; position: absolute; inset: 0; border: 1.5px dashed var(--cobalto); background: rgb(255 255 255 / .55); pointer-events: none; }
.vuelo-trazo { position: fixed; inset: 0; z-index: 59; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.vuelo-trazo path { fill: none; stroke: var(--cobalto); stroke-width: 1.5; stroke-dasharray: 1; }

.dialogo { max-width: 30rem; border: 0; padding: 2rem; background: var(--blanco); color: var(--tinta); box-shadow: var(--e3); }
.dialogo::backdrop { background: rgb(15 17 21 / .5); }
.dialogo h2 { margin: 0 0 1rem; font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: 1.75rem; line-height: 1; }
.dialogo p { margin: 0 0 1.25rem; }
.dialogo[open] { animation: aparece 320ms var(--muelle); }
@keyframes aparece { from { opacity: 0; transform: translateY(12px) scale(.96); } }

/* menú de tableta y teléfono */
.boton-menu { display: none; height: 2.75rem; padding: 0 1rem; background: none; border: 0; box-shadow: inset 0 0 0 1.5px var(--tinta); font-weight: 600; font-size: .9375rem; cursor: pointer; }
.boton-menu:hover { background: var(--tinta); color: var(--blanco); }
.menu-movil { margin: 0 0 0 auto; height: 100%; max-height: none; width: min(22rem, 100vw); border: 0; padding: 1.25rem 1.5rem; background: var(--blanco); box-shadow: var(--e3); }
.menu-movil::backdrop { background: rgb(15 17 21 / .45); }
.menu-movil[open] { animation: entra-menu 420ms var(--cajon); }
@keyframes entra-menu { from { transform: translateX(100%); } }
.menu-movil__cierra { display: flex; justify-content: flex-end; margin-bottom: 1rem; }
.menu-movil nav { display: grid; counter-reset: menu; }
.menu-movil nav a { position: relative; display: flex; align-items: baseline; gap: .9rem; counter-increment: menu; border-bottom: 0 !important; }
.menu-movil nav a::before { content: counter(menu, decimal-leading-zero); font-family: var(--f-dato); font-size: .75rem; font-weight: 500; letter-spacing: .04em; color: var(--cobalto-texto); }
.menu-movil nav a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; background: var(--cobalto); transform-origin: 0 50%; }
.menu-movil[open] nav a::after { animation: traza-menu 460ms var(--plotter) both; animation-delay: calc(var(--i, 0) * 60ms + 120ms); }
.menu-movil[open] nav a::before { animation: aparece-menu 200ms linear both; animation-delay: calc(var(--i, 0) * 60ms + 320ms); }
@keyframes traza-menu { from { transform: scaleX(0); } }
@keyframes aparece-menu { from { opacity: 0; } }
.menu-movil nav a { padding: 1rem 0; border-bottom: 1px solid var(--linea); color: var(--tinta); text-decoration: none; font-stretch: 125%; font-weight: 800; text-transform: uppercase; font-size: 1.25rem; }
.menu-movil nav a:hover { color: var(--cobalto); }

/* ------------------------------------------------------------ aviso de IA (contrato del 2026-10-01)
   A · la nota de cajetín («Nota» + la frase literal). Sin JS: al principio de la página, en el flujo y fija (no tapa
   nada). Con JS la lleva biela.js a la foto del héroe al empezar la intro (que ya descubre la foto): al hueco de papel de arriba a la izquierda
   (sin cotas ni bici: x < 43 %, y < 13,8 % de la foto, donde empieza el sillín) si cabe; si no, a la banda de abajo, sobre las ruedas y por encima de la
   cota de batalla. Entra barrida, como el ¾ del configurador, y a los 7 s (de pestaña visible) se va barrida.
   B · la marca de cada pieza IA: un rótulo de anotación (como .anota__rotulo, pero a 12 px) en una esquina; se escribe a saltos de
   carácter cuando la pieza se ve y a los 1,8 s se barre. Sin JS, fija: el distintivo de siempre.
   Retiradas (.es-retirado) quedan recortadas como .sr: fuera de la vista y dentro del árbol de accesibilidad. */
.aviso-ia { position: relative; max-width: 46rem; margin: 1rem var(--margen) 0; padding: .4rem .7rem .45rem; background: var(--blanco); box-shadow: inset 0 0 0 1px var(--cobalto); color: var(--tinta); font-size: .875rem; font-stretch: 87.5%; line-height: 1.3; }
.aviso-ia::before { content: "Nota" / ""; margin-right: .6em; font-family: var(--f-dato); font-size: .6875rem; font-stretch: 100%; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--cobalto-texto); }
.js .aviso-ia { position: absolute; z-index: 3; left: 0; top: 0; width: 42%; max-width: 27rem; margin: 0; pointer-events: none; opacity: 0; clip-path: inset(0 100% 0 0); transition: clip-path 420ms var(--plotter); }
.js .aviso-ia.es-banda { top: auto; bottom: 9.5%; width: 88%; max-width: 42rem; }
.js .aviso-ia.es-suelto { position: fixed; top: auto; left: var(--margen); bottom: 1rem; width: min(27rem, calc(100vw - 2 * var(--margen))); max-width: none; }
.js .aviso-ia.es-visible { opacity: 1; clip-path: inset(0); }
.js .aviso-ia.es-sale { clip-path: inset(0 0 0 100%); }
.marca-ia { position: absolute; z-index: 3; left: .6rem; top: .55rem; margin: 0; padding: .18rem .45rem .2rem .55rem; background: var(--blanco); color: var(--tinta-2); box-shadow: inset 2px 0 0 var(--cobalto); font-family: var(--f-dato); font-size: .75rem; font-weight: 400; font-stretch: 100%; letter-spacing: .04em; line-height: 1.3; text-transform: none; white-space: nowrap; pointer-events: none; }
.heroe__foto > .marca-ia { left: auto; right: 0; top: 0; } /* arriba a la derecha: a la izquierda va la nota */
.pista__foto > .marca-ia { left: auto; right: var(--margen); top: calc(var(--cabecera) + 1rem); } /* a la izquierda va la tarjeta */
/* galería y Detalle A, abajo a la izquierda: la mitad de arriba de esas fotos lleva sus rótulos y llamadas («Potencia ·
   5 N·m», «Manillar · 440 mm», «Cubierta 45 mm», «Cadena de 12 v») y con el paralaje se mueven; abajo a la izquierda no
   hay ninguno en todo el recorrido, a 1920, 1440, 1280, 1024, 768 y 390 (medido) */
:is(.foto-ruta__marco, .detalle__foto) > .marca-ia { top: auto; bottom: .55rem; }
.js .marca-ia { opacity: 0; clip-path: inset(0 100% 0 0); transition: clip-path 300ms steps(15); }
.js .marca-ia.es-visible { opacity: 1; clip-path: inset(0); }
.js .marca-ia.es-sale { clip-path: inset(0 0 0 100%); transition: clip-path 300ms var(--plotter); }
.js :is(.aviso-ia, .marca-ia).es-retirado { width: 1px !important; height: 1px; max-width: none; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } /* manda sobre el ancho de cada modo */
@media (max-width: 640px) {
  .js .aviso-ia.es-banda { width: 100%; max-width: none; }
  .heroe__foto > .marca-ia { left: 0; right: auto; } /* en el teléfono la nota va abajo y la cota de arriba ocupa el centro */
  .pista__foto > .marca-ia { top: .6rem; }
}
/* teléfono estrecho (≤ 370) o apaisado (≤ 500 de alto): la cota «Reach» de arriba llega a los dos lados; la marca y
   «Saltar intro» bajan a la fila de debajo (sobre la foto, donde no hay rótulos) */
@media (max-width: 370px), (max-height: 500px) {
  .heroe .heroe__foto > .marca-ia { top: 2.1rem; }
}
@media (max-width: 370px) {
  .heroe .intro__saltar { top: 2.1rem; }
  /* la cabecera entera en 320: logotipo (icono y nombre), «Menú» y la cesta, sin encoger el icono */
  .cabecera { gap: .75rem; }
  .cabecera__acciones { gap: .5rem; }
  .logo { gap: .4rem; }
  .logo span { font-size: 1.25rem; }
  /* fichas: la línea de datos se parte antes que empujar el precio fuera de la ficha (a 320 se salía hasta 53 px) */
  .bici article { grid-template-columns: minmax(0, 1fr) auto; }
  .bici__specs span { white-space: normal; }
  /* cifras de la pista: las tres caben en su cajetín («% grava» se salía) */
  .pista .pista__cifras div { padding: .45rem .5rem .5rem; }
  .pista .pista__n { font-size: 1.25rem; }
  .pista .pista__u { font-size: .6875rem; }
}
@media (prefers-reduced-motion: reduce) { .js :is(.aviso-ia, .marca-ia), .js :is(.aviso-ia, .marca-ia).es-sale { transition: none !important; } }

/* ==========================================================================
   MOVIMIENTO
   .js  = hay JavaScript: la tienda funciona.
   .mov = además manda la capa de movimiento (GSAP, js/movimiento.js). La pone el script en línea si
          NO se pide movimiento reducido, y se quita sola a los 3 s si movimiento.js no ha arrancado.
   Sin .mov (reducido, o GSAP caído) queda la entrada ligera de siempre (.ha-entrado, por IO).
   Sin JS no hay ni .js ni .mov: nada se esconde. Solo transform, opacity, clip-path y stroke-dashoffset.
   ========================================================================== */
/* --- entrada ligera (sin .mov) */
.js:not(.mov) .a-telon { clip-path: inset(0 0 100% 0); transform: translateY(.4em); transition: clip-path 900ms var(--cajon), transform 900ms var(--cajon); }
.js:not(.mov) .ha-entrado.a-telon, .js:not(.mov) .ha-entrado .a-telon { clip-path: inset(0 0 -10% 0); transform: none; }
.js:not(.mov) .bici { opacity: 0; transform: translateY(28px); transition: opacity 500ms var(--ease), transform 700ms var(--ease); transition-delay: calc(var(--i, 0) * 80ms); }
.js:not(.mov) .bici.ha-entrado { opacity: 1; transform: none; }
.js:not(.mov) .heroe__img, .js:not(.mov) .cotas { translate: -7% 0; transition: opacity 420ms var(--ease), translate 1300ms cubic-bezier(0.16, 1, 0.3, 1); }
.js:not(.mov) .heroe.ha-entrado .heroe__img, .js:not(.mov) .heroe.ha-entrado .cotas { translate: 0 0; }
.js:not(.mov) .heroe__ficha > * { opacity: 0; transform: translateY(16px); transition: opacity 500ms var(--ease), transform 700ms var(--ease); transition-delay: calc(var(--i, 0) * 70ms + 250ms); }
.js:not(.mov) .heroe.ha-entrado .heroe__ficha > * { opacity: 1; transform: none; }

/* --- las cotas del héroe (las dos capas): arrancan sin dibujar */
.js .cota__linea, .js .cota__marca { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 900ms var(--ease); transition-delay: calc(var(--o) * 170ms + 700ms); }
.js .cota__ext { opacity: 0; transition: opacity 600ms var(--ease); transition-delay: calc(var(--o) * 170ms + 600ms); }
.js .cota text, .js .cota circle { opacity: 0; transition: opacity 400ms var(--ease); transition-delay: calc(var(--o) * 170ms + 1200ms); }
.js .heroe.ha-entrado .cota__linea, .js .heroe.ha-entrado .cota__marca { stroke-dashoffset: 0; }
.js .heroe.ha-entrado .cota__ext { opacity: .45; }
.js .heroe.ha-entrado .cota text, .js .heroe.ha-entrado .cota circle { opacity: 1; }
.js .heroe.es-redibujo .cota__linea, .js .heroe.es-redibujo .cota__marca { transition: none; stroke-dashoffset: 1; }
/* las fotos del catálogo y del héroe se funden al decodificarse */
.js .bici__foto img, .js .heroe__img { opacity: 0; }
.js .bici__foto img.es-decodificada { opacity: 1; transition: opacity 700ms var(--ease); }
.js .heroe__img.es-visible.es-decodificada { opacity: 1; }
.js:not(.mov) .heroe:not(.ha-entrado) .heroe__img.es-visible { opacity: 0; }
/* guías de puntos de los servicios del taller */
.js .servicios li { opacity: 0; transform: translateY(10px); transition: opacity 400ms var(--ease), transform 600ms var(--ease); transition-delay: calc(var(--i, 0) * 90ms + 200ms); }
.js .ha-entrado .servicios li { opacity: 1; transform: none; }

/* --- la intro del héroe (con .mov, hasta que html[data-intro="hecha"]): el plano se traza y la foto aparece DENTRO */
.trazo { display: none; }
.trazo path { fill: none; stroke: var(--cobalto); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.trazo .trazo__fino { stroke-width: 2; }
.mov:not([data-intro="hecha"]) .trazo { display: inline; }
.mov:not([data-intro="hecha"]) .trazo path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.mov:not([data-intro="hecha"]) .heroe__img { clip-path: url(#heroe-mascara); }
/* la salida: con .es-sale la foto vuelve a pasar por la máscara (sus círculos los encoge el scroll) y el plano reaparece */
.mov .heroe.es-sale .heroe__img { clip-path: url(#heroe-mascara); transition: none; }
.mov .heroe.es-sale .trazo { display: inline; }
.mov .heroe.es-sale .trazo path { stroke-dasharray: 1; }
.mov:not([data-intro="hecha"]) :is(.heroe__cuenta, .heroe__compra) > * { opacity: 0; }
.mov:not([data-intro="hecha"]) .heroe .cota__linea, .mov:not([data-intro="hecha"]) .heroe .cota__marca { stroke-dashoffset: 1; }
.mov:not([data-intro="hecha"]) .heroe .cota__ext, .mov:not([data-intro="hecha"]) .heroe .cota text, .mov:not([data-intro="hecha"]) .heroe .cota circle { opacity: 0; }
.mov:not([data-intro="hecha"]) .heroe .cota *, .mov:not([data-intro="hecha"]) .heroe__img { transition: none !important; }
.mascara-def { position: absolute; width: 0; height: 0; overflow: hidden; }
.intro__saltar { position: absolute; left: 0; bottom: 0; z-index: 3; padding: .5rem .8rem; border: 0; background: var(--blanco); box-shadow: inset 0 0 0 1px var(--tinta); cursor: pointer; font-family: var(--f-dato); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--tinta); }
.intro__saltar:hover { background: var(--tinta); color: var(--blanco); }

/* --- títulos partidos por líneas (SplitText; se deshace al terminar) */
.mov .a-telon:not(.es-listo) { visibility: hidden; }
.linea-partida-mask { padding: .14em 0 .06em; margin: -.14em 0 -.06em; display: inline-block !important; width: 100%; vertical-align: top; } /* en línea: los márgenes negativos de dos líneas seguidas no se colapsan, y el titular partido mide lo mismo que recompuesto (si no, al recomponerse la página subía 2 px) */

/* --- catálogo: la ficha se imprime (contorno de plóter + relleno de arriba abajo); al pasar, su batalla */
.bici { position: relative; }
.bici__trazo { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.bici__trazo path { fill: none; stroke: var(--cobalto); stroke-width: 1.5; stroke-dasharray: 1; stroke-dashoffset: 1; }
.bici__cota { position: absolute; left: calc(var(--eje-t, 22.3) * 1%); right: calc((100 - var(--eje-d, 76.8)) * 1%); top: 70.4%; bottom: 2.5%; pointer-events: none; } /* ejes medidos en cada render: lab/medir-ejes.mjs */
.bici--grande .bici__cota::before { transform: scaleX(1); }
.bici--grande .bici__cota i { transform: scaleY(1); }
.bici--grande .bici__cota b { opacity: 1; }
.bici__cota::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; background: var(--cobalto); transform: scaleX(0); transform-origin: 0 50%; transition: transform 520ms var(--plotter) 60ms; }
.bici__cota i { position: absolute; top: 0; bottom: -5px; width: 1px; background: repeating-linear-gradient(var(--cobalto) 0 4px, transparent 4px 7px); transform: scaleY(0); transform-origin: 50% 0; transition: transform 380ms var(--plotter); }
.bici__cota i:first-of-type { left: 0; } .bici__cota i:last-of-type { right: 0; }
.bici__cota b { position: absolute; left: 50%; bottom: .45rem; translate: -50% 0; padding: .1rem .35rem; background: var(--blanco); font-family: var(--f-dato); font-weight: 500; font-size: .6875rem; letter-spacing: .04em; color: var(--cobalto-texto); white-space: nowrap; opacity: 0; transition: opacity 240ms var(--ease) 380ms; }
@media (hover: hover) and (pointer: fine) {
  .bici article:hover .bici__cota::before, .bici__foto:focus-visible .bici__cota::before { transform: scaleX(1); }
  .bici article:hover .bici__cota i, .bici__foto:focus-visible .bici__cota i { transform: scaleY(1); }
  .bici article:hover .bici__cota b, .bici__foto:focus-visible .bici__cota b { opacity: 1; }
}
/* sin ratón (táctil): la ficha que cruza el centro de la pantalla se acota sola, con el mismo gesto que el ratón al pasar
   (lámina que se desliza, ficha que se levanta, batalla que se traza); la marca la pone biela.js */
.bici:not(.bici--grande).es-acotada article { box-shadow: var(--e3); transform: translateY(-3px); }
.bici:not(.bici--grande).es-acotada .bici__lamina { transform: translateX(3.5%); }
.bici.es-acotada .bici__cota::before { transform: scaleX(1); }
.bici.es-acotada .bici__cota i { transform: scaleY(1); }
.bici.es-acotada .bici__cota b { opacity: 1; }

/* --- la cesta: el contador hace «tic» como un cuentakilómetros (el número real está siempre en el DOM) */
.boton-cesta__n { position: relative; overflow: hidden; }
.boton-cesta__n.es-tic { color: transparent; }
.boton-cesta__n.es-tic::before, .boton-cesta__n.es-tic::after { position: absolute; inset: 0; display: grid; place-items: center; color: var(--blanco); }
.boton-cesta:hover .boton-cesta__n.es-tic::before, .boton-cesta:hover .boton-cesta__n.es-tic::after { color: var(--cobalto); }
.boton-cesta__n.es-tic::before { content: attr(data-antes); animation: tic-sale 380ms var(--plotter) both; }
.boton-cesta__n.es-tic::after { content: attr(data-ahora); animation: tic-entra 380ms var(--plotter) both; }
@keyframes tic-sale { to { transform: translateY(-110%); } }
@keyframes tic-entra { from { transform: translateY(110%); } }

/* --- detalle A: con .mov el círculo y las llamadas existen; los puntos viajan con el zoom */
.mov .detalle__circulo, .mov .detalle__llamadas { display: block; }
.mov .detalle__circulo circle, .mov .detalle__llamadas path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.mov .llamada { opacity: 0; } /* estado de partida en CSS: un fromTo escalonado solo pinta el primero */

/* --- el taller y la ruta: con .mov y pantalla ancha y alta se fijan a la altura de la ventana (menos la cabecera);
   en el resto, ver «escena» más abajo */
@media (min-width: 901px) and (min-height: 600px) {
  .mov .taller__fijo { height: calc(100vh - var(--cabecera)); }
  .mov .taller__plano { height: 100%; }
  /* la lectura con ancho fijo (el de «Potencia y manillar»): el «Paso n/7» no baila a izquierda y derecha con cada nombre */
  .mov .taller__lectura { width: 17.5em; }
  .mov .ruta__fijo { height: calc(100vh - var(--cabecera)); }
  /* fijada, la galería cabe entera en la pantalla: las fotos miden lo que queda tras cabecera, titular, pies y regla
     (si no, el carril desbordaba hacia arriba y las fotos tapaban el titular y el contador) */
  .mov .ruta { --h-ruta: clamp(11rem, calc(100vh - 31rem), min(52vh, 32vw)); }
  .mov .ruta__ventana { align-self: stretch; }
}

/* --- la pista: el perfil se revela de izquierda a derecha con su pluma */
.mov .perfil__pluma { display: block; }

/* --- la carta: sello y matasellos */
.postal.es-sellado .postal__matasellos { animation: matasella 420ms var(--plotter) both; }
@keyframes matasella { 0% { opacity: 0; transform: rotate(-4deg) scale(1.35); } 60% { opacity: .88; transform: rotate(-9deg) scale(.98); } 100% { opacity: .88; transform: rotate(-9deg) scale(1); } }

/* ------------------------------------------------------------ tableta */
@media (max-width: 1080px) {
  .menu { display: none; }
  .cabecera { grid-template-columns: auto 1fr; }
  .cabecera__acciones { justify-self: end; }
  .boton-menu { display: inline-flex; align-items: center; }
  .catalogo__cabeza { grid-template-columns: 1fr; }
  .orden { grid-row: auto; grid-column: 1; flex-wrap: wrap; }
  .rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .talla, .carta { grid-template-columns: 1fr; }
}
@media (max-width: 1100px) {
  .heroe { grid-template-columns: 1fr; min-height: 0; max-height: none; gap: 1rem; }
  .heroe__foto { width: min(100%, calc(52svh * 1.3333)); }
}
@media (max-width: 1100px) and (min-width: 641px) {
  .heroe__ficha { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 2rem; align-items: start; }
  .heroe__titulo { font-size: clamp(2rem, 4.2vw, 2.6rem); }
}
/* ------------------------------------------------------------ teléfono y tableta estrecha: nada se fija */
@media (max-width: 900px) {
  .detalle { grid-template-columns: 1fr; } /* a partir de 901 se fija: en dos columnas cabe en la pantalla */
  .taller__fijo { grid-template-columns: 1fr; grid-template-rows: none; }
  /* sin fijar (teléfono): el SVG vuelve al flujo, con su proporción, entre la lectura del paso y la del rodillo */
  .taller__dibujo { position: relative; inset: auto; height: auto; aspect-ratio: 2605 / 1740; }
  .servicios { grid-template-columns: 1fr 1fr; gap: 0 1.25rem; }
  .servicios li { padding-bottom: .9rem; }
  .ruta__cabeza { flex-direction: column; align-items: start; gap: 1rem; }
  .ruta__ventana { overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-left: var(--margen); scrollbar-width: none; }
  .ruta__ventana::-webkit-scrollbar { display: none; }
  .foto-ruta { scroll-snap-align: start; }
  .foto-ruta__marco { height: auto; width: 78vw; }
  .foto-ruta figcaption { max-width: 78vw; }
  /* la grande, con las opciones debajo de la foto: la foto se queda pegada bajo la cabecera mientras se eligen (el
     cambio se ve al elegir) y hasta que acaba su ficha; el precio, junto al botón, cierra las opciones */
  .js .bici--grande .bici__foto { position: sticky; top: var(--cabecera); z-index: 2; margin-bottom: .25rem; padding-bottom: .75rem; background: var(--blanco); }
  .js .bici--grande .bici__precio { grid-column: 1; grid-row: 6; align-self: center; text-align: left; }
}
/* ------------------------------------------------------------ escena (contrato de dispositivos, 2026-10-02)
   Teléfono, tableta vertical y pantallas bajas (teléfono apaisado): Detalle A, taller y galería se fijan también
   (movimiento.js, MODOS: mismo corte); aquí cada uno se coloca para que su momento quepa en la ventana. Sin .mov
   (movimiento reducido, sin JS) nada de esto aplica: queda la maqueta suelta de siempre. */
.taller__spec { display: none; }
.taller.sin-rotulos .pieza__rotulo { display: none; } /* a menos de 8 px no se leerían: la lectura dice la pieza y su apriete */
.taller.sin-rotulos .taller__spec { display: block; width: 100%; min-height: 1.35em; line-height: 1.35; text-transform: none; letter-spacing: .02em; } /* su línea, siempre: si no, el dibujo cambiaría de alto al aparecer */
@media (max-width: 900px), (max-height: 599px) {
  /* Detalle A: la foto nunca más alta de lo que deja la ventana con su escala y su pie */
  .mov .detalle__foto { width: min(100%, calc((100svh - var(--cabecera) - 10rem) * 4 / 3)); }
  /* el taller: la hoja de montaje se lee al pasar; se fija el dibujo, con su lectura (paso, pieza) encima y el rodillo debajo */
  .mov .taller__fijo { grid-template-columns: 1fr; grid-template-rows: none; height: auto; }
  .mov .taller__plano { display: flex; flex-direction: column; gap: .5rem; height: min(calc(100svh - var(--cabecera) - 2rem), calc((100vw - 2 * var(--margen)) / 1.4971 + 7rem)); }
  .mov .taller__dibujo { position: relative; inset: auto; flex: 1 1 0; min-height: 0; width: 100%; height: auto; aspect-ratio: auto; }
  .mov .taller__lectura, .mov .taller__rodillo { position: static; margin: 0; flex-wrap: wrap; }
  .mov .taller__lectura { order: -1; }
  .mov .taller__rodillo { align-self: flex-end; }
  /* la galería: el carril lo mueve el scroll vertical, no la mano */
  .mov .ruta__ventana { overflow: hidden; scroll-snap-type: none; }
  .mov .foto-ruta__marco { height: auto; width: min(78vw, calc((100svh - var(--cabecera) - 17rem) * 4 / 3)); }
}
/* pantalla baja y apaisada: Detalle A en dos columnas (la escala junto a la foto) y en la galería el pie va al lado de
   la foto (si no, la foto quedaría en una tira) */
@media (max-height: 599px) and (orientation: landscape) and (min-width: 600px) {
  .mov .detalle { grid-template-columns: minmax(0, 1fr) auto; gap: 2rem; padding-block: 1.25rem; }
  .mov .detalle__foto { width: auto; height: calc(100svh - var(--cabecera) - 4.5rem); }
  .mov .detalle__escala { margin-top: 1rem; }
  .mov .ruta__fijo { padding-block: 1rem .5rem; }
  .mov .ruta__cabeza { flex-direction: row; align-items: end; padding-bottom: 1rem; }
  .mov .foto-ruta figure { display: flex; align-items: end; gap: 1rem; }
  .mov .foto-ruta__marco { width: auto; height: calc(100svh - var(--cabecera) - 9.5rem); }
  .mov .foto-ruta figcaption { flex: none; width: 14rem; max-width: none; margin: 0; }
}
/* ------------------------------------------------------------ dedo: objetivos de 44 px como mínimo (contrato de dispositivos).
   Se agranda la zona que se toca, no el dibujo: el punto del Detalle A sigue siendo un disco de 32 px */
@media (pointer: coarse) {
  .logo, .cabecera__talla, .elige__ayuda { display: inline-flex; align-items: center; min-height: 2.75rem; }
  .muestra { width: 2.75rem; height: 2.75rem; }
  .filtro, .catalogo .orden__abre, .orden select, input[type="range"], .paso button { height: 2.75rem; }
  .paso button { width: 2.75rem; }
  .intro__saltar, .linea-cesta__quitar { min-height: 2.75rem; }
  .linea-cesta__quitar { min-width: 2.75rem; }
  .menu a, .bici .boton, .boton { min-height: 2.75rem; }
  .opcion { min-height: 2.75rem; align-items: center; }
  .punto { width: 2.75rem; height: 2.75rem; margin: -1.375rem 0 0 -1.375rem; padding: .375rem; background-clip: content-box; }
  .punto::after { inset: .375rem; }
  .pie__legal a { padding-block: .875rem; }
}
/* pantalla vertical: la foto de la pista se encuadra sobre la Tramo, que está a la derecha */
@media (max-aspect-ratio: 1/1) and (min-width: 641px) { .pista__lienzo { --px: .9; } .pista__perfil { height: 24vh; } }
@media (max-width: 640px) {
  :root { --cabecera: 3.5rem; }
  .cabecera__talla { display: none; }
  .boton-cesta span:first-of-type:not(.boton-cesta__n) { display: none; }
  .rejilla { grid-template-columns: minmax(0, 1fr); }
  .bici--grande { grid-column: auto; grid-row: auto; }
  .heroe__foto { width: 100%; }
  .filtros { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none; margin-inline: calc(var(--margen) * -1); padding-inline: var(--margen); scroll-padding-inline: var(--margen); }
  .filtros::-webkit-scrollbar { display: none; }
  .filtro { flex: none; scroll-snap-align: start; }
  .orden__abre { display: inline-flex; align-items: center; gap: .5rem; justify-self: start; height: 2.5rem; padding: 0 1rem; border: 0; background: var(--blanco); box-shadow: inset 0 0 0 1px var(--linea); font-family: var(--f-dato); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; cursor: pointer; }
  .orden__abre::after { content: ""; width: .5rem; height: .5rem; border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: translateY(-.15rem) rotate(45deg); transition: transform var(--d-base) var(--ease); }
  .orden__abre[aria-expanded="true"]::after { transform: translateY(.1rem) rotate(-135deg); }
  .orden:not(.es-abierto) { display: none; }
  .bici__cota b { display: none; } /* a 390 la etiqueta taparía los neumáticos: quedan las líneas */
  .bici--grande .bici__ficha { grid-template-columns: 1fr; }
  .config__grupos { grid-template-columns: minmax(0, 1fr); }
  .vistas { overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none; }
  .vistas::-webkit-scrollbar { display: none; }
  .vista { scroll-snap-align: start; }
  .visor__cota { font-size: .6875rem; padding: .22rem .45rem; }
  .cotas text { font-size: 58px; stroke-width: 14px; }
  .cota--nota { display: none; }
  .cota:nth-child(3), .cota:nth-child(5) { display: none; }  /* stack (se sale por la derecha) y ángulo: no caben legibles en 390 px; el 1.º hijo es el plano */
  .pie { grid-template-columns: 1fr; }
  .pie__marca { grid-row: auto; }
  .intro__saltar { top: 0; bottom: auto; left: auto; right: 0; } /* a la izquierda va la marca de IA del héroe (y abajo, la nota) */
  .talla .boton--grande { width: 100%; font-size: .875rem; padding: 0 1rem; }
  .resultado dd { font-size: 1.125rem; }
  .talla__plano { order: -1; position: sticky; top: calc(var(--cabecera) + 8px); z-index: 3; height: 30svh; display: grid; grid-template-rows: minmax(0, 1fr) auto; margin: 0 calc(var(--margen) * -1); padding: .5rem var(--margen) .4rem; background: var(--blanco); border-bottom: 1px solid var(--linea); }
  .talla__plano .geo { height: 100%; width: 100%; }
  .talla__plano figcaption { margin-top: .25rem; }
  .geo text { font-size: 78px; stroke-width: 16px; }
  .taller__lectura { position: static; margin-bottom: .5rem; }
  .taller__rodillo { position: static; margin-top: .5rem; }
  .pista { height: auto; display: block; }
  .pista__foto { --alto: 125vw; position: relative; inset: auto; width: 100%; height: 125vw; }
  .pista__lienzo { --px: .86; }
  .anota__rotulo--escritorio { display: none; }
  .pista__perfil { top: calc(125vw - 11rem); bottom: auto; height: 11rem; min-height: 0; }
  .pista__texto { margin: 0; max-width: none; box-shadow: none; }
  .perfil__rotulos { display: none; }
  .pista__cifras { left: var(--margen); right: var(--margen); bottom: .6rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pista__cifras div { padding: .5rem .7rem .55rem; }
  .pista__n { font-size: 1.5rem; }
  .postal { grid-template-columns: 1fr; }
  .postal__ruta { border-right: 0; border-bottom: 1.5px dashed rgb(15 17 21 / .28); }
  .postal__matasellos { width: 7.5rem; right: 2.75rem; }
  .postal__sello { width: 4.25rem; }
  .postal__destino { padding-top: 6.5rem; }
  .carta__fila { flex-direction: column; align-items: stretch; }
}

/* ------------------------------------------------------------ movimiento reducido: todo a la vista, solo fundidos */
@media (prefers-reduced-motion: reduce) {
  .aviso-envio__cinta, .cinta-specs__pista { animation: none; }
  .punto::after { animation: none; }
  .js .a-telon, .js .bici, .js .servicios li, .js .heroe__foto, .js .heroe__ficha > * { transform: none !important; clip-path: none !important; transition-property: opacity; }
  .js .cota__linea, .js .cota__marca, .js .cota__ext { transition-duration: 0ms; }
  .js .heroe__img, .js .cotas { translate: 0 0; }
  .bici__foto img, .bici__lamina, .tallas__marca, .cesta, .muestra, .logo__biela, .bici__cota::before, .bici__cota i { transition-duration: 0ms !important; }
  .menu-movil[open] { animation: none; }
  .menu-movil[open] nav a::after, .menu-movil[open] nav a::before { animation: none; }
  .opcion::after, .vista img, .visor { transition: none; }
  .boton-cesta__n.es-tic::before, .boton-cesta__n.es-tic::after { animation: none; }
  .postal.es-sellado .postal__matasellos { animation: none; }
  /* la galería se desliza a mano, como en el teléfono */
  .ruta__ventana { overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-left: var(--margen); }
  .foto-ruta { scroll-snap-align: start; }
}
