/* ═══════════════════════════════════════════════════════════════════════
   CORTE TÉCNICO — estilos de las piezas (bloque 02, 7 sep 2026)

   De dónde sale: es el bloque `.vp-*` de
   `herramienta-configurador/css/estilos.css`, que es el que ya publica el
   configurador. No se reinventa la paleta: el corte del hero tiene que ser
   reconocible como el mismo dibujo que la herramienta, y esos colores ya
   están decididos y publicados.

   Qué cambia respecto a aquel, y por qué:
   · Aquel vive solo sobre fondo oscuro. Aquí el tema principal es el claro,
     así que lo que se apoya en el fondo lleva sus dos caras con light-dark(),
     igual que el resto de la cara nueva (bloque 01). Los METALES no cambian:
     son degradados propios de la pieza, no del tema.
   · Los degradados viven en `assets/cortes/defs.svg`, que se inyecta UNA vez
     en el documento. Por eso aquí se referencian por `url(#vpLaton)` sin
     prefijo, igual que en el configurador.

   La paleta definitiva del hero se decide en el bloque 03; esto es la base
   sobre la que se juzga.
   ═══════════════════════════════════════════════════════════════════════ */

/* 🔴 EN CAPA, Y NO SUELTO. Una regla fuera de @layer gana a las de CUALQUIER
   capa nombrada, por poca especificidad que tenga. Con esta hoja sin capa, su
   `.vp-glow { opacity: 0 }` ganaba al estado degradado del hero, que vive en
   @layer motion: la válvula se veía cerrada justo donde tenía que verse
   abierta. Lo cazó medir el camino sin animation-timeline, no leer el CSS. */
@layer reset, base, layout, componentes, motion;

@layer componentes {

.valvula-corte { width: 100%; height: auto; display: block; overflow: visible; }

/* ── el metal del cuerpo: degradado propio de la pieza, igual en los dos temas ── */
.vp-metal-laton .vp-cuerpo, .vp-metal-laton .vp-bocaIn, .vp-metal-laton .vp-bocaOut,
.vp-metal-laton .vp-bridaIn, .vp-metal-laton .vp-bridaOut { fill: url(#vpLaton); stroke: var(--vp-linea); }
.vp-metal-inox .vp-cuerpo, .vp-metal-inox .vp-bocaIn, .vp-metal-inox .vp-bocaOut,
.vp-metal-inox .vp-bridaIn, .vp-metal-inox .vp-bridaOut { fill: url(#vpInox); stroke: var(--vp-linea); }
.vp-metal-neutro .vp-cuerpo, .vp-metal-neutro .vp-bocaIn, .vp-metal-neutro .vp-bocaOut,
.vp-metal-neutro .vp-bridaIn, .vp-metal-neutro .vp-bridaOut { fill: url(#vpGris); stroke: var(--vp-linea); }

.vp-tubo, .vp-bobina { fill: url(#vpGris); stroke: var(--vp-linea); }
.vp-embolo, .vp-nucleo, .vp-vastago { fill: url(#vpAcero); stroke: var(--vp-linea); }
/* 🔴 LA MEMBRANA PILOTADA, que se dibujó y nunca se pintó.
   Las siete series de membrana (03F, 04A, 04F, X3F, X4A, X4F, X6F) llevan desde
   el 7 sep 2026 nueve piezas propias —membrana, núcleo, vástago, tapa, sus dos
   anclajes, cámara superior, piloto y purga— y ninguna tenía regla: SVG sin
   `fill` es NEGRO, así que salían como masas negras. En la ficha no se veía
   porque el corte vive en una pestaña oculta y en tema oscuro es negro sobre
   casi negro; lo destapó llevarlo a la portada, en claro y a la vista.
   La paleta no se inventa: es la del configurador, que anima esta misma
   válvula en producción (`herramienta-configurador/css/estilos.css`), pasada a
   los tokens de esta hoja. Las tres cavidades van con «el hueco», arriba. */
.vp-tapa, .vp-memAncIzq, .vp-memAncDer { fill: url(#vpGris); stroke: var(--vp-linea); }
.vp-membrana { fill: var(--vp-junta, #3A4048); stroke: #00000077; }
.vp-asientoIzq, .vp-asientoDer { fill: #5C6672; stroke: var(--vp-linea); }
.vp-junta { fill: var(--vp-junta, #3A4048); stroke: #00000066; }
.vp-roscas, .vp-espiras { stroke: var(--vp-linea); fill: none; }
.vp-muelle { stroke: #7C8794; fill: none; }
.vp-tornillos { fill: var(--vp-linea); stroke: none; }
.vp-conectorA, .vp-conectorB { fill: #39414D; stroke: var(--vp-linea); }
.vp-escape { fill: url(#vpGris); stroke: var(--vp-linea); }
.vp-liq { fill: url(#vpLiq); }

/* ── el hueco: lo que NO es metal ──
   El interior de una válvula en corte se dibuja oscuro en cualquier catálogo,
   así que sobre papel sigue siendo oscuro; solo se levanta lo justo para que
   no sea un agujero absoluto en una página clara. */
.vp-cavIn, .vp-camara, .vp-cavSup, .vp-cavOut, .vp-escapeBore,
.vp-camSup, .vp-piloto, .vp-bleed {
  fill: light-dark(#171C23, #0B0E12); stroke: none;
}

/* ── el gas ──
   Del dibujo son el color (lo decide la junta) y el grosor (el perfil de
   velocidad del caudal), y van inline en cada chorro. El ESTADO lo decide la
   página: en reposo el gas llega al asiento y para, así que `vp-gasArr` se ve
   con la opacidad que declara su carril (--op) y `vp-gasPasa` está apagado.
   El hero invierte los dos al abrir la válvula. */
.vp-gas { fill: none; stroke-width: .9; stroke-linecap: round; }
.vp-gasArr  .vp-gas { opacity: var(--op, .95); }
.vp-gasPasa .vp-gas { opacity: 0; }

/* ── señales de estado ── */
.vp-glow { fill: none; stroke: #E23B3B; stroke-width: .8; opacity: 0; }
/* el destello del asiento, RETIRADO (Mario, 10 sep 2026): quieto era una
   barra crema que no decía nada, y en movimiento competía con el fluido que
   entra en ese mismo instante. El generador lo sigue dibujando; aquí no se pinta. */
.vp-destello { display: none; }
.vp-atex rect { fill: #241D0E; stroke: #D9A441; stroke-width: .6; }
.vp-atex text { fill: #F0C14B; font-family: var(--font-mono); font-weight: 700; }
.vp-fantasma { opacity: .62; stroke-dasharray: 3 3; }

/* ── el contorno ──
   `non-scaling-stroke` es lo que impide que el trazo engorde o adelgace al
   escalar el corte: sin él, a 375 px los filos se empastan y a 1440 se
   afilan hasta desaparecer. El grosor va en px de pantalla, no en mm. */
.valvula-corte [class^="vp-"], .valvula-corte [class*=" vp-"] {
  vector-effect: non-scaling-stroke;
  stroke-width: 1.3;
}
/* el gas es la excepción: su grosor SÍ escala con la pieza, porque representa
   un caudal y no un filo. Lo declara el generador con vector-effect:none. */

:root {
  /* el filo del metal. Sobre papel el #2C333C del configurador se lee bien;
     sobre el fondo oscuro se funde con él, así que ahí sube. */
  --vp-linea: light-dark(#2C333C, #49525E);
}

}

/* ═══════════════════════════════════════════════════════════════════════
   LOS RÓTULOS DEL CORTE — bloque 09, 7 sep 2026
   Van dentro del SVG, así que su tamaño escala con el dibujo. Eso es lo que
   se quiere en desktop y NO en móvil, donde el corte se reduce a la mitad y
   el texto caería a 9 px: ahí el tamaño sube y sobran rótulos.
   ═══════════════════════════════════════════════════════════════════════ */
@layer componentes {
  .vp-rot-linea {
    stroke: var(--vp-rot-linea); stroke-width: .5;
    vector-effect: non-scaling-stroke;
  }
  .vp-rot-punto { fill: var(--brand); stroke: none; }
  .vp-rot-texto {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 3.7px; letter-spacing: .12px;
    fill: var(--vp-rot-texto);
    paint-order: stroke;
    stroke: var(--vp-rot-halo); stroke-width: 1.1px; stroke-linejoin: round;
  }
  :root {
    /* el rótulo se lee sobre el papel Y sobre el metal del cuerpo, así que
       lleva un halo del color del fondo: sin él, el texto que cae encima del
       latón se pierde. Es la misma técnica que el proyecto ya usa en sus cotas. */
    --vp-rot-texto: light-dark(#10151D, #E8EDF4);
    --vp-rot-linea: light-dark(rgba(16,21,29,.55), rgba(255,255,255,.5));
    --vp-rot-halo:  light-dark(#F2F3F6, #0B0E13);
  }

  /* 🔴 En móvil el corte mide la mitad y un rótulo de 3,7 unidades caería a
     unos 9 px. Sube a 5,4 —que da ~13 px medidos— y salen del dibujo los que
     no caben sin pisarse: quedan los cuatro que cuentan el funcionamiento.
     Ocho rótulos en 343 px de ancho no informan, tapan. */
  @media (max-width: 760px) {
    .vp-rot-texto { font-size: 5.4px; stroke-width: 1.5px; }
    .vp-rot--tubo, .vp-rot--muelle, .vp-rot--conectorA, .vp-rot--asientoIzq { display: none; }
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   EL COMPONENTE DEL CORTE ENERGIZABLE — la figura, el mando y los cinco pasos
   ─────────────────────────────────────────────────────────────────────────
   🔴 Vivía en `ficha.css`, y la portada no carga esa hoja: el corte de la
   sección 06 habría salido con el botón sin estilo y la válvula sin moverse,
   sin un solo error. Aquí lo cargan las dos. Mismas capas que tenía, así que
   la cascada de la ficha no cambia —comprobado contra sus estilos computados.
   ═══════════════════════════════════════════════════════════════════════ */
@layer componentes {
  .corte__fig { position: relative; }
}

/* ── el corte técnico dentro de la ficha ── */
@layer componentes {
  .corte__fig { margin: 0; }
  .corte__dibujo { width: 100%; height: auto; display: block; max-height: 62vh; }
  .corte__pie { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted);
                margin: 14px 0 0; line-height: 1.7; }
  .corte__pie b { color: var(--text); font-weight: 600; }
}

/* ═══════════════════════════════════════════════════════════════════════
   EL CORTE QUE SE ENERGIZA — la válvula abre delante de ti

   🔴 Las cinco cosas que pasan al energizar están documentadas en
   `assets/cortes/anatomia.json` desde el bloque 02, con su orden y su eje.
   Aquí NO se inventa ninguna: se animan esas cinco, en ese orden.

   1 · la bobina se enciende          `vp-glow`
   2 · el grupo móvil sube su carrera `vp-movil`  ← la carrera REAL del artículo
   3 · el asiento destella            `vp-destello`  ← retirado el 10 sep 2026
   4 · el gas detenido se apaga       `vp-gasArr`
   5 · el gas que pasa se enciende    `vp-gasPasa`

   ⚠️ La carrera va en una variable que escribe el generador con el valor del
   catálogo —4,75 mm en la 01F, 14,55 en la 04F—, no un número redondo igual
   para todas. Un corte que abre más de lo que la pieza abre cuenta una mentira
   a quien sabe leerlo.
   ═══════════════════════════════════════════════════════════════════════ */
@layer componentes {
  .corte__mando {
    display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px;
    margin-bottom: var(--space-md);
  }
  .corte__btn {
    display: inline-flex; align-items: center; gap: 11px;
    font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .11em;
    text-transform: uppercase; color: var(--text);
    background: var(--bg); border: 1px solid var(--line-strong);
    border-radius: 999px; padding: 11px 20px; cursor: pointer;
    transition: border-color .18s, color .18s;
  }
  .corte__btn:hover { border-color: var(--brand); }
  .corte__btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
  .corte__btn[hidden] { display: none; }
  /* el piloto: apagado en reposo, encendido con la válvula energizada */
  .corte__led {
    width: 9px; height: 9px; border-radius: 50%; flex: none;
    background: var(--line-strong); transition: background .25s, box-shadow .25s;
  }
  .corte__estado { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); }
  /* 🔴 El estado cambia de texto al energizar, y el de «energizada» es más
     largo. En la portada —765 px de columna— pasaba a una segunda línea y el
     dibujo BAJABA 29 px justo cuando alguien pulsaba para mirarlo; en la ficha
     —1.344 px— cabía en una y no se notaba. Los dos textos van apilados en la
     misma celda, el largo invisible, así que la caja mide siempre lo que el
     largo: cambia el texto, no el sitio, sea cual sea el ancho. */
  .corte__estados { display: grid; flex: 1 1 24ch; min-width: 0; }
  .corte__estados > * { grid-area: 1 / 1; margin: 0; }
  .corte__estado-molde { visibility: hidden; }

  .corte__fig.is-viva .corte__led {
    background: var(--brand); box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 22%, transparent);
  }

  /* ── los cinco pasos ── */
  /* Transiciones de SALIDA: al apagar, todo vuelve junto y rápido. Las de
     ENTRADA —la secuencia— se declaran abajo, en los selectores `.is-viva`,
     porque la transición que manda es la del estado al que se llega. */
  .corte__dibujo .vp-glow { transition: opacity .3s var(--ease-out); }
  .corte__dibujo .vp-movil { transition: transform .42s var(--e-suave); }
  .corte__dibujo .vp-movilN { transition: transform .16s var(--ease-out); }
  .corte__dibujo .vp-gasArr .vp-gas,
  .corte__dibujo .vp-gasPasa .vp-gas { transition: opacity .34s var(--ease-out); }

  /* 🔴 El grupo móvil sube por la carrera del artículo, en unidades del SVG.
     El signo es negativo porque el eje y del corte va hacia abajo y la válvula
     abre hacia arriba: con el signo cambiado, la junta se clava en el asiento
     en vez de despegar de él. */
  .corte__fig.is-viva .vp-glow { opacity: 1; }
  .corte__fig.is-viva .vp-movil { transform: translateY(calc(var(--carrera, 4.75) * -1px)); }
  .corte__fig.is-viva .vp-movilN { transform: translateY(calc(var(--carreraN, 0) * -1px)); }
  .corte__fig.is-viva .vp-gasArr .vp-gas { opacity: 0; }
  .corte__fig.is-viva .vp-gasPasa .vp-gas { opacity: var(--op, .95); }

  /* ── 🔴 B · LA SECUENCIA, que antes no se veía ─────────────────────────
     Medido el 10 sep 2026: al energizar cambiaba el 2,8 % del dibujo, todo a
     la vez y en menos de medio segundo, y el movimiento de la membrana —lo que
     la sección 06 existe para enseñar— se quedaba en dos marcas de 27×12 px.
     Mario pulsó y no vio nada. Ahora cada paso espera al anterior:
       acción directa  bobina 0 → émbolo .3 → fluido .7                (~1,05 s)
       membrana        bobina 0 → núcleo .3 → la cámara se descarga .6 →
                       membrana .9 → fluido 1.35                       (~1,7 s)
     Y la curva es `--e-suave`, sin rebote: la de antes, `cubic-bezier(.34,
     1.26, .64, 1)`, llevaba la membrana a 10,94 mm antes de volver a 10,7 —un
     2,2 % más que su carrera—. Son 0,6 px en pantalla y no se ve, pero es
     justo lo que la regla prohíbe: el corte no abre más de lo que abre la pieza.
     La CARRERA no cambia —es del catálogo y exagerarla sería mentir—; cambia
     la velocidad, que es una decisión de enseñanza. Por eso estos tiempos ya
     NO coinciden con los del configurador (0,16 y 0,42 s), y es a propósito. */
  .corte__fig.is-viva .vp-glow { transition: opacity .3s var(--ease-out); }
  .corte__fig.is-viva .vp-movil { transition: transform .45s var(--e-suave) .3s; }
  .corte__fig.is-viva .vp-gasArr .vp-gas { transition: opacity .2s var(--ease-out) .7s; }
  .corte__fig.is-viva .vp-gasPasa .vp-gas { transition: opacity .35s var(--ease-out) .7s; }

  /* la membrana pilotada: DOS movimientos, y entre ellos la descarga */
  .corte__fig.is-viva[style*="--carreraN"] .vp-movilN { transition: transform .3s var(--ease-out) .3s; }
  .corte__fig.is-viva[style*="--carreraN"] .vp-camSup { animation: corte-descarga .5s var(--ease-out) .6s; }
  .corte__fig.is-viva[style*="--carreraN"] .vp-movil { transition: transform .5s var(--e-suave) .9s; }
  .corte__fig.is-viva[style*="--carreraN"] .vp-gasArr .vp-gas,
  .corte__fig.is-viva[style*="--carreraN"] .vp-gasPasa .vp-gas { transition-delay: 1.35s; }

  /* ── 🔴 A · SEÑALAR LO QUE SE MUEVE ─────────────────────────────────────
     Una pieza de 20 px que sube medio segundo no se encuentra en un dibujo
     lleno. Lo que se mueve se pinta del rojo de marca justo cuando arranca, y
     la bobina se llena de luz en vez de llevar solo un contorno fino. El
     rojo llega con el movimiento, no antes, y al apagar vuelve de golpe.
     🔴 NO con una transición de `fill`, que fue el primer intento: partiendo
     de un degradado (`url(#vpAcero)`), Chrome deja de PINTAR la pieza mientras
     la transición espera su retardo —`getComputedStyle` sigue diciendo
     «degradado», pero en pantalla se ve la cavidad de detrás—. El núcleo
     desaparecía 0,3 s y el vástago 0,9 s antes de volver en rojo. Una
     animación de duración 0 con `forwards` no actúa durante su retardo, así
     que hasta entonces la pieza se pinta como siempre. */
  .corte__fig.is-viva .vp-glow { fill: color-mix(in srgb, #E23B3B 24%, transparent); }
  .corte__fig.is-viva .vp-embolo,
  .corte__fig.is-viva .vp-nucleo { animation: corte-rojo 0s linear .3s forwards; }
  .corte__fig.is-viva .vp-membrana,
  .corte__fig.is-viva .vp-vastago { animation: corte-rojo 0s linear .9s forwards; }
  @keyframes corte-rojo { to { fill: var(--brand); } }

  /* la cámara de arriba se vacía por el piloto: un pulso de color y vuelve */
  @keyframes corte-descarga {
    0%, 100% { fill: light-dark(#171C23, #0B0E12); }
    35% { fill: color-mix(in srgb, #E23B3B 45%, light-dark(#171C23, #0B0E12)); }
  }
}

@layer motion {
  @media (prefers-reduced-motion: reduce) {
    /* sin movimiento: el cambio ocurre igual, de golpe. La válvula sigue
       abriendo y cerrando, que es la información; lo que se quita es el viaje. */
    .corte__dibujo .vp-glow,
    .corte__dibujo .vp-movil, .corte__dibujo .vp-gasArr .vp-gas,
    .corte__dibujo .vp-gasPasa .vp-gas { transition: none; }
    .corte__dibujo .vp-movilN, .corte__fig.is-viva .vp-movilN,
    .corte__fig.is-viva .vp-movil, .corte__fig.is-viva .vp-glow,
    .corte__fig.is-viva .vp-gasArr .vp-gas, .corte__fig.is-viva .vp-gasPasa .vp-gas { transition: none; }
    /* sin viaje, pero el rojo sigue: dice qué se movió, y eso es información */
    .corte__fig.is-viva .vp-embolo, .corte__fig.is-viva .vp-nucleo,
    .corte__fig.is-viva .vp-membrana, .corte__fig.is-viva .vp-vastago { animation: corte-rojo 0s forwards; }
    .corte__fig.is-viva .vp-camSup { animation: none; }
    .corte__led { transition: none; }
  }
}

