/* Cronopuzzle: lienzo, nodos y conexiones
   Compartida por builder.html y play.html.
   .cn-viewport > .cn-layer (transform translate+scale) > svg (aristas) + .cn-nodes (tarjetas) */

.cn-viewport {
  position: relative;
  overflow: hidden;
  touch-action: none;            /* gestos manejados por JS */
  user-select: none;
  -webkit-user-select: none;
  border-radius: 18px;
  background-color: var(--cn-bg, #0b0713);
  background-image: var(--cn-bg-img, none);
  background-size: var(--cn-bg-size, auto);
  cursor: grab;
  color: var(--cn-text, #f0ecff);
}
.cn-viewport.is-panning { cursor: grabbing; }
.cn-viewport.is-linking { cursor: crosshair; }

.cn-layer {
  position: absolute;
  top: 0; left: 0;
  width: 0; height: 0;           /* solo sistema de coordenadas */
  transform-origin: 0 0;
  will-change: transform;
}

.cn-edges {
  position: absolute;
  overflow: visible;
  pointer-events: none;          /* hitbox propio por arista */
  left: 0; top: 0;
  width: 1px; height: 1px;
}

/* Nodos */
/* Alto fijo (necesario para huecos/retícula); el sobrante se lee en el modal */
.cn-node {
  position: absolute;
  width: 216px;
  height: 180px;
  display: flex;
  flex-direction: column;
  border-radius: var(--cn-node-radius, 16px);
  background: var(--cn-node-bg, rgba(24, 16, 42, 0.94));
  border: 1.5px solid var(--cn-node-border, rgba(255, 255, 255, 0.16));
  box-shadow: var(--cn-node-shadow, 0 10px 24px rgba(0, 0, 0, 0.4));
  /* Sin overflow:hidden: los puertos de anclaje sobresalen y necesitan ser clicables */
  cursor: grab;
  transition: box-shadow 0.18s ease, border-color 0.18s ease, opacity 0.18s ease;
}
.cn-node.is-dragging {
  cursor: grabbing;
  z-index: 50;
  box-shadow: 0 28px 54px rgba(0, 0, 0, 0.55), 0 0 0 2px var(--cn-accent, #8deeff);
  transform-origin: center;
  transition: none;
}
.cn-node.is-anchor { cursor: default; border-style: dashed; opacity: 0.96; }
.cn-node.is-locked { cursor: default; }
.cn-node.is-selected { border-color: var(--cn-accent, #8deeff); box-shadow: 0 0 0 2px var(--cn-accent, #8deeff), var(--cn-node-shadow, 0 10px 24px rgba(0,0,0,.4)); }
/* Destino de conexión en curso (distinto de is-selected) */
.cn-node.is-link-target {
  border-color: var(--cn-gold, #ffc94a);
  box-shadow: 0 0 0 2px var(--cn-gold, #ffc94a), 0 0 28px var(--cn-accent-dim, rgba(141,238,255,.25));
}

.cn-node-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 10px;
  background: var(--cn-node-head, rgba(255, 255, 255, 0.06));
  border-bottom: 1px solid var(--cn-node-border, rgba(255, 255, 255, 0.12));
  border-radius: inherit;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.cn-node-badge {
  flex: none;
  display: grid;
  place-items: center;
  width: 20px; height: 20px;
  border-radius: 7px;
  font-size: 10.5px; font-weight: 800;
  background: var(--cn-accent, #8deeff);
  color: var(--cn-badge-text, #0d0a16);
}
.cn-node-title {
  flex: 1;
  min-width: 0;
  font-family: var(--cn-font-head, "Baloo 2", sans-serif);
  font-size: 12.5px;
  font-weight: 800;
  line-height: 1.25;
  color: var(--cn-title, inherit);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cn-node-zoom {
  flex: none;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  border: 0; border-radius: 6px;
  background: transparent;
  color: var(--cn-muted, #a99fc4);
  font-size: 12px; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.cn-node-zoom:hover { background: rgba(255,255,255,.12); color: var(--cn-text, #fff); }

.cn-node-media {
  height: 72px;
  flex: none;
  background: var(--cn-media-bg, rgba(0, 0, 0, 0.28));
  display: grid;
  place-items: center;
  overflow: hidden;
  position: relative;
}
.cn-node-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cn-node-media.is-empty::after {
  content: "🖼 arrastra una imagen";
  font-size: 9.5px;
  letter-spacing: .03em;
  color: var(--cn-muted, #8b81a8);
  text-align: center;
  padding: 0 8px;
}
.cn-node-text {
  flex: 1;
  padding: 8px 10px 10px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--cn-muted, #b9b0d4);
  /* Tres líneas; el resto se lee en el modal */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Sin imagen: el texto ocupa el hueco */
.cn-node.no-media .cn-node-media { display: none; }
.cn-node.no-media .cn-node-text { -webkit-line-clamp: 7; }

/* En el constructor (.cn-edit), el hueco vacío sigue mostrando la pista de arrastre */
.cn-viewport.cn-edit .cn-node.no-media .cn-node-media { display: grid; }
.cn-viewport.cn-edit .cn-node.no-media .cn-node-text { -webkit-line-clamp: 3; }
.cn-node-hint {
  padding: 0 10px 8px;
  font-size: 9.5px;
  color: var(--cn-accent, #8deeff);
  opacity: .85;
}

/* Puertos de anclaje: área táctil ampliada vía ::after */
.cn-port {
  position: absolute;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--cn-accent, #8deeff);
  border: 2px solid var(--cn-node-bg, #180f2b);
  opacity: 0;
  transform: scale(0.7);
  transition: opacity 0.16s ease, transform 0.16s ease;
  cursor: crosshair;
  z-index: 3;
}
.cn-port::after { content: ""; position: absolute; inset: -9px; border-radius: 50%; }
.cn-viewport.is-linking .cn-port { opacity: 0.85; transform: scale(1); }

/* Ratón: tiradores ocultos hasta hover */
@media (hover: hover) and (pointer: fine) {
  .cn-node:hover .cn-port { opacity: 0.85; transform: scale(1); }
  .cn-port:hover { opacity: 1 !important; transform: scale(1.45) !important; }
}

/* Táctil: tiradores siempre visibles, hitbox ampliado a 44px */
@media (hover: none), (pointer: coarse) {
  .cn-port { opacity: 0.55; transform: scale(1); }
  .cn-port::after { inset: -16px; }
  .cn-node.is-dragging .cn-port { opacity: 0; }
}
.cn-port-t { top: -6px;  left: 50%; margin-left: -5.5px; }
.cn-port-b { bottom: -6px; left: 50%; margin-left: -5.5px; }
.cn-port-l { left: -6px;  top: 50%; margin-top: -5.5px; }
.cn-port-r { right: -6px; top: 50%; margin-top: -5.5px; }

/* Estados de validación */
.cn-node.is-right { border-color: #3ddc97; box-shadow: 0 0 0 2px #3ddc97, 0 0 26px rgba(61,220,151,.34); }
.cn-node.is-wrong { border-color: #ff5470; box-shadow: 0 0 0 2px #ff5470, 0 0 26px rgba(255,84,112,.3); }
.cn-node.is-flash { animation: cnFlash .55s cubic-bezier(.34,1.56,.64,1); }
.cn-node.is-shake { animation: cnShake .42s ease-in-out; }
.cn-node.is-radar::before {
  content: ""; position: absolute; inset: -6px; border-radius: 20px;
  border: 2px solid var(--cn-gold, #ffc94a); animation: cnRadar 1.1s ease-out infinite;
  pointer-events: none;
}
@keyframes cnFlash {
  0%   { transform: scale(1);    filter: brightness(1); }
  40%  { transform: scale(1.07); filter: brightness(1.7); }
  100% { transform: scale(1);    filter: brightness(1); }
}
@keyframes cnShake {
  0%,100% { margin-left: 0; }
  20% { margin-left: -8px; } 40% { margin-left: 7px; }
  60% { margin-left: -5px; } 80% { margin-left: 3px; }
}
@keyframes cnRadar {
  0%   { transform: scale(.96); opacity: 1; }
  100% { transform: scale(1.28); opacity: 0; }
}

/* Siluetas (huecos donde encaja cada nodo) */
.cn-slot {
  position: absolute;
  width: 216px; height: 180px;
  border-radius: var(--cn-node-radius, 16px);
  border: 2px dashed var(--cn-slot-border, rgba(255, 255, 255, 0.22));
  background: var(--cn-slot-bg, rgba(255, 255, 255, 0.035));
  display: grid;
  place-items: center;
  text-align: center;
  padding: 10px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--cn-slot-text, var(--cn-muted, #7d739c));
  pointer-events: none;
  transition: border-color .16s ease, background .16s ease, transform .16s ease;
}
.cn-slot.is-near {
  border-color: var(--cn-accent, #8deeff);
  background: var(--cn-accent-dim, rgba(141, 238, 255, 0.12));
  transform: scale(1.03);
}
.cn-slot.is-taken { opacity: 0; }
.cn-slot.is-radar { border-color: var(--cn-gold, #ffc94a); animation: cnSlotPulse 1s ease-in-out infinite alternate; }
@keyframes cnSlotPulse {
  from { box-shadow: 0 0 0 rgba(255,201,74,0); }
  to   { box-shadow: 0 0 26px 6px rgba(255,201,74,.4); }
}

/* Aristas */
.cn-edge-base {
  fill: none;
  stroke: var(--cn-edge, rgba(180, 170, 220, 0.55));
  stroke-width: 2.4;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
/* Segunda pasada punteada y en marcha: sensación de dirección */
.cn-edge-flow {
  fill: none;
  stroke: var(--cn-accent, #8deeff);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 3 13;
  vector-effect: non-scaling-stroke;
  animation: cnFlow 1.05s linear infinite;
  opacity: .95;
}
@keyframes cnFlow { to { stroke-dashoffset: -32; } }

/* Punta de flecha: path relleno, color propio (fill no hereda de stroke) */
.cn-edge-head { fill: var(--cn-edge, rgba(180, 170, 220, 0.55)); stroke: none; }
.cn-edge-g.is-hover .cn-edge-head { fill: var(--cn-accent, #8deeff); }
.cn-edge-g.is-right .cn-edge-head { fill: #3ddc97; }
.cn-edge-g.is-wrong .cn-edge-head { fill: #ff5470; }
.cn-edge-g.is-ghost .cn-edge-head { fill: var(--cn-gold, #ffc94a); }

/* Cazador invisible: hitbox ancho para clicar la curva */
.cn-edge-hit {
  fill: none;
  stroke: transparent;
  stroke-width: 18;
  vector-effect: non-scaling-stroke;
  pointer-events: stroke;
  cursor: pointer;
}
.cn-edge-g.is-hover .cn-edge-base { stroke: var(--cn-accent, #8deeff); stroke-width: 3.4; }
.cn-edge-g.is-right .cn-edge-base { stroke: #3ddc97; }
.cn-edge-g.is-right .cn-edge-flow { stroke: #3ddc97; }
.cn-edge-g.is-wrong .cn-edge-base { stroke: #ff5470; stroke-dasharray: 7 6; }
.cn-edge-g.is-wrong .cn-edge-flow { display: none; }
.cn-edge-g.is-ghost .cn-edge-base { stroke: var(--cn-gold, #ffc94a); stroke-width: 3.2; }
.cn-edge-g.is-ghost .cn-edge-flow { stroke: var(--cn-gold, #ffc94a); }
.cn-edge-label {
  fill: var(--cn-muted, #b9b0d4);
  font-family: "Nunito", sans-serif;
  font-size: 10px;
  font-weight: 700;
  text-anchor: middle;
  paint-order: stroke;
  stroke: var(--cn-bg, #0b0713);
  stroke-width: 4px;
  stroke-linejoin: round;
}
/* Línea elástica mientras se traza una conexión nueva */
.cn-edge-draft {
  fill: none;
  stroke: var(--cn-accent, #8deeff);
  stroke-width: 2.6;
  stroke-dasharray: 8 7;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  animation: cnFlow .7s linear infinite;
}

/* Barrido de verificación (modo investigación) */
.cn-scan {
  position: absolute;
  top: 0; bottom: 0;
  width: 190px;
  pointer-events: none;
  z-index: 80;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--cn-accent-dim, rgba(141,238,255,.18)) 45%,
    var(--cn-accent, #8deeff) 50%,
    var(--cn-accent-dim, rgba(141,238,255,.18)) 55%,
    transparent 100%);
  animation: cnScan 1.15s cubic-bezier(.4,0,.2,1) forwards;
}
@keyframes cnScan {
  from { left: -200px; }
  to   { left: 100%; }
}

/* Controles flotantes del lienzo (zoom, encuadre) */
.cn-cam {
  position: absolute;
  right: 12px; bottom: 12px;
  z-index: 60;
  display: flex; flex-direction: column; gap: 6px;
}
.cn-cam button {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 11px;
  border: 1px solid var(--cn-node-border, rgba(255,255,255,.18));
  background: var(--cn-node-bg, rgba(24,16,42,.92));
  color: var(--cn-text, #f0ecff);
  font-size: 14px; font-weight: 800;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.cn-cam button:hover { border-color: var(--cn-accent, #8deeff); }
.cn-zoom-label {
  position: absolute; left: 12px; bottom: 12px; z-index: 60;
  padding: 5px 10px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: var(--cn-node-bg, rgba(24,16,42,.92));
  border: 1px solid var(--cn-node-border, rgba(255,255,255,.16));
  color: var(--cn-muted, #b9b0d4);
  pointer-events: none;
}

/* Modal de lectura (doble clic sobre un nodo) */
.cn-modal {
  position: fixed; inset: 0; z-index: 9000;
  display: grid; place-items: center;
  padding: 20px;
  background: rgba(4, 2, 10, 0.72);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.cn-modal[hidden] { display: none; }
.cn-modal-card {
  width: min(560px, 94vw);
  max-height: 88vh; overflow-y: auto;
  border-radius: 24px;
  background: var(--cn-node-bg, #180f2b);
  border: 1px solid var(--cn-node-border, rgba(255,255,255,.18));
  box-shadow: 0 30px 80px rgba(0,0,0,.55);
  color: var(--cn-text, #f0ecff);
  animation: cnModalIn .22s cubic-bezier(.34,1.56,.64,1);
}
@keyframes cnModalIn { from { transform: scale(.94); opacity: 0; } }
.cn-modal-img { width: 100%; max-height: 300px; object-fit: contain; background: rgba(0,0,0,.35); display: block; }
.cn-modal-body { padding: 20px 24px 24px; }
.cn-modal-body h3 { margin: 0 0 10px; font-family: var(--cn-font-head, "Baloo 2", sans-serif); font-size: 1.3rem; }
.cn-modal-body p { margin: 0 0 12px; font-size: .92rem; line-height: 1.6; color: var(--cn-muted, #b9b0d4); white-space: pre-wrap; }
.cn-modal-pista {
  margin: 0 0 14px; padding: 10px 12px; border-radius: 12px;
  background: rgba(255, 201, 74, .1); border: 1px solid rgba(255, 201, 74, .34);
  color: var(--cn-gold, #ffc94a); font-size: .84rem; line-height: 1.5;
}
.cn-modal-close {
  padding: 9px 18px; border-radius: 999px; border: 0; cursor: pointer;
  background: var(--cn-accent, #8deeff); color: var(--cn-badge-text, #0d0a16);
  font-weight: 800; font-size: .84rem;
}

/* Skins del lienzo: solo redefinen variables */

/* Corcho de investigación */
.cn-skin-corcho {
  --cn-bg: #6b4a2c;
  --cn-bg-img:
    radial-gradient(circle at 20% 30%, rgba(0,0,0,.16) 0 2px, transparent 3px),
    radial-gradient(circle at 70% 65%, rgba(0,0,0,.13) 0 2.5px, transparent 3.5px),
    radial-gradient(circle at 45% 85%, rgba(255,255,255,.07) 0 2px, transparent 3px),
    linear-gradient(135deg, #7a5433 0%, #5f4026 100%);
  --cn-bg-size: 37px 37px, 53px 53px, 29px 29px, auto;
  --cn-text: #2b1c0f;
  --cn-muted: #6a5238;
  --cn-title: #2b1c0f;
  --cn-node-bg: #f6ecd8;
  --cn-node-head: rgba(0,0,0,.06);
  --cn-node-border: rgba(60, 38, 18, .3);
  --cn-node-shadow: 0 12px 22px rgba(0,0,0,.4);
  --cn-node-radius: 4px;
  --cn-media-bg: rgba(0,0,0,.12);
  --cn-edge: #b3282c;
  --cn-accent: #d1372f;
  --cn-accent-dim: rgba(209,55,47,.16);
  --cn-badge-text: #fff;
  --cn-slot-border: rgba(255,255,255,.4);
  --cn-slot-bg: rgba(0,0,0,.14);
  --cn-slot-text: rgba(255,255,255,.78);
  --cn-gold: #f0b429;
}
/* Chincheta: solo en el skin de corcho */
.cn-skin-corcho .cn-node::after {
  content: "";
  position: absolute; top: 4px; left: 50%; margin-left: -5px;
  width: 10px; height: 10px; border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, #ff8a80, #b3282c 70%);
  box-shadow: 0 2px 4px rgba(0,0,0,.5);
  z-index: 4;
}

/* Fluxograma técnico */
.cn-skin-blueprint {
  --cn-bg: #0a1626;
  --cn-bg-img:
    linear-gradient(rgba(90,170,255,.13) 1px, transparent 1px),
    linear-gradient(90deg, rgba(90,170,255,.13) 1px, transparent 1px),
    linear-gradient(rgba(90,170,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(90,170,255,.05) 1px, transparent 1px);
  --cn-bg-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  --cn-text: #dbeeff;
  --cn-muted: #7fa8cc;
  --cn-node-bg: rgba(12, 32, 56, .96);
  --cn-node-head: rgba(90,170,255,.12);
  --cn-node-border: rgba(120, 190, 255, .34);
  --cn-node-radius: 6px;
  --cn-media-bg: rgba(0,0,0,.32);
  --cn-edge: rgba(120, 190, 255, .6);
  --cn-accent: #4fc3f7;
  --cn-accent-dim: rgba(79,195,247,.16);
  --cn-badge-text: #04121f;
  --cn-slot-border: rgba(120,190,255,.4);
  --cn-slot-text: rgba(190,225,255,.72);
  --cn-gold: #ffca28;
}

/* Pergamino */
.cn-skin-pergamino {
  --cn-bg: #e8d9b5;
  --cn-bg-img:
    radial-gradient(circle at 15% 20%, rgba(140,110,60,.14) 0 40px, transparent 90px),
    radial-gradient(circle at 82% 72%, rgba(140,110,60,.12) 0 60px, transparent 120px),
    linear-gradient(160deg, #f2e6c8 0%, #dfcda3 100%);
  --cn-bg-size: auto;
  --cn-text: #3a2a12;
  --cn-muted: #7a6237;
  --cn-node-bg: #fdf6e3;
  --cn-node-head: rgba(122, 98, 55, .12);
  --cn-node-border: rgba(122, 98, 55, .42);
  --cn-node-radius: 3px;
  --cn-node-shadow: 0 8px 18px rgba(90,70,30,.28);
  --cn-media-bg: rgba(122,98,55,.12);
  --cn-edge: #8a6a33;
  --cn-accent: #b5892f;
  --cn-accent-dim: rgba(181,137,47,.18);
  --cn-badge-text: #fdf6e3;
  --cn-slot-border: rgba(122,98,55,.5);
  --cn-slot-bg: rgba(122,98,55,.08);
  --cn-slot-text: rgba(58,42,18,.62);
  --cn-gold: #a06a12;
}

/* Circuito neón (default) */
.cn-skin-neon {
  --cn-bg: #06040f;
  --cn-bg-img:
    radial-gradient(circle at 18% 22%, rgba(169,106,231,.22), transparent 46%),
    radial-gradient(circle at 84% 76%, rgba(141,238,255,.16), transparent 44%),
    linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px);
  --cn-bg-size: auto, auto, 26px 26px, 26px 26px;
  --cn-text: #f0ecff;
  --cn-muted: #a99fc4;
  --cn-node-bg: rgba(23, 14, 40, .95);
  --cn-node-head: rgba(255,255,255,.06);
  --cn-node-border: rgba(169, 106, 231, .42);
  --cn-node-radius: 16px;
  --cn-node-shadow: 0 12px 30px rgba(0,0,0,.5);
  --cn-media-bg: rgba(0,0,0,.35);
  --cn-edge: rgba(169, 106, 231, .7);
  --cn-accent: #8deeff;
  --cn-accent-dim: rgba(141,238,255,.16);
  --cn-badge-text: #0d0a16;
  --cn-slot-border: rgba(141,238,255,.32);
  --cn-slot-text: rgba(215,205,240,.66);
  --cn-gold: #ffc94a;
}

@media (prefers-reduced-motion: reduce) {
  .cn-edge-flow, .cn-edge-draft, .cn-node.is-radar::before,
  .cn-slot.is-radar, .cn-scan, .cn-modal-card { animation: none !important; }
  .cn-node, .cn-slot { transition: none !important; }
}
/* Modo bajo rendimiento: sin animaciones continuas */
body.perf-low .cn-edge-flow,
body.perf-low .cn-node.is-radar::before { animation: none; }
body.perf-low .cn-viewport { background-image: none; }

/* Pulso de las flechas, apagado cuando sale caro */
.cn-viewport.no-flow .cn-edge-flow,
.cn-viewport.is-panning .cn-edge-flow,
.cn-viewport.is-moving .cn-edge-flow { animation: none; }

/* Blancos táctiles: botones de icono ampliados en pointer:coarse */
@media (pointer: coarse) {
  .cn-cam button { min-width: 44px; min-height: 44px; }
}
