/* Práctica: una sola mesa técnica 2,5D. A la izquierda, las piezas sueltas y la herramienta sobre la madera; en el
   centro, la placa sobre la alfombrilla ESD; a la derecha, las instrucciones. Aquí está todo lo propio de esta mesa;
   css/styles.css tiene la base común (cabecera, escena, paneles, ayudas). La madera es la misma que la del banco
   del taller 3D (el mismo archivo, así se aprovecha la caché); --wood es su tono medio mientras carga. */
.practice-page {
  --desk-texture: url('../assets/workshop/madera.webp'); --wood: #f0cba9;
  --wood-veil: rgb(255 248 238 / 30%);   /* aclara la madera sin cambiar la imagen */
  /* Halo de pieza disponible: centro crema y borde ámbar, para que se distinga sobre la madera. */
  --piece-glow: rgb(255 240 205 / 80%), rgb(var(--hint-rgb) / 30%) 45%;
}
.practice-page .app {
  height: 100vh; display: grid; gap: 12px; padding: 0 16px 12px;
  grid-template-columns: minmax(0, 1fr) minmax(290px, 330px);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "top top" "center right";
  background: linear-gradient(var(--wood-veil), var(--wood-veil)), var(--desk-texture) center top / cover no-repeat var(--wood);
}
.practice-page .topbar { grid-area: top; margin: 0 -16px; }
.practice-page .workbench { grid-area: center; --parts-width: clamp(155px, 23%, 230px); background: transparent; box-shadow: none; overflow: hidden; border-radius: 0; }
.practice-page .panel--step { grid-area: right; align-self: stretch; box-shadow: 0 2px 5px #624b291a; }
.practice-page .workbench::before {
  content: ''; position: absolute; inset: 4px 5px 0 calc(var(--parts-width) + 7px);
  border-radius: 22px; border: 1px solid #244858;
  background: radial-gradient(ellipse at 50% 45%, #d2dedf18, transparent 75%), linear-gradient(#718997bd, #637f8dbd), url('../assets/alfombrilla-esd.webp') center / 109% 122% no-repeat;
  box-shadow: 0 3px 5px #18333b35, inset 0 0 0 1px #8fb4c344;
}
/* Interior de la alfombrilla (dentro de su borde): lo ocupan el área de la placa y la capa de la pulsera. */
.practice-page .workbench { --mat-inset: 5px 6px 1px calc(var(--parts-width) + 8px); }
.practice-page .workbench .workspace { inset: var(--mat-inset); padding: 3px 12px 43px 13px; border-radius: 21px; }
/* El área de la placa cubre toda la alfombrilla (dentro de su borde) y el relleno deja el margen de la vista al
   100 % (abajo, el del zoom): con zoom, la placa llena la alfombrilla y el control queda encima. Se mueve
   arrastrando y se amplía con + / − o la rueda: sin barras de desplazamiento. */
.practice-page .workspace { scrollbar-width: none; touch-action: none; overscroll-behavior: contain; }
.practice-page .workspace::-webkit-scrollbar { display: none; }
.practice-page .scene__board { filter: drop-shadow(1px 3px 3px #142c3538); }
/* Zoom en la esquina inferior derecha de la alfombrilla (el mismo margen que tenía a la izquierda). */
.practice-page .workbench .zoom { left: auto; right: 21px; bottom: 2px; }

/* Piezas sobre la mesa: cada una en su sitio fijo (% de la franja izquierda), sin tarjetas ni rejilla. */
.practice-page .desk-parts { position: absolute; inset: 0 auto 0 0; z-index: 5; width: var(--parts-width); overflow: visible; }
.practice-page .desk-pieces { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; }
.practice-page .desk-piece-wrap { position: absolute; left: 3%; width: 84%; height: 15%; min-width: 0; display: grid; place-items: center; }
.practice-page .desk-piece-wrap--cpu { top: 5%; left: 36%; width: 43%; height: 14%; }
.practice-page .desk-piece-wrap--ram { top: 24%; left: 3%; width: 88%; height: 9%; }
.practice-page .desk-piece-wrap--ram-second { top: 35%; left: 9%; }
.practice-page .desk-piece-wrap--m2 { top: 47%; left: 14%; height: 13%; width: 76%; }
.practice-page .desk-piece-wrap--cooler { top: 62%; left: 2%; height: 19%; width: 88%; }
.practice-page .desk-piece {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; min-width: 0; padding: 5px; border: 0; border-radius: 40%; background: transparent;
  touch-action: none; user-select: none; cursor: default;
}
.practice-page .desk-piece .figure { max-width: 100%; filter: drop-shadow(1px 3px 2px #3b302a2e); }
.practice-page .desk-piece img { max-width: 100%; max-height: 100%; object-fit: contain; pointer-events: none; }
.practice-page .desk-piece--cpu .figure { width: clamp(45px, 4.4vw, 66px); }
/* RAM: los dos módulos, algo girados, uno junto al otro. */
.practice-page .desk-piece--ram .figure { flex: none; width: 100%; max-width: 100%; transform: rotate(9deg); }
.practice-page .desk-piece--ram img { width: 100%; max-width: 100%; }
.practice-page .desk-piece-wrap--ram-second .figure { transform: rotate(12deg); }
.practice-page .desk-piece--m2 .figure { width: 85%; transform: rotate(-7deg); }
.practice-page .desk-piece--cooler .figure { width: 100%; }
.practice-page .desk-piece--cooler img { max-height: 125px; }
.practice-page .desk-rotate {
  position: absolute; bottom: -2px; right: -5px; width: 28px; height: 28px; display: grid; place-items: center;
  font-size: 24px; line-height: 1; color: var(--blue); border: 1px solid var(--line); border-radius: 50%; background: #fff8eb; cursor: pointer;
}
/* Herramienta: siempre en la mesa; solo se puede coger cuando la acción la necesita. */
.practice-page .desk-tools { position: absolute; bottom: 3%; left: 5%; width: 86%; height: 17%; margin: 0; }
.practice-page .desk-tools[hidden] { display: none; }
.practice-page .desk-tools .desk-piece-wrap { inset: 0; width: 100%; height: 100%; display: block; }
.practice-page .desk-piece--tool { position: absolute; inset: 0; height: 100%; min-height: 0; padding: 10px; }
.practice-page .desk-piece--tool img { width: 100%; height: 100%; max-height: 100%; object-fit: contain; transform: rotate(-6deg); filter: drop-shadow(1px 3px 2px #3b302a2e); }
/* Estados de las piezas. */
.practice-page .desk-piece.is-available { cursor: grab; background: radial-gradient(ellipse, var(--piece-glow), transparent 70%); }
.practice-page .desk-piece.is-available:hover { filter: brightness(1.07); }
.practice-page .desk-piece.is-available:active { cursor: grabbing; }
.practice-page .desk-piece.is-selected { outline: 2px solid var(--blue); outline-offset: -4px; background: radial-gradient(ellipse, var(--blue-soft), transparent 75%); }
.practice-page .desk-piece.is-dragging { opacity: .2; }
.practice-page .desk-piece:focus-visible { outline: 3px solid var(--blue); outline-offset: 1px; }
.component-mark-on .desk-piece.is-available .mark { display: block; }
/* El tornillo del SSD, junto a la herramienta: se arrastra hasta el soporte 2242 (consumible, js/config/tools.js).
   La imagen mide 30 px, lo mismo que al arrastrarlo y que ya colocado en la placa (con el acercamiento del paso
   del SSD); el botón tiene 10 px de margen alrededor para cogerlo con facilidad. */
.practice-page .desk-screw {
  position: absolute; left: calc(var(--parts-width) - 55px); bottom: calc(18% - 16.5px); z-index: 6;
  width: 50px; height: 50px; padding: 10px; border: 0; border-radius: 50%; background: transparent;
  touch-action: none; user-select: none; cursor: default;
}
.practice-page .desk-screw[hidden] { display: none; }
.practice-page .desk-screw img { display: block; width: 100%; height: 100%; transform: rotate(-20deg); filter: drop-shadow(1px 2px 1px #3b302a35); pointer-events: none; }
.practice-page .desk-screw.is-available { cursor: grab; background: radial-gradient(circle, var(--piece-glow), transparent 70%); }
.practice-page .desk-screw.is-available:not(.is-dragging) img { animation: piece-attention 2.8s ease-in-out infinite; }
.practice-page .desk-screw.is-dragging { opacity: .2; }

.practice-page .panel__body { gap: 16px; padding: 18px; }
.practice-page .prep { padding: 13px 15px; }

/* ---------- Aspecto de laboratorio (continuidad con la tarjeta del taller 3D) ----------
   Superficies claras con un degradado casi imperceptible, borde azul suave y sombra azulada. Solo aspecto: los
   bordes nuevos van como sombra interior (no cambian medidas) y la mesa, la placa y las piezas no se tocan. */
.practice-page {
  --lab-line: rgb(var(--blue-rgb) / 24%);          /* borde azul de baja intensidad */
  --lab-line-soft: rgb(var(--blue-rgb) / 11%);     /* borde casi imperceptible de los bloques */
  --lab-glow: rgb(120 190 235 / 18%);              /* halo exterior suave */
  --lab-surface: linear-gradient(180deg, #ffffff 0%, #f5f9fc 100%);
  --lab-block: linear-gradient(180deg, #f2f7fb 0%, #eaf2f8 100%);
  --lab-shadow: 0 1px 2px rgb(var(--navy-rgb) / 8%), 0 12px 28px -10px rgb(var(--blue-rgb) / 30%);
}
/* Panel de la práctica */
.practice-page .panel--step {
  background: var(--lab-surface); border-color: rgb(88 160 218 / 58%);
  box-shadow: var(--lab-shadow), 0 0 0 4px var(--lab-glow), 0 0 26px -4px rgb(120 190 235 / 48%);
}
.practice-page .panel__head { background: linear-gradient(180deg, #1c3c5b, var(--navy)); box-shadow: inset 0 -1px 0 rgb(120 190 235 / 30%); }
.practice-page .step__title { color: var(--navy); }
/* Bloques secundarios: preparación, acción actual y ficha de revisión. */
.practice-page :is(.prep, .action, .review) {
  background: var(--lab-block);
  box-shadow: inset 0 0 0 1px var(--lab-line-soft), inset 0 1px 0 rgb(255 255 255 / 75%);
}
.practice-page .callout--tip { box-shadow: inset 0 0 0 1px rgb(var(--hint-rgb) / 16%); }
.practice-page .review-extra { border-color: var(--lab-line); }
/* Desplegables («El manual de la placa base» y preguntas): secundarios, con un leve brillo al pasar. */
.practice-page .more {
  background: var(--lab-surface); border-color: var(--lab-line);
  transition: border-color .15s, box-shadow .15s;
}
.practice-page .more:hover { border-color: rgb(var(--blue-rgb) / 42%); box-shadow: 0 0 0 3px var(--lab-glow); }
/* En el panel inicial («Sobre esta práctica», con el manual dentro) el icono ya indica el desplegable: sin la flecha. */
/* «Sobre esta práctica» en el panel inicial: abre su ventana; mismo aspecto que un desplegable, sin flecha. */
.practice-page .more--open { display: flex; align-items: center; gap: 6px; width: 100%; font: inherit; font-size: 14px; font-weight: 600; color: var(--blue); text-align: left; cursor: pointer; }
.practice-page .more--open .icon { width: 16px; height: 16px; }
/* Botones */
.practice-page .btn--primary {
  background: linear-gradient(180deg, #3678a9 0%, var(--blue) 55%, #295f8a 100%);
  border-color: #4a8cc0;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 22%), 0 0 0 3px rgb(120 190 235 / 20%), 0 6px 18px -6px rgb(var(--blue-rgb) / 75%);
  transition: filter .15s, box-shadow .15s, translate .15s;
}
.practice-page .btn--primary:hover {
  filter: brightness(1.05); translate: 0 -1px;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 24%), 0 0 0 3px rgb(120 190 235 / 28%), 0 8px 22px -6px rgb(var(--blue-rgb) / 85%);
}
.practice-page .btn--secondary { background: var(--lab-surface); box-shadow: inset 0 0 0 1.5px var(--blue), 0 4px 10px -6px rgb(var(--blue-rgb) / 40%); }
.practice-page .btn--secondary:hover { background: var(--blue-soft); }
/* Cabecera: solo el borde de Taller y Reiniciar, con un brillo mínimo al pasar. */
.practice-page .tool { box-shadow: inset 0 1px 0 rgb(255 255 255 / 8%); transition: border-color .15s, background-color .15s; }
.practice-page .tool:hover { border-color: rgb(143 187 219 / 55%); background-color: rgb(255 255 255 / 6%); }
/* Zoom: sigue oscuro; un filo claro y sombra coherentes con el panel. */
.practice-page .zoom { box-shadow: inset 0 0 0 1px rgb(143 187 219 / 22%), 0 6px 14px -6px rgb(var(--navy-rgb) / 50%); }
/* «Sobre esta práctica» (desplegable del panel inicial): texto de página, con acentos azules. */
/* Ventana «Sobre esta práctica» (#about): cabecera azul, cuerpo con su propio desplazamiento y el botón de
   comenzar al pie. Mismo lenguaje que el panel «Prácticas» del taller. */
.about-dialog {
  width: min(600px, calc(100vw - 24px)); max-height: min(86vh, 760px); padding: 0; border: 1px solid rgb(96 164 214 / 42%);
  border-radius: 14px; background: var(--surface); color: var(--ink); box-shadow: 0 18px 44px rgb(var(--navy-rgb) / 30%);
}
.about-dialog[open] { display: flex; flex-direction: column; }
.about-dialog::backdrop { background: rgb(var(--navy-rgb) / 40%); }
.about-dialog__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 12px 12px 20px; background: linear-gradient(180deg, #1c3c5b, var(--navy)); color: var(--on-dark); }
.about-dialog__head h2 { font-size: 17px; }
.about-dialog__close { display: grid; place-items: center; width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: var(--on-dark); cursor: pointer; }
.about-dialog__close:hover { background: rgb(255 255 255 / 14%); }
.about-dialog__body { overflow-y: auto; padding: 18px 22px 8px; display: grid; gap: 8px; align-content: start; font-size: 14.5px; line-height: 1.5; }
.about-dialog__title { margin-top: 8px; font-size: 15px; color: var(--navy); }
.about-dialog__body :is(ul, ol) { margin: 0; padding-left: 20px; display: grid; gap: 4px; }
.about-dialog__body li::marker { color: var(--blue); font-weight: 600; }
.about-dialog__steps { gap: 8px !important; }
.about-dialog__steps em { font-style: normal; font-weight: 600; color: var(--navy); }
.about-dialog__note { margin-top: 6px; font-size: 13.5px; color: var(--muted); }
.about-dialog__foot { display: flex; justify-content: flex-end; padding: 12px 22px 16px; border-top: 1px solid var(--line); }
@media (max-width: 960px) { .about-dialog { max-height: calc(100svh - 24px); } .about-dialog__body { padding: 16px 16px 8px; } .about-dialog__foot { padding: 12px 16px 14px; } .about-dialog__foot .btn { width: 100%; } }
.practice-page .step__noscript { padding: 10px 12px; border-radius: 8px; background: var(--hint-soft); color: var(--hint-ink); }
@media (prefers-reduced-motion: reduce) {
  .practice-page :is(.btn--primary, .more, .tool) { transition: none; }
  .practice-page .btn--primary:hover { translate: none; }
}

@media (max-width: 1100px) {
  .practice-page .app { gap: 10px; padding: 0 10px 10px; grid-template-columns: minmax(0, 1fr) minmax(260px, 29%); }
  .practice-page .topbar { margin: 0 -10px; }
  .practice-page .workbench { --parts-width: 145px; }
  .practice-page .panel__body { padding: 14px; gap: 12px; }
}
/* Layout estrecho (≤ 960 px: tablet pequeña y móvil). Por debajo de ese ancho, con dos columnas la placa
   quedaría por debajo de ~460 px; así que la mesa pasa a ocupar todo el ancho, con el panel debajo.
   Solo hay dos composiciones: ancha (mesa | panel) y estrecha (mesa / panel). */
@media (max-width: 960px) {
  .practice-page .app {
    height: auto; min-height: 100vh;
    grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto; grid-template-areas: "top" "center" "right";
  }
  /* Cabecera compacta: marca y botones en una fila si caben; si no, dos filas juntas. */
  .practice-page .topbar { flex-wrap: wrap; gap: 4px 10px; padding: 6px 12px; min-width: 0; }
  .practice-page .brand { flex: 1 1 auto; gap: 8px; }
  .practice-page .brand__logo { width: 36px; height: 36px; }
  .practice-page .brand__name { font-size: 16px; }
  .practice-page .brand__title { font-size: 12.5px; line-height: 1.35; }
  .practice-page .tools { margin-left: auto; }
  .practice-page .tool { min-height: 36px; padding: 6px 10px; font-size: 12.5px; }
  /* Mesa: la franja de piezas se adapta al ancho y la placa usa el resto. El alto es el que necesita la placa
     a ese ancho (proporción 1269/1240 + márgenes del área de trabajo y del zoom), con un mínimo para que las piezas
     de la mesa no se aprieten y sin pasar del alto de la pantalla. */
  .practice-page .workbench {
    --parts-width: clamp(100px, 18vw, 145px);
    height: max(calc(var(--parts-width) * 4), min(calc((100vw - 39px - var(--parts-width)) * 1.024 + 59px), calc(100svh - 70px)));
    min-width: 0;
  }
  .practice-page .panel--step { min-width: 0; }
  .practice-page .workbench::before { inset: 4px 0 5px calc(var(--parts-width) + 3px); border-radius: 14px; }
  .practice-page .workbench { --mat-inset: 5px 1px 6px calc(var(--parts-width) + 4px); }
  .practice-page .workbench .workspace { padding: 7px 7px 41px; border-radius: 13px; }
  .practice-page .workbench .zoom { gap: 0; right: 4px; bottom: 7px; }
  .practice-page .desk-piece--cpu .figure { width: calc(var(--parts-width) * .38); }
  .practice-page .desk-piece--cooler img { max-height: calc(var(--parts-width) * .85); }
  .practice-page .desk-screw { left: calc(var(--parts-width) - 41px); width: 44px; height: 44px; }
  .practice-page .desk-rotate { width: 24px; height: 24px; font-size: 21px; right: -12px; }
}
/* Ayudas pegadas al hardware: contorno de la ranura y de su pestaña, sin aros flotantes. */
.practice-page .highlight.look-slot .highlight__line { stroke-width: 1.5; fill: rgb(var(--board-blue-rgb) / 12%); }
.practice-page .highlight.look-slot .highlight__halo { stroke-width: 3; animation: none; }
.practice-page .highlight.look-glow .highlight__halo { stroke-width: 3; animation: none; }
.practice-page .highlight.look-glow .highlight__line { stroke-width: 1.3; animation: none; }
.practice-page .guide--m2 { display: none; }
.practice-page .mark--notch::after, .practice-page .mark--connector::after { width: 12px; height: 5px; left: -6px; top: -2px; border-radius: 1px; border-width: 1px; box-shadow: 0 0 3px rgb(var(--hint-rgb) / 45%); animation: none; }
/* La herramienta requerida destaca con luz de contacto; el tornillo conserva su señal de destino. */
.practice-page .desk-piece--tool.is-available { background: radial-gradient(ellipse, var(--piece-glow), transparent 72%); }
.practice-page .desk-piece--tool.is-available img { filter: drop-shadow(0 0 3px rgb(var(--hint-rgb) / 80%)) drop-shadow(1px 3px 2px #3b302a2e); }
/* El disipador tapa las referencias de los orificios al acercarlo o dejarlo instalado. */
.practice-page .scene.is-cooler-preview .highlight[data-for^="COOLER_HOLE_"],
.practice-page .scene.has-cooler .highlight[data-for^="COOLER_HOLE_"] { visibility: hidden; }
.ghost--cooler .ghost__ring { display: none !important; }
.ghost--cooler.is-valid .ghost__top { filter: drop-shadow(0 0 4px rgb(var(--board-ok-rgb) / 80%)); }
/* Pulsa la silueta completa de la pieza que hay que coger, incluida la herramienta. */
.practice-page .desk-piece.is-available:not(.is-dragging) .figure,
.practice-page .desk-piece--tool.is-available:not(.is-dragging) img { animation: piece-attention 2.8s ease-in-out infinite; }
/* Sin aclararla: la pieza se levanta un poco (algo más grande y con más sombra) y su contorno se ilumina en ámbar.
   `scale` no interfiere con el giro (`transform`) de cada pieza. */
@keyframes piece-attention {
  0%, 65%, 100% { scale: 1; filter: drop-shadow(1px 3px 2px #3b302a2e) drop-shadow(0 0 3px rgb(var(--hint-rgb) / 90%)); }
  30% { scale: 1.06; filter: drop-shadow(2px 7px 5px #3b302a40) drop-shadow(0 0 9px rgb(var(--hint-rgb))); }
}
/* En la placa se ilumina el cuerpo de la ranura o la pestaña, no un punto encima. */
.practice-page .highlight.look-slot.is-on .highlight__line,
.practice-page .highlight.look-glow.is-on .highlight__line { animation: hardware-attention 2.8s ease-in-out infinite; }
@keyframes hardware-attention {
  0%, 65%, 100% { fill: rgb(var(--hint-rgb) / 6%); stroke-width: 1.2; }
  30% { fill: rgb(var(--hint-rgb) / 65%); stroke-width: 2.5; }
}
.practice-page .highlight.is-on.is-valid .highlight__line,
.practice-page .highlight.is-on.is-misaligned .highlight__line { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .practice-page .desk-piece.is-available:not(.is-dragging) .figure,
  .practice-page .desk-piece--tool.is-available:not(.is-dragging) img,
  .practice-page .desk-screw.is-available:not(.is-dragging) img { animation: none; filter: drop-shadow(0 0 4px rgb(var(--hint-rgb) / 70%)); }
  .practice-page .highlight.look-slot.is-on .highlight__line,
  .practice-page .highlight.look-glow.is-on .highlight__line { animation: none; fill: rgb(var(--board-blue-rgb) / 18%); }
}
.practice-page .highlight[data-for="CPU_SOCKET"] .highlight__halo {
  stroke: #ffd58b; stroke-width: 7; fill: none; filter: blur(3px);
}
.practice-page .highlight[data-for="CPU_SOCKET"].is-on .highlight__halo {
  animation: socket-glow 2.6s ease-in-out infinite;
}
.practice-page .highlight[data-for="CPU_SOCKET"] .highlight__line { stroke: none; fill: none; animation: none; }
.practice-page .highlight[data-for="CPU_SOCKET"].is-valid .highlight__halo { stroke: var(--on-board-ok); animation: none; opacity: .8; }
@keyframes socket-glow {
  0%, 100% { opacity: .15; }
  50% { opacity: .85; }
}
@media (prefers-reduced-motion: reduce) {
  .practice-page .highlight[data-for="CPU_SOCKET"].is-on .highlight__halo { animation: none; opacity: .55; }
}
.practice-page .highlight[data-for="SOCKET_LEVER"] .highlight__halo { display: none; }
.practice-page .highlight[data-for="SOCKET_LEVER"].is-on .highlight__line {
  stroke: none; fill: #ffe1a6;
  filter: blur(.6px) drop-shadow(0 0 5px #ffcf76);
  animation: lever-shading 2.4s ease-in-out infinite;
}
.practice-page .control[data-control="SOCKET_LEVER"].is-active:hover { stroke: none; fill: transparent; }
@keyframes lever-shading {
  0%, 100% { opacity: .18; }
  50% { opacity: .9; }
}
@media (prefers-reduced-motion: reduce) {
  .practice-page .highlight[data-for="SOCKET_LEVER"].is-on .highlight__line { animation: none; opacity: .65; }
}

/* Ayuda por inactividad (`idleHint`): flecha sutil y punteada de la pieza a su destino, sobre la placa. */
.practice-page .idle-arrow {
  position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; z-index: 115; pointer-events: none;
  color: rgb(var(--hint-rgb)); opacity: 0; transition: opacity .6s ease-out;
}
.practice-page .idle-arrow.is-visible { opacity: .9; }
.practice-page .idle-arrow__line {
  fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-dasharray: 9 7;
  vector-effect: non-scaling-stroke; filter: drop-shadow(0 0 2px rgb(0 0 0 / 55%)); animation: idle-arrow-dash 1.4s linear infinite;
}
.practice-page .idle-arrow__head { fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
@keyframes idle-arrow-dash { to { stroke-dashoffset: -16; } }
@media (prefers-reduced-motion: reduce) { .practice-page .idle-arrow__line { animation: none; } }

/* ---------- Preparación del puesto: pulsera antiestática (js/ui/esd.js) ----------
   Mientras se prepara el puesto la placa sigue a la vista, atenuada y sin responder (ni su zoom). La pulsera, la
   pinza y la toma de tierra van en una capa propia sobre la alfombrilla; al terminar, la placa recupera su color y
   la pinza queda enganchada en la toma. */
.practice-page .workbench.is-prep .workspace { opacity: .4; filter: saturate(.5); pointer-events: none; }
.practice-page .workbench .workspace { transition: opacity .5s ease-out, filter .5s ease-out; }
.practice-page .workbench.is-prep .zoom { visibility: hidden; }
.practice-page .esd { position: absolute; inset: var(--mat-inset); z-index: 200; pointer-events: none; }
.practice-page .esd[hidden] { display: none; }
.practice-page .esd__cable { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.practice-page .esd__cable path { fill: none; stroke-linecap: round; }
.practice-page .esd__cable-edge { stroke: #1b4a8c; stroke-width: 6; }
.practice-page .esd__cable-core { stroke: #3a82dc; stroke-width: 3.5; }
.practice-page .esd__strap, .practice-page .esd__clip {
  position: absolute; left: 0; top: 0; padding: 0; border: 0; background: none; pointer-events: auto; touch-action: none;
}
.practice-page .esd__strap { cursor: pointer; }
.practice-page .esd__clip { cursor: grab; }
.practice-page .esd__clip.is-dragging { cursor: grabbing; }
.practice-page .esd__strap img, .practice-page .esd__clip img { display: block; width: 100%; height: 100%; pointer-events: none; filter: drop-shadow(1px 3px 2px #10202840); }
/* Toma de tierra: botón metálico a presión en la esquina inferior izquierda, en la franja libre de la alfombrilla. */
.practice-page .esd__stud {
  position: absolute; left: 14px; bottom: 9px; width: 24px; height: 24px; padding: 0; border-radius: 50%; pointer-events: auto; cursor: pointer;
  border: 1px solid #3a4c56; background: radial-gradient(circle at 38% 34%, #f5f7f8, #aab4ba 55%, #6c7880); box-shadow: 0 1px 2px #0006, inset 0 0 0 3px #8a959c55;
}
.practice-page .esd__strap:focus-visible, .practice-page .esd__clip:focus-visible, .practice-page .esd__stud:focus-visible { outline: 3px solid var(--on-dark); outline-offset: 2px; }
/* Lo que hay que usar en cada momento destaca igual que las piezas de la mesa; la toma, con un halo ámbar. */
.practice-page .esd[data-stage="start"] .esd__strap img,
.practice-page .esd[data-stage="worn"] .esd__clip:not(.is-dragging) img { animation: piece-attention 2.8s ease-in-out infinite; }
.practice-page .esd[data-stage="worn"] .esd__stud { animation: stud-attention 1.4s ease-in-out infinite; }
@keyframes stud-attention { 0%, 100% { box-shadow: 0 1px 2px #0006, 0 0 0 0 rgb(var(--hint-rgb) / 0%); } 50% { box-shadow: 0 1px 2px #0006, 0 0 0 7px rgb(var(--hint-rgb) / 45%); } }
.practice-page .esd[data-stage="grounded"] :is(.esd__clip, .esd__stud) { pointer-events: none; cursor: default; }
@media (prefers-reduced-motion: reduce) {
  .practice-page .esd [class^="esd__"], .practice-page .esd img { animation: none !important; }
  .practice-page .workbench .workspace { transition: none; }
}

/* Coberturas reversibles de los dos orificios inferiores que sobresalen del
   asset del disipador. Solo capa visual, nunca se altera la foto de la placa. */
.practice-page .scene.has-cooler::before,
.practice-page .scene.has-cooler::after {
  content: '';position:absolute;top:41.017%;width:2.823%;height:2.758%;
  border-radius:50%;background:radial-gradient(ellipse,#25282b 0 78%,#25282b00 100%);
  z-index:1;pointer-events:none;
}
.practice-page .scene.has-cooler::before{left:35.887%}
.practice-page .scene.has-cooler::after{left:63.25%}
.practice-page .scene.has-cooler.review-cpu::before,
.practice-page .scene.has-cooler.review-cpu::after{display:none}
/* CPU_FAN: se distingue la pieza que se arrastra, sin aclarar la placa. */
.practice-page.hints-on .loose--fan-connector.is-available:not(.is-dragging){animation:fan-plug-attention 2.4s ease-in-out infinite}
@keyframes fan-plug-attention{
  0%,65%,100%{filter:brightness(1.3) drop-shadow(0 0 3px #ffab38);scale:1}
  30%{filter:brightness(1.8) drop-shadow(0 0 7px #ffab38);scale:1.06}
}
.practice-page .scene:has(.loose--fan-connector.is-available) .cable__edge{stroke:#a1c9dd;stroke-opacity:.9}
.practice-page .scene:has(.loose--fan-connector.is-available) .cable__shine{stroke:#a6bac5;opacity:.95}
@media(prefers-reduced-motion:reduce){.practice-page.hints-on .loose--fan-connector.is-available:not(.is-dragging){animation:none;filter:brightness(1.4) drop-shadow(0 0 4px #ffab38)}}

/* Al colocar el disipador, la referencia son los cuatro orificios reales.
   El destino central sigue aceptando el arrastre, pero no dibuja otro círculo. */
.practice-page .highlight[data-for="CPU_COOLER_AREA"]{display:none}
.practice-page .highlight[data-for^="COOLER_HOLE_"].is-on .highlight__halo{
  stroke:#ffab38;animation:cooler-hole-glow 2.4s ease-in-out infinite;
}
.practice-page .highlight[data-for^="COOLER_HOLE_"].is-on .highlight__line{
  stroke:#ffbc57;animation:cooler-hole-rim 2.4s ease-in-out infinite;
}
@keyframes cooler-hole-glow{
  0%,65%,100%{opacity:.18;stroke-width:4}
  30%{opacity:.9;stroke-width:13}
}
@keyframes cooler-hole-rim{
  0%,65%,100%{opacity:.45;stroke-width:1.5;fill:#ffab3800}
  30%{opacity:1;stroke-width:3;fill:#ffab3840}
}
@media(prefers-reduced-motion:reduce){
  .practice-page .highlight[data-for^="COOLER_HOLE_"].is-on .highlight__halo{animation:none;opacity:.6;stroke-width:8}
  .practice-page .highlight[data-for^="COOLER_HOLE_"].is-on .highlight__line{animation:none;opacity:1;stroke-width:2.5}
}

/* CPU_FAN queda por encima del cable y de la pieza que se está cogiendo.
   El SVG no intercepta el puntero: el arrastre conserva sus destinos. */
.practice-page .scene:has(.loose--fan-connector.is-available) .scene__highlights{z-index:125}
.practice-page .highlight[data-for="CPU_FAN"].is-on:not(.is-valid) .highlight__halo{
  stroke:#ffab38;animation:cooler-hole-glow 2.4s ease-in-out infinite;
}
.practice-page .highlight[data-for="CPU_FAN"].is-on:not(.is-valid) .highlight__line{
  stroke:#ffbc57;animation:cooler-hole-rim 2.4s ease-in-out infinite;
}
@media(prefers-reduced-motion:reduce){
  .practice-page .highlight[data-for="CPU_FAN"].is-on:not(.is-valid) .highlight__halo{animation:none;opacity:.6;stroke-width:8}
  .practice-page .highlight[data-for="CPU_FAN"].is-on:not(.is-valid) .highlight__line{animation:none;opacity:1;stroke-width:2.5}
}

/* Móvil: piezas compactas, más ancho útil para la placa y objetivos táctiles separados. */
@media (max-width: 600px) {
  .practice-page .workbench {
    --parts-width: clamp(76px, 18vw, 96px);
    height: max(360px, min(calc((100vw - 22px - var(--parts-width)) * 1.024 + 49px), calc(100svh - 70px)));
  }
  .practice-page .workbench .workspace { padding: 3px 2px 37px; }
  .practice-page .desk-piece { min-width: 44px; min-height: 44px; }
  .practice-page .desk-piece-wrap--ram { top: 23%; }
  .practice-page .desk-piece-wrap--ram-second { top: 36%; }
}
