/* MathGym — Complete Project (MEJORADO) */

:root {
    /* Superficies: el navy del pantalón y las zapatillas de Deceerre, oscurecido.
       El fondo NO es morado a propósito: el morado es lo que lleva él en la
       camiseta y lo que llevan los iconos, y sobre fondo morado se cancelaría. */
    --bg: #141b26;
    --card: rgba(255,255,255,.07);
    --card-b: rgba(255,255,255,.14);
    --fg: #eceff4;
    --muted: #a8b3c4;
    /* Superficies sólidas de la sala de entrenamiento (la home). El resto del
       sitio usa --card, que es translúcido sobre el degradado del body. */
    --surface: #1a2230;
    --surface-2: #212b3b;
    --line: #2a3648;

    /* Marca, medida sobre assets/logo_mathgym.png.
       OJO: --brand es RELLENO, nunca texto — sobre --bg da 2.2:1 y falla.
       Para texto y bordes está --accent, del mismo tono (303°) pero legible. */
    --brand: #8a2189;       /* morado del hexágono; blanco encima 7.9:1 */
    --brand-lift: #a32ba0;  /* hover de relleno */
    --brand-deep: #5e1660;  /* sombra dura */
    --accent: #d163cc;      /* texto y bordes; 5.2:1 sobre --bg */
    --grad-brand: linear-gradient(135deg, var(--brand), var(--brand-lift));

    --gold: #f8c818;        /* la M del logo; 10.9:1 sobre --bg */
    --blue: #1788c7;        /* las pesas del logo, como relleno */
    --blue-text: #4fb3e8;   /* el azul legible como texto; 7.4:1 */

    /* Semánticos: independientes de la marca, no se tocan. */
    --success: #10b981;
    --warning: #f59e0b;
    --error: #ef4444;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: linear-gradient(135deg, #141b26 0%, #2c142c 100%);
    color: var(--fg);
    font: 16px/1.6 'Lexend', system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-variant-numeric: tabular-nums;
    min-height: 100vh;
}

h1, h2, h3 {
    font-family: 'Unbounded', system-ui, sans-serif;
}

/* Números destacados de reto (objetivo, cronómetro, pesadas): monoespaciado */
.target-amount,
.sand-clock-value,
.weighings-count {
    font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
}

.card {
    background: var(--card);
    border: 1px solid var(--card-b);
    border-radius: 16px;
    padding: 20px;
    margin: 16px 0;
    backdrop-filter: blur(10px);
    transition: all 0.2s ease;
}

.card:hover {
    background: rgba(255,255,255,.1);
    border-color: rgba(255,255,255,.2);
    transform: translateY(-1px);
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--card-b);
    background: linear-gradient(135deg, 
        rgba(255,255,255,.1) 0%, 
        rgba(255,255,255,.05) 100%);
    color: var(--fg);
    padding: 10px 16px;
    border-radius: 12px;
    text-decoration: none;
    cursor: pointer;
    font-weight: 500;
    transition: all 0.2s ease;
}

.btn:hover {
    background: linear-gradient(135deg, 
        rgba(255,255,255,.15) 0%, 
        rgba(255,255,255,.1) 100%);
    border-color: var(--accent);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(138, 33, 137, 0.2);
}

.btn:focus {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.btn:disabled {
    opacity: .5;
    cursor: not-allowed;
    transform: none !important;
    box-shadow: none !important;
}

/* Loading states */
.skeleton {
    min-height: 120px;
    border: 2px dashed var(--card-b);
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.02), transparent);
    background-size: 200% 100%;
    animation: shimmer 2s infinite;
}

@keyframes shimmer {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

/* Feedback messages */
.feedback {
    margin-top: 12px;
    padding: 8px 12px;
    border-radius: 8px;
    font-weight: 500;
}

.feedback.ok {
    color: var(--success);
    background: rgba(16, 185, 129, 0.1);
    border: 1px solid rgba(16, 185, 129, 0.2);
}

.feedback.ko {
    color: var(--error);
    background: rgba(239, 68, 68, 0.1);
    border: 1px solid rgba(239, 68, 68, 0.2);
}

.feedback.warning {
    color: var(--warning);
    background: rgba(245, 158, 11, 0.1);
    border: 1px solid rgba(245, 158, 11, 0.2);
}

/* Enigma game styles */
.template-box {
    padding: 20px 0;
}

.badge {
    display: inline-block;
    background: var(--grad-brand);
    color: white;
    padding: 6px 14px;
    border-radius: 20px;
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 16px;
}

.ein-grid {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
    gap: 24px;
    margin-top: 20px;
}

@media (max-width: 968px) {
    .ein-grid {
        grid-template-columns: 1fr;
        gap: 20px;
    }
}

.ein-clues, .ein-board, .ein-palette {
    background: rgba(255,255,255,.04);
    border: 1px solid var(--card-b);
    border-radius: 12px;
    padding: 16px;
    min-width: 0;
}

.ein-clues h2, .ein-board h2, .ein-palette h2 {
    margin: 0 0 16px 0;
    font-size: 1.2rem;
    color: var(--fg);
}

/* Tablero */
.ein-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 4px;
}

.cell {
    width: 80px;
    height: 80px;
    background: rgba(255,255,255,.06);
    border: 2px solid var(--card-b);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s ease;
    vertical-align: top;
    position: relative;
}

.cell:hover {
    background: rgba(255,255,255,.1);
    border-color: var(--accent);
}

.cell:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* Chips */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    padding: 4px;
    min-height: 72px;
    align-items: flex-start;
    align-content: flex-start;
}

.chip {
    background: var(--grad-brand);
    color: white;
    border: none;
    border-radius: 6px;
    padding: 2px 6px;
    font-size: 0.7rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s ease;
    line-height: 1.2;
}

.chip:hover {
    background: var(--grad-brand);
    transform: scale(1.05);
}

.chip:focus {
    outline: 1px solid white;
    outline-offset: 1px;
}

/* Paleta */
.ein-group {
    margin-bottom: 16px;
}

.ein-group h3 {
    margin: 0 0 8px 0;
    font-size: 1rem;
    color: var(--fg);
}

.ein-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.ein-cards .card {
    background: rgba(255,255,255,.08);
    border: 1px solid var(--card-b);
    border-radius: 8px;
    padding: 8px 12px;
    margin: 0;
    cursor: pointer;
    transition: all 0.2s ease;
    font-size: 0.9rem;
    color: var(--fg);
    font-family: inherit;
}

.ein-cards .card:hover {
    background: rgba(255,255,255,.15);
    border-color: var(--accent);
    transform: translateY(-1px);
}

.ein-cards .card.is-selected {
    background: var(--grad-brand);
    border-color: var(--accent);
    color: white;
    box-shadow: 0 4px 12px rgba(138, 33, 137, 0.3);
}

.ein-cards .card:focus {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Toolbar */
.toolbar {
    display: flex;
    gap: 8px;
    margin: 16px 0;
}

.toolbar .btn {
    padding: 8px 16px;
    font-size: 0.9rem;
}

/* Lists */
ol, ul {
    padding-left: 20px;
}

li {
    margin-bottom: 4px;
    line-height: 1.5;
}

/* Footer */
.site-footer {
    text-align: center;
    padding: 20px;
    color: var(--muted);
    font-size: 0.9rem;
    border-top: 1px solid var(--card-b);
    margin-top: auto;
}

/* Responsive */
@media (max-width: 768px) {
    .brand {
        padding: 12px 16px;
        gap: 12px;
    }
    
    .brand-title h1 {
        font-size: 1.5rem;
    }
    
    .contenedor-reto {
        padding: 0 16px;
    }
    
    .card {
        padding: 16px;
    }
    
    .cell {
        width: 60px;
        height: 60px;
    }
    
    .chips {
        min-height: 52px;
        padding: 2px;
    }
    
    .chip {
        font-size: 0.6rem;
        padding: 1px 4px;
    }
}
/* =========================================================
   Tema compartido de los retos — cabecera "estilo Einstein"
   ========================================================= */

/* Cabecera oscura con barrido de luz, usada por los 5 retos */
.enigma-header-dark {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 14px;
  background: linear-gradient(90deg, #261426 0%, #3a1338 60%, #5e1660 100%);
  padding: 10px 18px;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0,0,0,.4);
  margin-bottom: 16px;
}

.enigma-header-dark::before {
  content: '';
  position: absolute;
  inset: 0;
  left: -100%;
  z-index: 0;
  background: linear-gradient(90deg, transparent, rgba(138, 33, 137,.18), transparent);
  animation: slideLight 3s infinite;
  pointer-events: none;
}

.enigma-header-dark > * {
  position: relative;
  z-index: 1;
}

/* Placa del icono de cabecera.
   NO se recorta: los iconos son SVG anchos y transparentes (la balanza ocupa
   casi todo el lienzo de lado a lado), y el círculo con object-fit:cover que
   había aquí antes les comía los bordes. Se excluye .site-header, que tiene su
   propio logo redondo más abajo. */
.enigma-header-dark:not(.site-header) > img,
.enigma-header-dark .enigma-header-icon {
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  box-sizing: border-box;
  padding: 6px;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--card-b);
  border-radius: 18px;
  object-fit: contain;
}

.enigma-header-dark .enigma-header-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
}

.enigma-header-dark .enigma-header-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* En web el icono es protagonista, no una viñeta. */
@media (min-width: 700px) {
  .enigma-header-dark:not(.site-header) > img,
  .enigma-header-dark .enigma-header-icon {
    width: 76px;
    height: 76px;
    border-radius: 22px;
    padding: 8px;
  }
  .enigma-header-dark:not(.site-header) h2 { font-size: 1.7rem; }
}

@media (min-width: 1000px) {
  .enigma-header-dark:not(.site-header) > img,
  .enigma-header-dark .enigma-header-icon {
    width: 92px;
    height: 92px;
  }
  .enigma-header-dark:not(.site-header) h2 { font-size: 2rem; }
}

.enigma-header-dark h2 {
  position: relative;
  z-index: 1;
  margin: 0;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--accent);
}

/* Cabecera de sitio (portada/archivo): misma barra oscura + logo con halo,
   nombre en degradado y resplandor de fondo, para más presencia de marca */
.site-header {
  max-width: 1180px;
  margin: 16px auto 0;
  position: sticky;
  top: 0;
  z-index: 100;
  backdrop-filter: blur(10px);
}

/* ::after (no ::before, que ya lo usa el barrido de .enigma-header-dark) */
.site-header::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background:
    radial-gradient(circle at 12% 30%, rgba(163, 43, 160,.30), transparent 45%),
    radial-gradient(circle at 90% 75%, rgba(16,132,199,.25), transparent 45%);
  pointer-events: none;
}

.site-header img {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border-color: rgba(255,255,255,.15);
  animation: siteHeaderGlow 3.2s ease-in-out infinite;
}

@keyframes siteHeaderGlow {
  0%, 100% { box-shadow: 0 0 0 2px rgba(138, 33, 137,.45), 0 0 14px rgba(138, 33, 137,.35); }
  50%      { box-shadow: 0 0 0 2px rgba(163, 43, 160,.65), 0 0 30px rgba(163, 43, 160,.6); }
}

.site-header h2 {
  font-size: 1.5rem;
  letter-spacing: .2px;
  background: linear-gradient(90deg, var(--brand-lift), var(--accent) 55%, var(--gold));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.site-header-tagline {
  margin: 2px 0 0;
  font-size: .85rem;
  font-weight: 500;
  letter-spacing: .2px;
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  .site-header img {
    animation: none;
  }
}

.site-nav {
  max-width: 1180px;
  margin: 0 auto;
  padding: 8px 20px 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.streak-badge {
  margin-right: auto;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--card-b);
  background: rgba(255,255,255,.04);
  color: var(--fg);
  font-size: 0.85rem;
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .enigma-header-dark::before {
    animation: none;
  }
}

/* Tarjeta cristal "Cómo se juega", usada por los 5 retos */
.deceerre-instructions {
  display: flex;
  align-items: center;
  gap: 20px;
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  background: linear-gradient(135deg, rgba(124,58,237,.05), rgba(163, 43, 160,.04));
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,.10);
  box-shadow: 0 8px 24px rgba(0,0,0,.25);
  padding: 16px 20px;
  margin-bottom: 16px;
}

.deceerre-instructions img {
  width: 90px;
  height: 90px;
  flex-shrink: 0;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgba(138, 33, 137,.30));
}

.deceerre-instructions .instructions-body {
  flex: 1;
}

.deceerre-instructions h3 {
  margin: 0 0 8px;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--accent);
}

.deceerre-instructions p {
  margin: 0 0 6px;
  color: var(--fg);
  line-height: 1.55;
  font-size: .95rem;
}

.deceerre-instructions p:last-child {
  margin-bottom: 0;
}

.deceerre-instructions ul {
  margin: 0 0 6px;
  padding-left: 1.2rem;
  color: var(--fg);
  line-height: 1.55;
  font-size: .95rem;
}

.deceerre-instructions li {
  margin-bottom: 2px;
}

@media (max-width: 560px) {
  .deceerre-instructions {
    flex-direction: column;
    text-align: center;
  }
}

/* Celebración compartida (confetti + Deceerre), usada por los 5 retos */
.celebration-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(0,0,0,.8);
  cursor: pointer;
  animation: celebrationFadeIn .25s ease-out forwards;
}

.celebration-confetti {
  position: fixed;
  inset: 0;
  z-index: -1;
}

.celebration-card {
  position: relative;
  z-index: 1;
  width: min(520px, 92vw);
  max-height: 85vh;
  overflow: auto;
  padding: 28px 24px;
  border-radius: 18px;
  background: linear-gradient(135deg, rgba(255,255,255,.08), rgba(255,255,255,.03));
  border: 1.5px solid rgba(255,255,255,.14);
  box-shadow: 0 24px 52px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.06);
  text-align: center;
  color: var(--fg);
  cursor: default;
  transform: translateY(10px) scale(.98);
  animation: celebrationPop .4s cubic-bezier(.2,.9,.18,1.1) forwards .1s;
}

.celebration-avatar {
  width: 160px;
  max-width: 60%;
  height: auto;
  object-fit: contain;
  margin: 0 auto 12px;
  filter: drop-shadow(0 10px 24px rgba(138, 33, 137,.4));
  animation: celebrationBounce 1.1s ease-in-out infinite;
}

.celebration-title {
  margin: 6px 0 2px;
  font-weight: 800;
  font-size: 1.6rem;
}

.celebration-title.is-ok { color: var(--success); }
.celebration-title.is-warn { color: var(--warning); }

/* Las estrellas de la celebración: aparecen una a una, y las no ganadas se
   quedan como hueco apagado para que se vea lo que faltó. */
.celebration-estrellas {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 10px 0 6px;
}

.celebration-estrellas .estrella svg {
  width: 44px;
  height: 44px;
  display: block;
  fill: rgba(255,255,255,.14);
}

.celebration-estrellas .estrella.is-ganada {
  animation: estrellaGanada .5s cubic-bezier(.2,.9,.3,1.4) backwards;
}

.celebration-estrellas .estrella.is-ganada svg {
  fill: var(--gold);
  filter: drop-shadow(0 0 10px rgba(248, 200, 24, .55));
}

@keyframes estrellaGanada {
  from { opacity: 0; transform: scale(.2) rotate(-40deg); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .celebration-estrellas .estrella.is-ganada { animation: none; }
}

.celebration-message {
  margin: 0 0 6px;
  opacity: .9;
  font-size: .95rem;
}

.celebration-hint {
  display: block;
  margin-top: 8px;
  opacity: .7;
  font-size: .8rem;
}

@keyframes celebrationFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes celebrationPop {
  from { transform: translateY(12px) scale(.95); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}

@keyframes celebrationBounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}

@media (prefers-reduced-motion: reduce) {
  .celebration-overlay,
  .celebration-card,
  .celebration-avatar {
    animation: none !important;
  }
}

/* La meta del reto, encima del tablero: el mínimo deja de estar escondido en
   una pista. */
.meta-reto {
  /* Sin ancho propio: se alinea con la caja del juego, que ocupa el contenedor */
  margin: 0 0 14px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: rgba(248, 200, 24, .07);
  color: var(--muted);
  font-size: .92rem;
  text-align: center;
}

.meta-reto strong { color: var(--gold); }

/* Contenedor del juego de polígonos */
.polygon-game {
  max-width: 600px;
  margin: 0 auto;
}

.polygon-instructions {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--card-b);
  border-radius: 12px;
  padding: 16px;
  margin: 16px 0;
  text-align: center;
}

.polygon-instructions p {
  margin: 0;
  color: var(--muted);
}

.polygon-instructions strong {
  color: var(--fg);
}

.polygon-hint {
  margin-top: 8px !important;
  font-size: 0.85em;
  line-height: 1.4;
}

/* Contenedor principal */
.polygon-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

/* Stage del juego */
.polygon-stage {
  position: relative;
  width: min(480px, 100%);
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  background: #131a2a;
  box-shadow: 0 10px 30px rgba(0,0,0,.35);
  border: 1px solid var(--card-b);
  margin: 0 auto;
}

.polygon-stage canvas {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  border-radius: 12px;
}

/* Capa de nodos */
.polygon-nodes {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.polygon-node {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--muted);
  transform: translate(-50%, -50%);
  pointer-events: auto;
  cursor: pointer;
  transition: all 0.12s ease;
  z-index: 10;
}

.polygon-node:hover {
  background: var(--brand);
  transform: translate(-50%, -50%) scale(1.2);
}

.polygon-node.selected {
  background: var(--success);
  box-shadow: 0 0 10px rgba(53, 208, 127, 0.9);
  transform: translate(-50%, -50%) scale(1.3);
}

.polygon-node.adj {
  background: var(--brand);
  box-shadow: 0 0 12px rgba(255, 210, 59, 0.85);
  animation: polygonPulse 1.6s ease-in-out infinite;
}

@keyframes polygonPulse {
  0% {
    opacity: 0.6;
    transform: translate(-50%, -50%) scale(1.0);
  }
  50% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.15);
  }
  100% {
    opacity: 0.6;
    transform: translate(-50%, -50%) scale(1.0);
  }
}

/* Controles */
.polygon-controls {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

.polygon-controls .btn {
  padding: 10px 16px;
  font-size: 0.9rem;
}

.btn-secondary {
  background: transparent !important;
  border: 1px solid var(--card-b) !important;
}

.btn-secondary:hover {
  background: rgba(255,255,255,.05) !important;
  border-color: var(--accent) !important;
}

/* Mensaje del juego */
.polygon-message {
  text-align: center;
  color: var(--muted);
  font-size: 0.9rem;
  max-width: 400px;
  line-height: 1.4;
}

/* Responsive */
@media (max-width: 560px) {
  .polygon-node {
    width: 10px;
    height: 10px;
  }
  
  .polygon-controls {
    gap: 8px;
  }
  
  .polygon-controls .btn {
    padding: 8px 12px;
    font-size: 0.85rem;
  }
  
  .polygon-instructions {
    padding: 12px;
    font-size: 0.9rem;
  }
}

/* Estilos de mezcla-quimica (matraces) y de los paneles compartidos */

/* Contenedor del juego de mezcla */
.mezcla-game {
  max-width: 700px;
  margin: 0 auto;
}

/* Compuestos por sintetizar: uno o dos, y con dos hay que ver cuál queda */
.mezcla-objetivos {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--card-b);
  border-radius: 12px;
  padding: 16px;
  margin: 16px 0;
  text-align: center;
}

.objetivos-titulo {
  margin: 0 0 10px;
  color: var(--muted);
  font-size: 1.1rem;
}

.objetivos-lista {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
}

.objetivo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 120px;
  padding: 10px 16px;
  border: 1px solid var(--card-b);
  border-radius: 10px;
  background: rgba(255,255,255,.03);
}

.objetivo.hecho {
  background: rgba(16, 185, 129, 0.1);
  border-color: rgba(16, 185, 129, 0.3);
}

.objetivo.hecho .target-amount {
  color: var(--success);
  text-decoration: line-through;
}

.objetivo-estado {
  color: var(--muted);
  font-size: 0.85rem;
}

.objetivo.hecho .objetivo-estado {
  color: var(--success);
}

.target-amount {
  color: var(--accent);
  font-weight: bold;
  font-size: 1.3rem;
}

/* Contenedor de recipientes */
.mezcla-matraces {
  display: flex;
  justify-content: space-around;
  align-items: flex-end;
  margin: 30px 0;
  padding: 20px;
  background: rgba(255,255,255,.02);
  border-radius: 12px;
  border: 1px solid var(--card-b);
  min-height: 200px;
}

/* Recipiente individual */
.matraz {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  transition: all 0.3s ease;
  padding: 10px;
  border-radius: 12px;
}

.matraz:hover {
  transform: translateY(-5px);
  background: rgba(255,255,255,.05);
}

.matraz.selected {
  background: rgba(255, 210, 59, 0.15);
  border: 2px solid var(--accent);
  transform: translateY(-5px);
  box-shadow: 0 0 20px rgba(255, 210, 59, 0.3);
}

/* Labels de capacidad */
.capacity-label {
  margin-bottom: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent);
}

/* El matraz: cuello estrecho arriba y cono ancho abajo, recortado con
   clip-path. El líquido es un hijo que crece desde abajo, así que el recorte
   le da solo la forma -- el porcentaje de altura sigue siendo el nivel real,
   no el volumen del cono. Un borde normal se cortaría con el clip, así que el
   contorno del vidrio lo pone un drop-shadow del contenedor. */
.matraz-cuerpo {
  width: 80px;
  --matraz-silueta: polygon(32% 0, 68% 0, 68% 30%, 100% 100%, 0 100%, 32% 30%);
  clip-path: var(--matraz-silueta);
  background: rgba(255,255,255,.06);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  filter: drop-shadow(0 0 1px var(--card-b));
  transition: filter 0.3s ease;
}

.matraz-cuerpo:hover {
  filter: drop-shadow(0 0 3px var(--accent));
}

/* El reactivo, en el morado de marca del icono del tipo */
.reactivo {
  width: 100%;
  background: linear-gradient(180deg, var(--brand-lift), var(--brand-deep));
  transition: height 0.4s ease;
  position: relative;
  box-shadow: 0 -2px 10px rgba(138, 33, 137, 0.55);
}

/* Segundo compuesto: mismo reactivo fungible, pero se recolorea al azul de
   marca en cuanto se vierte el primero, para que no parezca el mismo
   líquido sin más durante toda la síntesis en cadena. */
.reactivo.compuesto-2 {
  background: linear-gradient(180deg, var(--blue-text), #0d4d70);
  box-shadow: 0 -2px 10px rgba(23, 136, 199, 0.55);
}

.reactivo::before {
  content: '';
  position: absolute;
  top: -2px;
  left: 0;
  right: 0;
  height: 4px;
  background: rgba(255,255,255,0.3);
  border-radius: 50%;
  opacity: 0.8;
}

/* Controles */
.panel-controls {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin: 20px 0;
}

/* Sección del reactor (el gesto de comprobar) */
.mezcla-reactor {
  display: flex;
  justify-content: center;
  margin: 30px 0;
}

.reactor-button {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  background: rgba(138, 33, 137, 0.14);
  border: 2px solid rgba(163, 43, 160, 0.4);
  border-radius: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
  max-width: 200px;
}

.reactor-button:hover {
  background: rgba(138, 33, 137, 0.24);
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(138, 33, 137, 0.3);
}

.reactor-button.celebration {
  animation: reactorGlow 2s infinite;
}

@keyframes reactorGlow {
  0%, 100% {
    box-shadow: 0 0 20px rgba(163, 43, 160, 0.55);
    transform: scale(1);
  }
  50% {
    box-shadow: 0 0 30px rgba(163, 43, 160, 0.85);
    transform: scale(1.05);
  }
}

.reactor-icon {
  margin-bottom: 10px;
  filter: drop-shadow(0 0 10px rgba(163, 43, 160, 0.8));
}

.reactor-icon img {
  display: block;
  width: 72px;
  height: 72px;
}

.reactor-text {
  text-align: center;
  color: var(--fg);
  font-weight: 500;
}

.reactor-text small {
  color: var(--muted);
  font-size: 0.8rem;
}

/* Mensaje de estado */
.panel-message {
  text-align: center;
  color: var(--muted);
  font-size: 1rem;
  margin: 15px 0;
  padding: 10px;
  background: rgba(255,255,255,.03);
  border-radius: 8px;
  min-height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.panel-message.ko {
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  color: var(--error);
}

.panel-message.ok {
  background: rgba(16, 185, 129, 0.1);
  border: 1px solid rgba(16, 185, 129, 0.3);
  color: var(--success);
}

/* Responsive */
@media (max-width: 768px) {
  .mezcla-matraces {
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
    min-height: auto;
    padding: 15px;
  }
  
  .matraz-cuerpo {
    width: 60px;
  }
  
  .capacity-label {
    font-size: 0.8rem;
  }
  
  .reactor-icon img {
    width: 56px;
    height: 56px;
  }
  
  .celebration-text {
    font-size: 2rem;
  }
  
  .celebration-emoji {
    font-size: 3rem;
  }
}

@media (max-width: 480px) {
  .mezcla-matraces {
    flex-direction: column;
    align-items: center;
  }
  
  .matraz {
    margin-bottom: 15px;
  }
  
  .panel-controls {
    flex-wrap: wrap;
  }
}
/* =========================================================
   style.css — Balanza Lógica (versión corregida y centrada)
   - Centrado robusto
   - Menos aire vertical
   - Cuerda más larga y platos más abajo
   - Moneda en plato vuelve al pool con clic (compatible con JS)
   - Celebración con Deceerre disponible
   - Accesibilidad (focus) y reduce motion
   ========================================================= */

/* ---------- Contenedor del juego ---------- */
.balance-game {
  max-width: 800px;
  margin: 0 auto;
  display: grid;           /* centrado robusto en cualquier layout padre */
  justify-items: stretch;  /* los hijos ocupan el ancho completo de la columna */
}

/* ---------- Instrucciones ---------- */
.balance-instructions {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--card-b);
  border-radius: 12px;
  padding: 16px;
  margin: 16px 0;
  text-align: center;
  color: var(--muted);
  font-size: 1.1rem;
}

/* ---------- Contador de pesadas ---------- */
.weighings-info {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: rgba(255,255,255,.06);
  border: 1px solid var(--card-b);
  border-radius: 20px;
  margin: 8px auto;    /* menos aire */
  width: fit-content;
  font-size: 0.9rem;
  color: var(--muted);
}
.weighings-count {
  color: var(--accent);
  font-size: 1.1rem;
  font-weight: bold;
}

/* ---------- Pool de monedas ---------- */
.balance-coins {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  padding: 20px;
  background: rgba(255,255,255,.02);
  border: 1px solid var(--card-b);
  border-radius: 12px;
  margin: 12px 0;      /* más compacto */
}

/* Monedas */
.balance-coin {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: radial-gradient(120% 120% at 30% 30%, #ffe58f, var(--gold));
  border: 2px solid rgba(0,0,0,0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: #2a2a2a;
  cursor: pointer;
  user-select: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease, outline 0.1s ease;
  position: relative;
  z-index: 5; /* por si algún stacking context del plato interfiere */
}
.balance-coin:hover {
  box-shadow: 0 6px 18px rgba(255,210,59,0.35);
  transform: scale(1.05);
}
.balance-coin.selected {
  outline: 3px solid var(--success);
  transform: scale(1.1);
}
/* Moneda cuando está en el plato (lo marca el JS) */
.balance-coin.in-plate {
  transform: scale(0.92);
  z-index: 20;
}

/* ---------- Contenedor de la balanza ---------- */
.balance-container {
  position: relative;
  width: 100%;
  max-width: 600px;
  height: 280px;       /* más compacta */
  margin: 8px auto;    /* “sube” la balanza */
  display: block;
}

/* Pivote (fallback; el JS ya aplica inline) */
.balance-pivot {
  position: absolute;
  bottom: 55px;
  left: 50%;
  transform: translateX(-50%);
  width: 30px;
  height: 30px;
  background: linear-gradient(145deg, #666, #333);
  border-radius: 8px;
  box-shadow: 0 4px 15px rgba(0,0,0,0.5);
  z-index: 3;
}

/* Barra (fallback por si el JS usa clases en vez de inline) */
.balance-beam {
  position: absolute;
  bottom: 70px;
  left: 50%;
  transform: translateX(-50%);
  width: 500px;
  height: 12px;
  background: linear-gradient(180deg, #ccc, #999);
  border-radius: 6px;
  transition: transform 0.6s ease;
  transform-origin: center;
  z-index: 2;
}
.balance-beam.tilt-left  { transform: translateX(-50%) rotate(-6deg); }
.balance-beam.tilt-right { transform: translateX(-50%) rotate(6deg); }
.balance-beam.balanced   { transform: translateX(-50%) rotate(0deg); }

/* Ganchos (fallback) */
.balance-hook {
  position: absolute;
  top: -5px;
  width: 4px;
  height: 20px;
}
.balance-hook.left  { left: 50px; }
.balance-hook.right { right: 50px; }

/* Cuerdas (alargar para “llegar” al plato) */
.balance-rope {
  position: absolute;
  top: 12px;
  left: 1px;
  width: 2px;
  height: 110px;  /* antes 80px */
  background: #888;
  transform-origin: top;
}

/* Platos (más abajo para mayor distancia barra ↔ plato) */
.balance-plate {
  position: absolute;
  top: 140px;    /* antes 92px */
  left: -100px;
  width: 200px;
  height: 20px;
  background: linear-gradient(180deg, #ddd, #aaa);
  border-radius: 20px;
  border: 2px solid rgba(0,0,0,0.3);
  cursor: pointer;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}
.balance-plate:hover {
  background: linear-gradient(180deg, #eee, #bbb);
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}

/* Área donde el JS posiciona las monedas del plato.
   Nota: pointer-events desactivado para el contenedor,
   y reactivado en las monedas (.balance-coin) vía JS o selector descendiente. */
.plate-coins {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  width: 180px;
  height: 120px;
  overflow: visible;
  pointer-events: none;
}
.plate-coins > .balance-coin {
  pointer-events: auto;  /* permite clic para devolver al pool */
}

/* ---------- Controles ---------- */
.balance-controls {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin: 16px 0;
  flex-wrap: wrap;
}
.balance-controls .btn {
  padding: 10px 16px;
  font-size: 0.9rem;
}

/* ---------- Mensajes ---------- */
.balance-message {
  text-align: center;
  padding: 10px;
  margin: 10px 0;
  border-radius: 8px;
  font-weight: 500;
}
.balance-message.info {
  background: rgba(16, 132, 199, 0.1);
  border: 1px solid rgba(16, 132, 199, 0.3);
  color: var(--secondary);
}
.balance-message.success {
  background: rgba(16, 185, 129, 0.1);
  border: 1px solid rgba(16, 185, 129, 0.3);
  color: var(--success);
}
.balance-message.error {
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  color: var(--error);
}
.balance-message.warning {
  background: rgba(245, 158, 11, 0.1);
  border: 1px solid rgba(245, 158, 11, 0.3);
  color: var(--warning);
}

/* ---------- Sección de respuesta ---------- */
.balance-answer-section {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--card-b);
  border-radius: 12px;
  padding: 20px;
  margin: 20px 0;
}
.balance-answer-section h3 {
  margin: 0 0 15px 0;
  text-align: center;
  color: var(--fg);
}
/* Fuerza centrado del botón principal (además de inline style en JS) */
.balance-answer-section .btn.btn-primary {
  display: block;
  width: fit-content;
  margin: 12px auto 0;
}

.answer-title {
  font-weight: 600;
  text-align: center;
  margin-bottom: 12px;
  color: var(--fg);
}

.answer-coins {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 15px 0;
}

.answer-coin {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(255,255,255,.1);
  border: 2px solid var(--card-b);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  color: var(--fg);
  cursor: pointer;
  transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}
.answer-coin:hover {
  background: rgba(255,255,255,.15);
  border-color: var(--accent);
  transform: scale(1.1);
}
.answer-coin.selected {
  background: var(--brand);
  border-color: var(--accent);
  color: var(--bg); /* legible sobre acento claro */
  transform: scale(1.1);
}

.sign-selector {
  display: flex;
  gap: 20px;
  justify-content: center;
  margin: 15px 0;
}
.sign-selector label {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  cursor: pointer;
}
.sign-selector input[type="radio"] {
  accent-color: var(--accent);
}

.answer-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}
.answer-section {
  background: rgba(255,255,255,.02);
  border: 1px solid var(--card-b);
  border-radius: 8px;
  padding: 12px;
}
.section-title {
  font-weight: 600;
  text-align: center;
  margin-bottom: 10px;
  color: var(--muted);
  font-size: 0.9rem;
}

/* ---------- Accesibilidad: foco visible ---------- */
.balance-coin:focus-visible,
.answer-coin:focus-visible,
.balance-plate:focus-visible,
.balance-controls .btn:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(138, 33, 137,.25);
}

/* ---------- Reduce Motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .balance-beam,
  .balance-coin,
  .answer-coin {
    transition: none !important;
    animation: none !important;
  }
}

/* ---------- Animaciones ---------- */
@keyframes slideLight {
  0% { left: -100%; }
  50% { left: 100%; }
  100% { left: 100%; }
}
@keyframes bounce {
  0%,20%,50%,80%,100% { transform: translateY(0); }
  40% { transform: translateY(-10px); }
  60% { transform: translateY(-5px); }
}
@keyframes sparkle {
  0%,100% { opacity: 0.3; transform: scale(1); }
  50% { opacity: 0.7; transform: scale(1.1); }
}

/* ---------- Responsive ---------- */
@media (max-width: 768px) {
  .balance-container {
    height: 260px;
    max-width: 400px;
    margin: 8px auto;
  }
  .balance-beam { width: 350px; }
  .balance-plate {
    width: 150px;
    left: -75px;
    top: 130px;   /* acompasa el descenso en móvil */
  }
  .balance-rope { height: 100px; }
  .balance-coin {
    width: 40px;
    height: 40px;
    font-size: 0.9rem;
  }
  .answer-grid {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .celebration-text { font-size: 2rem; }
  .celebration-emoji { font-size: 3rem; }
}

@media (max-width: 480px) {
  .balance-coins { padding: 15px; }
  .balance-controls { gap: 8px; }
  .balance-controls .btn {
    padding: 8px 12px;
    font-size: 0.85rem;
  }
}
/* =========================================================
   Ajuste visual Enigma de Einstein dentro del tema MathGym
   ========================================================= */

/* Contenedor general y grid */
#contenedor-interactivo .template-box {
  max-width: 1100px;
  margin: 0 auto 60px;
  padding: 0 20px;
  text-align: initial;
}

#contenedor-interactivo .ein-grid {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  gap: 24px;
  margin-top: 20px;
}

@media (max-width: 968px) {
  #contenedor-interactivo .ein-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }
}

/* Pistas */
#contenedor-interactivo .ein-clues {
  text-align: left;
}
#contenedor-interactivo .ein-clues h2 {
  text-align: center;
  font-weight: 700;
}
#contenedor-interactivo .ein-clues ol {
  list-style: decimal;
  list-style-position: outside;
  padding-left: 1.2rem;
  margin: 8px 0 14px;
}
#contenedor-interactivo .ein-clues li {
  margin: 6px 0;
  line-height: 1.5;
  color: var(--fg);
}
/* Tablero */
#contenedor-interactivo .ein-board h2 {
  text-align: center;
  font-weight: 700;
}
#contenedor-interactivo .ein-board-grid {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
/* Comprobar/Borrar todo van debajo del tablero (antes vivian junto a las
   pistas, lejos de donde se acaba de jugar) y resaltados en un panel propio
   para que no se confundan con el resto de controles de la pagina. */
#contenedor-interactivo .ein-board-actions {
  margin-top: 16px;
  padding: 12px;
  border: 1px solid rgba(209, 99, 204, 0.3);
  border-radius: 12px;
  background: rgba(209, 99, 204, 0.05);
}
#contenedor-interactivo .ein-board-actions .toolbar {
  justify-content: center;
  margin: 0;
}
#contenedor-interactivo .ein-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 4px;
}
/* Con 5 casas la fila mide 5x80 px y no cabe en un móvil: el tablero ya
   vive dentro de un contenedor con scroll horizontal propio
   (.ein-board-grid), y el `min-width` es lo que impide que la tabla se
   estruje hasta volverse ilegible en vez de dejar que ese scroll haga su
   trabajo. */
#contenedor-interactivo .ein-table .cell,
#contenedor-interactivo .ein-table th.house-header {
  min-width: 64px;
}
/* Con 5 casas la fila entera son 5x80 px y no cabe ni en la columna del
   tablero ni en un móvil. La celda encoge -- sigue siendo un blanco
   cómodo de tocar -- y la rejilla le cede ancho a costa de las pistas
   (ver applyLayout en plantillas/enigma_einstein.js). */
#contenedor-interactivo .ein-grid[data-casas="5"] .ein-table .cell {
  width: 64px;
  height: 64px;
}
#contenedor-interactivo .ein-grid[data-casas="5"] .ein-table .cell,
#contenedor-interactivo .ein-grid[data-casas="5"] .ein-table th.house-header {
  min-width: 56px;
}
#contenedor-interactivo .ein-table .cell {
  width: 80px;
  height: 80px;
  background: rgba(255,255,255,.06);
  border: 2px solid var(--card-b);
  border-radius: 8px;
  box-sizing: border-box;
  transition: all 0.2s ease;
  vertical-align: top;
  overflow: hidden;
}
#contenedor-interactivo .ein-table .cell:hover {
  background: rgba(255,255,255,.1);
  border-color: var(--accent);
}

/* Chips: la celda tiene tamaño fijo (arriba); es la ficha soltada la que
   tiene que encogerse y partir su texto dentro de ese hueco, no al reves --
   si no, un valor largo ensanchaba la celda entera (y con ella toda la
   columna de la tabla). */
#contenedor-interactivo .chips {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 2px;
  align-items: flex-start;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  overflow: hidden;
}
#contenedor-interactivo .chip {
  background: var(--grad-brand);
  color: white;
  border: none;
  border-radius: 6px;
  padding: 1px 2px;
  min-width: 0;
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  text-align: center;
  font-size: 0.52rem;
  line-height: 1.1;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
}
#contenedor-interactivo .chip:hover {
  background: var(--grad-brand);
  transform: scale(1.05);
}

/* Tarjetas */
#contenedor-interactivo .ein-palette h2 {
  text-align: center;
  font-weight: 700;
}
#contenedor-interactivo .ein-group {
  margin-bottom: 16px;
}
#contenedor-interactivo .ein-group h3 {
  margin: 0 0 8px;
  font-size: 1rem;
  color: var(--fg);
  text-align: left;
}
#contenedor-interactivo .ein-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
#contenedor-interactivo .ein-cards .card {
  background: rgba(255,255,255,.08);
  border: 1px solid var(--card-b);
  border-radius: 8px;
  padding: 8px 12px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 0.9rem;
  color: var(--fg);
  font-family: inherit;
}
#contenedor-interactivo .ein-cards .card:hover {
  background: rgba(255,255,255,.15);
  border-color: var(--accent);
  transform: translateY(-1px);
}
#contenedor-interactivo .ein-cards .card.is-selected {
  background: var(--grad-brand);
  border-color: var(--accent);
  color: white;
  box-shadow: 0 4px 12px rgba(138, 33, 137, 0.3);
}

/* Feedback */
#contenedor-interactivo .feedback {
  border-radius: 8px;
  margin-top: 10px;
  text-align: center;
}
/* ==== Drag & Drop visual para columnas del Enigma ==== */
.house-header {
  cursor: grab;
  user-select: none;
  background: rgba(255,255,255,.06);
  padding: 8px 10px;
  border-radius: 8px;
  text-align: center;
  transition: all 0.2s ease;
}

.house-header:hover {
  background: rgba(255,255,255,.12);
}

.house-header.dragging {
  opacity: 0.5;
  background: var(--brand);
  color: #fff;
  cursor: grabbing;
  transform: scale(1.05);
}

/* Animación de desplazamiento visual de columnas */
.ein-table td,
.ein-table th {
  transition: transform 0.2s ease;
}

/* =========================================================
   Relojes de Arena
   ========================================================= */

.sand-clock {
  text-align: center;
  margin: 8px 0 16px;
  color: var(--muted);
}

.sand-clock-value {
  color: var(--accent);
  font-size: 1.4rem;
  font-variant-numeric: tabular-nums;
}

.sand-glasses {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: 40px;
  flex-wrap: wrap;
  margin: 8px 0 24px;
}

.sand-glass {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.sand-glass.locked {
  cursor: not-allowed;
}

.sand-glass-label {
  color: var(--muted);
  font-size: .85rem;
  font-weight: 600;
}

.sand-glass-body {
  width: var(--glass-size, 72px);
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: filter .2s ease;
}

.sand-glass.running .sand-glass-body {
  filter: drop-shadow(0 0 8px rgba(217,164,65,.5));
}

.sand-glass.empty .sand-glass-body {
  filter: grayscale(.4) opacity(.6);
}

/* Bulbos triangulares: el superior apunta hacia abajo, el inferior hacia arriba */
.sand-bulb {
  position: relative;
  width: var(--glass-size, 72px);
  height: var(--glass-size, 72px);
  background: rgba(255,255,255,.05);
  filter: drop-shadow(0 0 0 1.5px var(--card-b));
  transition: width .2s ease, height .2s ease;
}

.sand-bulb-top {
  clip-path: polygon(4% 0%, 96% 0%, 50% 96%);
}

.sand-bulb-bottom {
  clip-path: polygon(50% 4%, 96% 100%, 4% 100%);
}

.sand-neck {
  width: 10px;
  height: 4px;
  background: var(--card-b);
  flex-shrink: 0;
}

.sand-fill {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 0%;
  background: linear-gradient(180deg, #e9c46a, #d9a441);
  transition: height .2s linear;
}

/* ===== Anillas Encadenadas ===== */
.anillas-info {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin: 4px 0 16px;
  font-size: 0.95rem;
  color: var(--fg);
}

.anillas-hint {
  text-align: center;
  margin: -8px 0 8px;
  font-size: 0.85rem;
  color: var(--accent);
}

.anillas-bar-container {
  position: relative;
  padding: 32px 12px 20px;
}

.anillas-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--card-b);
  margin: 0 auto 28px;
  max-width: 90%;
}

.anillas-row {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 18px;
}

.anillas-ring {
  position: relative;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  border: 6px solid var(--brand-lift);
  background: rgba(138, 33, 137, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: var(--fg);
  cursor: pointer;
  transition: transform 0.2s ease, opacity 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

.anillas-ring::before {
  content: '';
  position: absolute;
  top: -26px;
  left: 50%;
  transform: translateX(-50%);
  width: 3px;
  height: 26px;
  background: var(--card-b);
}

.anillas-ring:hover {
  border-color: var(--accent);
}

.anillas-ring.is-off {
  opacity: 0.4;
  transform: translateY(28px);
  border-color: var(--card-b);
  background: transparent;
}

.anillas-ring.is-legal {
  animation: anillasPulse 1.6s ease-in-out infinite;
}

/* Una anilla suelta que sigue siendo tocable (para volver a engancharla)
   necesita distinguirse claramente de una suelta y NO tocable: si no, el
   atenuado de .is-off (opacidad 40%) casi anula el brillo dorado y parece
   que no se puede tocar aunque sí se pueda. */
.anillas-ring.is-off.is-legal {
  opacity: 0.85;
  border-color: #ffd23b;
}

/* Fila de referencia con el objetivo, para las variantes en las que no hay
   que soltarlas todas sino dejarlas en una posición concreta. Son marcas, no
   anillas jugables: más pequeñas, sin cursor y sin la barra de la que
   cuelgan. */
.anillas-objetivo {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 4px 0 12px;
  flex-wrap: wrap;
}

.anillas-objetivo-label {
  font-size: 0.85rem;
  color: var(--muted, #aab3c5);
}

.anillas-objetivo-row {
  display: flex;
  gap: 10px;
}

.anillas-meta-ring {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 3px solid var(--brand-lift);
  background: rgba(138, 33, 137, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--fg);
}

.anillas-meta-ring.is-off {
  opacity: 0.35;
  border-style: dashed;
  border-color: var(--card-b);
  background: transparent;
}

@keyframes anillasPulse {
  0%, 100% { box-shadow: 0 0 0 rgba(255, 210, 59, 0); }
  50% { box-shadow: 0 0 14px rgba(255, 210, 59, 0.85); }
}

.anillas-controls {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

@media (max-width: 560px) {
  .anillas-row {
    gap: 12px;
  }

  .anillas-ring {
    width: 44px;
    height: 44px;
    border-width: 5px;
    font-size: 0.85rem;
  }

  .anillas-ring.is-off {
    transform: translateY(20px);
  }
}

/* ===== Cajas Apiladas ===== */
.cajas-info {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin: 4px 0 16px;
  font-size: 0.95rem;
  color: var(--fg);
}

/* Aviso de lo que lleva la carretilla ahora mismo (mecánica de carga por
   kilos): ocupa siempre su hueco para que el tablero no dé un salto al
   cargar y descargar. */
.cajas-carga {
  min-height: 1.4em;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent);
}

.cajas-board {
  display: flex;
  justify-content: space-around;
  align-items: flex-end;
  gap: 16px;
  padding: 20px 12px 12px;
}

.cajas-zona {
  position: relative;
  flex: 1;
  min-width: 0;
  max-width: 220px;
  height: 200px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  cursor: pointer;
  padding-bottom: 8px;
  border-radius: 10px;
  transition: background 0.15s ease;
}

.cajas-zona:hover {
  background: rgba(255,255,255,.04);
}

.cajas-zona.is-selected {
  background: rgba(138, 33, 137, 0.15);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.cajas-stack {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 3px;
}

.cajas-caja {
  max-width: 100%;
  height: 26px;
  border-radius: 4px;
  background: linear-gradient(180deg, #e9c46a, #d9a441);
  border: 1px solid var(--card-b);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 700;
  color: #2b2410;
  box-shadow: 0 2px 6px rgba(0,0,0,.3);
}

/* Las cajas que van cargadas en la carretilla se levantan un poco y se
   marcan, para ver de un vistazo qué se está moviendo. */
.cajas-caja.is-selected {
  background: linear-gradient(180deg, #f3d98a, #e0b455);
  box-shadow: 0 0 0 2px var(--accent), 0 4px 10px rgba(0,0,0,.35);
  transform: translateX(6px);
}

.cajas-suelo {
  width: 90%;
  max-width: 200px;
  height: 4px;
  background: var(--card-b);
  border-radius: 2px;
  margin-top: 6px;
}

.cajas-zona-label {
  position: relative;
  z-index: 1;
  margin-top: 6px;
  font-weight: 700;
  color: var(--muted);
}

.cajas-controls {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

@media (max-width: 560px) {
  .cajas-board {
    gap: 8px;
    padding: 16px 4px 8px;
  }

  .cajas-zona {
    height: 150px;
  }

  .cajas-caja {
    height: 20px;
    font-size: 0.65rem;
  }
}

/* ===== Nonograma ===== */
.nono-board-wrap {
  overflow-x: auto;
  padding: 8px 0;
}

.nono-board {
  --nono-cell-size: 32px;
  display: grid;
  grid-template-columns: var(--nono-cell-size) repeat(var(--nono-cols), var(--nono-cell-size));
  gap: 2px;
  margin: 8px auto;
  width: fit-content;
}

.nono-corner,
.nono-cell {
  width: var(--nono-cell-size);
  height: var(--nono-cell-size);
}

/* min-height, no height: en color una columna puede tener mas bloques que
   una fila de casillas alta (colores distintos no necesitan hueco), y con
   altura fija esos numeros de mas quedaban recortados y tapados por la
   primera fila del tablero, que se pinta encima. */
.nono-clue-col {
  width: var(--nono-cell-size);
  min-height: var(--nono-cell-size);
}

.nono-clue {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--muted);
  transition: color 0.15s ease;
}

.nono-clue-col {
  flex-direction: column;
  padding-bottom: 4px;
}

.nono-clue-row {
  justify-content: flex-end;
  padding-right: 6px;
}

.nono-clue.is-done {
  color: var(--success);
}

.nono-cell {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--card-b);
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: var(--muted);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.nono-cell:hover {
  border-color: var(--accent);
}

.nono-cell.is-filled {
  background: var(--grad-brand);
  border-color: var(--card-b);
}

/* Barra de color del nonograma multicolor: elige con qué se pinta. En el
   monocromo no se monta, y el resto del tablero queda igual. */
.nono-paleta {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 16px 0;
}

.nono-color {
  width: 40px;
  height: 40px;
  border: 2px solid var(--card-b);
  border-radius: 10px;
  cursor: pointer;
  padding: 0;
  transition: transform 0.15s ease, border-color 0.15s ease;
}

.nono-color:hover {
  transform: translateY(-2px);
}

/* El activo se marca con el borde y un anillo, no solo con el color: dos
   colores de la paleta ya compiten entre sí ahí. */
.nono-color.is-active {
  border-color: var(--fg);
  box-shadow: 0 0 0 3px rgba(255,255,255,.18);
}

.nono-controls {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

@media (max-width: 560px) {
  .nono-board {
    --nono-cell-size: 26px;
  }

  .nono-clue {
    font-size: 0.65rem;
  }
}

/* ===== Láseres y Espejos ===== */
.laser-board-wrap {
  overflow-x: auto;
  padding: 8px 0;
}

.laser-board {
  display: grid;
  grid-template-columns: repeat(var(--laser-cols), var(--laser-cell-size));
  gap: 2px;
  margin: 8px auto;
  width: fit-content;
}

/* Envoltorio de la malla triangular (laser_triangular.js): apila el
   tablero, el SVG de los rayos y la capa de vertices en el mismo
   rectángulo, para poder dibujar líneas finas y botones de vértice por
   encima de las celdas. --laser-cell-size vive aquí (no en .laser-board)
   porque la capa de vértices es HERMANA de .laser-board, no descendiente:
   una custom property no cruza entre hermanos, solo de padre a hijo. */
.laser-board-stack {
  --laser-cell-size: 36px;
  position: relative;
  width: fit-content;
  margin: 8px auto;
}

.laser-board-stack .laser-board {
  margin: 0;
}

/* Sin separación entre celdas: así el SVG (que usa un viewBox de
   "una unidad por celda") coincide en píxeles con la cuadrícula real */
.laser-board-mesh {
  gap: 0;
}

.laser-beams {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.laser-beam-line {
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  opacity: 0.95;
}

/* Espejos-vertice: viven en el BORDE compartido por dos celdas (retícula
   (n+1)x(n+1)), no dentro de ninguna, así que se dibujan en una capa
   aparte por encima del tablero -- por orden en el DOM (se añade tras el
   SVG), no por z-index, igual que el resto de esta hoja. */
.laser-vertice-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.laser-vertice {
  position: absolute;
  width: 20px;
  height: 20px;
  transform: translate(-50%, -50%);
  pointer-events: auto;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* Mismo lenguaje visual que un espejo normal (.laser-pieza[data-pieza]):
   barra reflectante blanca con resplandor, no un color aparte -- es la
   MISMA pieza, solo que anclada en el vértice en vez de dentro de una
   celda. Ancho relativo a --laser-cell-size (no al 20px fijo de
   .laser-vertice: eso daba una barra de solo 14px, sin escalar con el
   tablero real). 80% de la celda, no 100%, porque cubre solo la mitad
   del borde compartido, no el ancho entero de una celda. */
.laser-vertice::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--laser-cell-size) * 0.8);
  height: 4px;
  transform: translate(-50%, -50%);
  background: linear-gradient(90deg, transparent, #fff, #f3d9f1, #fff, transparent);
  border-radius: 2px;
  opacity: 0;
}

.laser-vertice:hover::after {
  opacity: 0.35;
  background: #ffd23b;
}

.laser-vertice[data-pieza="horiz"]::after,
.laser-vertice[data-pieza="vert"]::after {
  opacity: 1;
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.8);
}

.laser-vertice[data-pieza="vert"]::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.laser-cell {
  position: relative;
  width: var(--laser-cell-size);
  height: var(--laser-cell-size);
  background: rgba(255,255,255,.04);
  border: 1px solid var(--card-b);
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.laser-cell:hover {
  border-color: var(--accent);
}

.laser-cell.is-emitter,
.laser-cell.is-target,
.laser-cell.is-block {
  cursor: default;
  overflow: visible;
}

/* Emisor y diana llevan el borde sólido en su propio color, no solo un
   tinte de fondo, para que la pareja se distinga de un vistazo */
.laser-cell.is-emitter,
.laser-cell.is-target {
  border-color: var(--laser-color, currentColor);
  border-width: 2px;
}

/* Malla triangular (laser_triangular.js): cada celda lleva sus dos
   diagonales completas dibujadas en gris tenue, para que el tablero se lea
   como formado por triángulos en vez de cuadrados macizos */
.laser-board-mesh .laser-cell:not(.is-block)::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(45deg, transparent calc(50% - 1px), rgba(255, 255, 255, 0.12) calc(50% - 1px), rgba(255, 255, 255, 0.12) calc(50% + 1px), transparent calc(50% + 1px)),
    linear-gradient(135deg, transparent calc(50% - 1px), rgba(255, 255, 255, 0.12) calc(50% - 1px), rgba(255, 255, 255, 0.12) calc(50% + 1px), transparent calc(50% + 1px)),
    linear-gradient(0deg, transparent calc(50% - 1px), rgba(255, 255, 255, 0.06) calc(50% - 1px), rgba(255, 255, 255, 0.06) calc(50% + 1px), transparent calc(50% + 1px)),
    linear-gradient(90deg, transparent calc(50% - 1px), rgba(255, 255, 255, 0.06) calc(50% - 1px), rgba(255, 255, 255, 0.06) calc(50% + 1px), transparent calc(50% + 1px));
  pointer-events: none;
  z-index: 0;
}

/* Solo z-index: NO tocar "position" aquí. Cada hijo (boquilla, diana,
   insignia, pieza) ya declara su propia position (relative o absolute)
   en su regla específica; si esta regla también fijara position, al tener
   más especificidad (dos clases) pisaría ese valor -- por ejemplo
   .laser-pieza pasaría de "absolute" a "relative" y perdería el centrado
   exacto por top/left/transform. */
.laser-board-mesh .laser-cell > * {
  z-index: 1;
}

/* Insignia numerada: empareja emisor <-> diana sin depender solo del color */
.laser-badge {
  position: absolute;
  top: 1px;
  left: 1px;
  z-index: 3;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  background: var(--laser-color, #888);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
}

/* Bloqueo: rayas de peligro, para que se lea como un obstáculo real */
.laser-cell.is-block {
  background: repeating-linear-gradient(
    45deg,
    #331e33,
    #331e33 5px,
    #271327 5px,
    #271327 10px
  );
  border-color: var(--card-b);
}

/* Emisor: fuente con brillo pulsante, coloreada según --laser-color
   (cada láser tiene su color, fijado en línea desde laser.js) */
.laser-cell.is-emitter {
  background: radial-gradient(circle, color-mix(in srgb, var(--laser-color, #ff6b35) 35%, transparent), transparent 70%);
  animation: laserEmitterPulse 1.8s ease-in-out infinite;
}

/* Boquilla del emisor: un triangulo macizo apuntando a --laser-dir-rot.
   Sustituye al emoji ➤, que desentonaba con el resto de tableros. Sin
   top/left: .laser-cell es flex con align/justify-content: center, así que
   un hijo absoluto sin offset toma esa posición estática -- ya centrada --
   por spec. .laser-pieza sí fija top/left porque además necesita rotar
   sobre ese punto con transform; .laser-badge sí lo fija porque su sitio
   NO es el centro, sino la esquina. */
.laser-emisor {
  position: absolute;
  width: 62%;
  height: 62%;
  background: var(--laser-color, #ff6b35);
  clip-path: polygon(100% 50%, 15% 100%, 35% 50%, 15% 0%);
  transform: rotate(var(--laser-dir-rot, 0deg));
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--laser-color, #ff6b35) 90%, transparent));
}

@keyframes laserEmitterPulse {
  0%, 100% { box-shadow: inset 0 0 8px color-mix(in srgb, var(--laser-color, #ff6b35) 40%, transparent); }
  50% { box-shadow: inset 0 0 16px color-mix(in srgb, var(--laser-color, #ff6b35) 80%, transparent); }
}

/* Diana: anillos tipo radar en expansión, coloreada según --laser-color */
.laser-cell.is-target {
  background: radial-gradient(circle, color-mix(in srgb, var(--laser-color, #ffd23b) 15%, transparent), transparent 70%);
}

.laser-cell.is-target::before,
.laser-cell.is-target::after {
  content: '';
  position: absolute;
  inset: 4px;
  border: 2px solid color-mix(in srgb, var(--laser-color, #ffd23b) 70%, transparent);
  border-radius: 50%;
  animation: laserTargetPing 2s ease-out infinite;
}

.laser-cell.is-target::after {
  animation-delay: 1s;
}

@keyframes laserTargetPing {
  0% { transform: scale(0.6); opacity: 1; }
  100% { transform: scale(1.8); opacity: 0; }
}

/* Diana: la FORMA identifica el color, para que el reto se pueda jugar sin
   distinguirlos. El tinte va aparte, en --laser-color. */
.laser-diana {
  position: absolute;
  width: 46%;
  height: 46%;
  background: var(--laser-color, #ffd23b);
}
.laser-diana[data-forma="circulo"]   { border-radius: 50%; }
.laser-diana[data-forma="triangulo"] { clip-path: polygon(50% 0%, 100% 100%, 0% 100%); }
.laser-diana[data-forma="cuadrado"]  { border-radius: 2px; }
.laser-diana[data-forma="rombo"]     { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); }

.laser-cell.is-target.is-hit {
  background: radial-gradient(circle, rgba(53, 208, 127, 0.4), transparent 70%);
}

.laser-cell.is-target.is-hit::before,
.laser-cell.is-target.is-hit::after {
  border-color: var(--success);
  animation: none;
  transform: scale(1);
  opacity: 0.6;
}

/* Espejos: barra reflectante en vez de un carácter de texto. Ancho al
   142% (raíz de 2) para que llegue exactamente de esquina a esquina de la
   celda, como un espejo plano real, no una barra corta centrada */
.laser-pieza[data-pieza="slash"],
.laser-pieza[data-pieza="backslash"],
.laser-pieza[data-pieza="vert"],
.laser-pieza[data-pieza="horiz"] {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 142%;
  height: 3px;
  background: linear-gradient(90deg, transparent, #fff, #f3d9f1, #fff, transparent);
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.8);
  border-radius: 2px;
}

.laser-pieza[data-pieza="slash"] {
  transform: translate(-50%, -50%) rotate(-45deg);
}

.laser-pieza[data-pieza="backslash"] {
  transform: translate(-50%, -50%) rotate(45deg);
}

/* Espejos planos horizontal/vertical (laser_triangular.js): van de lado a
   lado de la celda (100%, no 142%, porque no son diagonales) */
.laser-pieza[data-pieza="horiz"],
.laser-pieza[data-pieza="vert"] {
  width: 100%;
}

.laser-pieza[data-pieza="horiz"] {
  transform: translate(-50%, -50%) rotate(0deg);
}

.laser-pieza[data-pieza="vert"] {
  transform: translate(-50%, -50%) rotate(90deg);
}

/* Prisma: triangulo hueco con el borde en degradado azul -> rojo, que es
   justo lo que hace con el rayo. */
.laser-pieza[data-pieza="prisma"] {
  position: absolute;
  width: 66%;
  height: 66%;
  background: linear-gradient(135deg, #3ec6ff, #ff5d5d);
  clip-path: polygon(50% 8%, 96% 92%, 4% 92%, 50% 8%, 50% 26%, 22% 82%, 78% 82%, 50% 26%);
}

/* Condensador: dos arcos que convergen en un punto. */
.laser-pieza[data-pieza="condensador"] {
  position: absolute;
  width: 66%;
  height: 66%;
  border: 2px solid #c084fc;
  border-radius: 50%;
  border-left-color: #3ec6ff;
  border-right-color: #ff5d5d;
  border-top-color: transparent;
  border-bottom-color: transparent;
}

/* Trayecto del rayo: degradado con pulso en el color de su propio láser
   (--laser-color-path), no un tinte plano */
.laser-cell.is-path {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--laser-color-path, #ff8c42) 35%, transparent),
    color-mix(in srgb, var(--laser-color-path, #ff8c42) 25%, transparent));
  border-color: color-mix(in srgb, var(--laser-color-path, #ff8c42) 70%, transparent);
  animation: laserBeamPulse 1.2s ease-in-out infinite;
}

@keyframes laserBeamPulse {
  0%, 100% { box-shadow: inset 0 0 4px color-mix(in srgb, var(--laser-color-path, #ff8c42) 30%, transparent); }
  50% { box-shadow: inset 0 0 10px color-mix(in srgb, var(--laser-color-path, #ff8c42) 70%, transparent); }
}

.laser-cell.is-hit {
  background: radial-gradient(circle, rgba(53, 208, 127, 0.45), rgba(53, 208, 127, 0.15));
  border-color: var(--success);
  animation: none;
  box-shadow: inset 0 0 12px rgba(53, 208, 127, 0.6);
}

/* Cruce entre dos trayectos: no permitido, se marca en rojo de alerta
   por encima del color de cualquiera de los dos láseres implicados */
.laser-cell.is-crossing {
  background: repeating-linear-gradient(
    45deg,
    rgba(255, 59, 59, 0.55),
    rgba(255, 59, 59, 0.55) 4px,
    rgba(120, 10, 10, 0.55) 4px,
    rgba(120, 10, 10, 0.55) 8px
  );
  border-color: #ff3b3b;
  animation: laserCrossAlert 0.9s ease-in-out infinite;
}

@keyframes laserCrossAlert {
  0%, 100% { box-shadow: inset 0 0 6px rgba(255, 59, 59, 0.5); }
  50% { box-shadow: inset 0 0 14px rgba(255, 59, 59, 0.9); }
}

.laser-controls {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 16px;
}

.laser-btn-lanzar {
  font-weight: 600;
}

/* Donde el rayo se apaga: contra un emisor o contra un bloque. */
.laser-cell.is-choque {
  animation: laserChoque 0.9s ease-in-out infinite;
  border-color: #ff5d5d;
}

@keyframes laserChoque {
  0%, 100% { box-shadow: inset 0 0 6px color-mix(in srgb, #ff5d5d 40%, transparent); }
  50%      { box-shadow: inset 0 0 14px color-mix(in srgb, #ff5d5d 90%, transparent); }
}

/* El rayo avanza en vez de aparecer de golpe. --laser-largo lo fija la
   plantilla con getTotalLength(). */
.laser-beam-line.is-lanzando {
  stroke-dasharray: var(--laser-largo);
  stroke-dashoffset: var(--laser-largo);
  animation: laserAvanza 0.45s ease-out forwards;
}

@keyframes laserAvanza {
  to { stroke-dashoffset: 0; }
}

/* Bandeja abierta: existencias infinitas de cada pieza, asi que sin
   contadores. touch-action: none para que arrastrar no haga scroll. */
.laser-tray {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin: 0 0 12px;
  touch-action: none;
}

.laser-tray-pieza {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 2px solid rgba(255, 255, 255, 0.18);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  cursor: grab;
  touch-action: none;
}

.laser-tray-pieza:hover { border-color: rgba(255, 255, 255, 0.4); }

/* Pieza armada: el siguiente toque en una celda la coloca. */
.laser-tray-pieza.is-armada {
  border-color: #ffd23b;
  box-shadow: 0 0 10px color-mix(in srgb, #ffd23b 60%, transparent);
}

.laser-tray-pieza:active { cursor: grabbing; }

/* Las piezas de la bandeja se dibujan con las mismas reglas que las del
   tablero, y se centran igual que .laser-emisor (ver el comentario de
   ahi): .laser-tray-pieza ahora es flex con align/justify-content:
   center, asi que un hijo absoluto SIN top/left cae ya centrado por
   spec -- que es el caso de prisma y condensador. Los cuatro espejos SI
   fijan su propio top/left/transform (ademas rotan sobre ese punto), y
   ese valor no lo toca esta regla.
   Antes habia aqui un `inset: 0; margin: auto;` con la misma
   especificidad que el top/left de los espejos y declarado despues en el
   archivo, asi que ganaba y les pisaba el top/left sin pisar su
   transform: translate(-50%,-50%) -- el resultado era una barra
   descentrada unos 31px, sin overflow:hidden en el boton que la recortara. */
.laser-board { touch-action: none; }

@media (max-width: 560px) {
  .laser-board-stack {
    --laser-cell-size: 30px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .laser-cell.is-emitter,
  .laser-cell.is-target::before,
  .laser-cell.is-target::after,
  .laser-cell.is-path,
  .laser-cell.is-crossing,
  .laser-cell.is-choque,
  .laser-emisor,
  .laser-diana {
    animation: none;
  }

  /* Sin animación de avance: quien tenga esto activado ve el rayo entero de
     golpe en vez de ninguno (stroke-dashoffset se quedaría en su valor
     inicial si la animación nunca llega a 'to'). */
  .laser-beam-line.is-lanzando {
    animation: none;
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
}

/* ===== Puentes de Hashi ===== */
.hashi-board-stack {
  position: relative;
  width: fit-content;
  margin: 8px auto;
}

.hashi-board {
  --hashi-cell-size: 42px;
  display: grid;
  grid-template-columns: repeat(var(--hashi-cols), var(--hashi-cell-size));
  grid-template-rows: repeat(var(--hashi-rows), var(--hashi-cell-size));
}

.hashi-cell {
  position: relative;
  width: var(--hashi-cell-size);
  height: var(--hashi-cell-size);
  display: flex;
  align-items: center;
  justify-content: center;
}

.hashi-bridges {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
}

.hashi-bridge-line {
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 0 3px rgba(159, 180, 255, 0.6));
}

.hashi-island-btn {
  position: relative;
  z-index: 2;
  /* El tamaño lo pone la plantilla, que lo deriva del grado del chip. */
  padding: 0;
  border: 0;
  /* Esquina redondeada, no círculo: el aro de estado se dibuja siguiendo
     este radio, y un halo redondo alrededor de un chip cuadrado cantaba. */
  border-radius: 26%;
  background: none;
  cursor: pointer;
  line-height: 0;
  transition: box-shadow 0.15s ease, filter 0.15s ease;
}

.hashi-island-btn svg {
  display: block;
}

.hashi-island-btn:hover {
  filter: brightness(1.18);
}

/* Los tres estados van en un aro POR FUERA del chip, nunca en su relleno:
   el cuerpo lleva el color del tramo de grado, y si los estados pintaran
   ahí se perderían los dos. */
.hashi-cell.is-island.is-selected .hashi-island-btn {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.75);
}

.hashi-cell.is-island.is-satisfied .hashi-island-btn {
  box-shadow: 0 0 0 3px var(--success);
}

.hashi-cell.is-island.is-over .hashi-island-btn {
  box-shadow: 0 0 0 3px #ff3b3b;
}

/* Seleccionado y satisfecho a la vez: el halo blanco por dentro y el verde
   por fuera, para que no se tape uno al otro. */
.hashi-cell.is-island.is-selected.is-satisfied .hashi-island-btn {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.75), 0 0 0 6px var(--success);
}

.hashi-cell.is-island.is-selected.is-over .hashi-island-btn {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.75), 0 0 0 6px #ff3b3b;
}

@media (max-width: 560px) {
  .hashi-board {
    --hashi-cell-size: 34px;
  }

  .hashi-island-btn {
    /* El tamaño lo pone la plantilla; aquí solo se encoge proporcionalmente. */
    transform: scale(0.85);
  }
}

/* ===== Muestrario de tipos de reto (muestrario.html) ===== */
.muestrario-grid {
  width: 100%;
  max-width: 900px;
  display: flex;
  flex-direction: column;
  gap: 28px;
  margin-top: 24px;
}

.muestrario-card {
  text-align: left;
  padding: 20px;
}

.muestrario-card-head {
  display: flex;
  align-items: center;
  gap: 20px;
}

.muestrario-icono {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  object-fit: contain;
}

@media (min-width: 700px) {
  .muestrario-icono { width: 96px; height: 96px; }
}

@media (min-width: 1000px) {
  .muestrario-icono { width: 112px; height: 112px; }
}

.muestrario-titulos h3 {
  margin: 0 0 4px;
}

.muestrario-resumen {
  margin: 0;
  color: var(--muted, #aab3c5);
  font-size: 0.95rem;
}

.muestrario-etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 4px;
}

.muestrario-tag {
  font-size: 0.75rem;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(255,255,255,.06);
  border: 1px solid var(--card-b);
}

.muestrario-tag-tipo {
  font-family: 'JetBrains Mono', monospace;
}

/* El ejemplo se monta aquí dentro; se reserva alto para que la página no
   pegue saltos al ir cargando las fichas al hacer scroll. */
.muestrario-host {
  min-height: 120px;
  margin-top: 8px;
}

.muestrario-cargando {
  color: var(--muted, #aab3c5);
  font-size: 0.9rem;
  padding: 24px 0;
  text-align: center;
}

.muestrario-diagnostico {
  width: 100%;
  max-width: 900px;
  margin-top: 16px;
  text-align: left;
}

.muestrario-error {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.8rem;
  color: #ff6b6b;
  margin: 4px 0;
}

.muestrario-debug {
  margin-top: 12px;
  font-size: 0.8rem;
  color: var(--muted, #aab3c5);
}

.muestrario-debug pre {
  overflow-x: auto;
  background: rgba(0,0,0,.25);
  padding: 10px;
  border-radius: 8px;
}

/* ===== El Riego (riego_plantas.js) ===== */
.riego-tabla-wrap {
  overflow-x: auto;
  margin: 8px 0 12px;
  /* Dentro de .riego-layout es un item flex más, entre las dos columnas de
     tarjetas -- un width:100% aquí lo obligaba a ocupar su propia línea
     entera y tiraba las columnas cada una a la suya. */
  flex: 1 1 auto;
  min-width: 0;
}

.riego-tabla {
  margin: 0 auto;
  border-collapse: separate;
  border-spacing: 4px;
  font-size: 0.9rem;
}

.riego-tabla th {
  font-weight: 600;
  color: var(--muted, #aab3c5);
  font-size: 0.8rem;
  padding: 2px 6px;
}

.riego-nombre {
  text-align: right;
  padding-right: 8px;
  font-weight: 600;
}

.riego-nombre-texto {
  white-space: nowrap;
}

/* Tablero al centro, tarjetas de planta repartidas en los dos márgenes que
   en escritorio suelen quedar vacíos. Por debajo del breakpoint (mismo que
   .deceerre-instructions) no hay margen que aprovechar: pasa a columna con
   el tablero primero y las tarjetas debajo en cuadrícula. */
.riego-layout {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
}

.riego-cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1 1 140px;
  max-width: 180px;
}

.riego-planta-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 8px;
  border-radius: 12px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: transform 0.15s ease, border-color 0.15s ease;
}

.riego-planta-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.riego-planta-card-icono {
  display: inline-flex;
  width: 64px;
  height: 64px;
}

.riego-planta-card-icono img {
  width: 100%;
  height: 100%;
}

.riego-planta-card-nombre {
  font-weight: 600;
  font-size: 0.85rem;
  text-align: center;
}

@media (max-width: 622px) {
  .riego-layout {
    flex-direction: column;
    align-items: stretch;
  }
  .riego-layout .riego-tabla-wrap {
    order: -1;
  }
  .riego-cards {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    max-width: none;
  }
  .riego-planta-card {
    flex: 1 1 30%;
  }
}

/* Overlay centrado con la cara de Deceerre y su bocadillo de cómic (ventana
   + con quién no puede coincidir). Se abre al tocar una tarjeta y se
   autocierra a los 5s; tocar el propio overlay (en cualquier punto) lo
   cierra antes, igual que .celebration-overlay en celebration.js. */
.riego-deceerre-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .55);
  padding: 16px;
}

.riego-deceerre-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  max-width: 280px;
}

/* Insignia circular tras la cabeza (recorte de assets/deceerre-cabeza.png,
   no la figura entera) para que resalte sobre el fondo oscurecido del
   overlay -- sin esto la cabeza sola, sin cuerpo, se perdía contra el
   backdrop semitransparente. */
.riego-deceerre-figura {
  width: 130px;
  height: 130px;
  border-radius: 50%;
  overflow: hidden;
  border: 4px solid #140a3c;
  background: radial-gradient(circle at 50% 40%, var(--accent), #8a2189 70%);
}

.riego-deceerre-figura img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
}

/* Caja de pista (fondo claro, borde grueso a juego con el resto del
   overlay) con una bombilla encima en vez del rabito de cómic de antes:
   la idea ya no es "Deceerre habla", es "aquí va una pista". La bombilla
   se monta como insignia circular que se solapa con el borde superior,
   mismo patrón que .riego-deceerre-figura. */
.riego-deceerre-bocadillo {
  position: relative;
  background: #fff9ec;
  border: 4px solid #140a3c;
  border-radius: 22px;
  padding: 22px 18px 14px;
  font-size: .9rem;
  line-height: 1.5;
  color: #140a3c;
  text-align: center;
}

.riego-deceerre-bombilla {
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #fff9ec;
  border: 4px solid #140a3c;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 4px #fff9ec, 0 0 12px 2px rgba(248, 200, 24, .7);
}

.riego-deceerre-bombilla svg {
  width: 20px;
  height: 20px;
}

.riego-deceerre-bocadillo p {
  margin: 4px 0;
}

.riego-cell {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid var(--card-b);
  background: rgba(255, 255, 255, 0.04);
  cursor: pointer;
  text-align: center;
  font-weight: 700;
  color: var(--muted, #aab3c5);
  transition: background 0.15s ease, transform 0.15s ease;
}

.riego-cell:hover {
  background: rgba(138, 33, 137, 0.2);
}

.riego-cell.is-on {
  background: linear-gradient(180deg, #4dabf7, #1c7ed6);
  border-color: #1c7ed6;
}

/* Marca voluntaria del jugador (×): recuerda que, según el texto de su
   ventana, esa planta no va en ese ciclo. Gratis, no se valida -- igual que
   las × del nonograma. */
.riego-cell.is-marked {
  background: repeating-linear-gradient(45deg,
    rgba(255,255,255,.03), rgba(255,255,255,.03) 4px,
    transparent 4px, transparent 8px);
  border-style: dashed;
  opacity: 0.7;
}

.riego-dosis {
  padding-left: 8px;
  font-variant-numeric: tabular-nums;
  color: var(--muted, #aab3c5);
}

.riego-dosis.is-done { color: #51cf66; font-weight: 700; }
.riego-dosis.is-over { color: #ff6b6b; font-weight: 700; }

.riego-total {
  text-align: center;
  font-size: 0.75rem;
  color: var(--muted, #aab3c5);
  font-variant-numeric: tabular-nums;
}

.riego-total.is-over { color: #ff6b6b; font-weight: 700; }

.riego-controls {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: 8px;
}

/* ============================================================================
   SALA DE ENTRENAMIENTO (la home, index.html)
   Todo cuelga de body.sala para no tocar el resto del sitio: el reto se monta
   dentro del mismo body y sus plantillas siguen usando .card, .btn y compañía.
   ========================================================================== */

body.sala {
    background: var(--bg);          /* plano: las trazas se leen sobre el navy */
    position: relative;
    min-height: 100vh;
}

.circuitry {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: .13;
}
.circuitry path,
.circuitry circle { fill: none; stroke: var(--gold); stroke-width: 1.5; }

body.sala .wrap { position: relative; z-index: 1; }

/* ---------- cabecera ---------- */
.sala-header {
    max-width: 1000px;
    margin: 0 auto;
    padding: 26px 24px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
}
.sala-header .brand {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: inherit;
    transition: opacity 0.15s ease;
}
.sala-header .brand:hover { opacity: 0.85; }
.sala-header .brand-logo {
    width: 68px;
    height: 68px;
    border-radius: 14px;
    border: 1px solid var(--line);
    background: var(--surface-2);
    object-fit: contain;
}
.brand-name { font-size: 27px; font-weight: 800; letter-spacing: -.5px; }
.brand-tag { font-size: 13.5px; color: var(--muted); margin-top: 1px; }

.sala-nav { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.sala-nav a {
    font-size: 13px;
    font-weight: 500;
    padding: 9px 15px;
    border-radius: 999px;
    border: 1px solid var(--line);
    color: var(--muted);
    text-decoration: none;
    transition: color .15s ease, border-color .15s ease;
}
.sala-nav a:hover { color: var(--fg); border-color: var(--blue); }
.sala-nav a.active { color: #fff; background: var(--brand); border-color: var(--brand-lift); }

body.sala main { max-width: 1000px; margin: 0 auto; padding: 32px 24px 80px; }

/* ---------- ficha del día ---------- */
.sala .hero {
    display: grid;
    grid-template-columns: 1.15fr .85fr;
    gap: 24px;
    align-items: stretch;
}
@media (max-width: 820px) { .sala .hero { grid-template-columns: 1fr; } }

.workout-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 18px;
    padding: 28px;
}

.eyebrow {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11.5px;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--gold);
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 12px;
}
.eyebrow::before {
    content: "";
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--brand-lift);
    box-shadow: 0 0 0 3px rgba(163, 43, 160, .28);
}

.workout-name {
    font-family: 'Unbounded', system-ui, sans-serif;
    font-size: clamp(30px, 4.4vw, 42px);
    line-height: 1.08;
    margin: 4px 0 14px;
    letter-spacing: -1px;
}
.workout-desc {
    color: var(--muted);
    font-size: 15px;
    line-height: 1.65;
    max-width: 46ch;
    margin: 0 0 24px;
}

.meta-row { display: flex; gap: 26px; margin-bottom: 26px; flex-wrap: wrap; }
.meta-item {
    font-size: 11.5px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 1px;
}
.meta-item b {
    display: block;
    margin-top: 6px;
    font-size: 17px;
    font-weight: 700;
    color: var(--fg);
    letter-spacing: 0;
    text-transform: none;
}
.meta-item b.mono { font-family: 'JetBrains Mono', monospace; }
.difficulty-dots { display: flex; gap: 5px; margin-top: 9px; }
.difficulty-dots span { width: 9px; height: 9px; border-radius: 50%; background: var(--line); }
.difficulty-dots span.on { background: var(--gold); }

.cta {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: var(--brand);
    color: #fff;                    /* blanco sobre morado: 7.9:1 */
    border: none;
    padding: 15px 28px;
    border-radius: 999px;
    font-family: 'Lexend', sans-serif;
    font-weight: 700;
    font-size: 15px;
    cursor: pointer;
    box-shadow: 0 5px 0 var(--brand-deep), 0 12px 20px rgba(0, 0, 0, .4);
    transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.cta:hover {
    background: var(--brand-lift);
    transform: translateY(2px);
    box-shadow: 0 3px 0 var(--brand-deep), 0 7px 12px rgba(0, 0, 0, .4);
}
.cta:active { transform: translateY(5px); box-shadow: 0 0 0 var(--brand-deep); }

/* ---------- Deceerre ---------- */
.coach {
    background:
        radial-gradient(circle at 50% 42%, rgba(138, 33, 137, .30), transparent 62%),
        var(--surface);
    border: 1px solid var(--line);
    border-radius: 18px;
    padding: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 14px;
    min-height: 300px;
    overflow: hidden;
}
.coach-figure { width: 100%; max-width: 230px; flex: 1; display: flex; align-items: center; }
.coach-figure img { width: 100%; height: auto; object-fit: contain; }
.coach-bubble {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 12px 14px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--muted);
    text-align: center;
    width: 100%;
}
.coach-bubble b { color: var(--gold); font-weight: 600; }

/* ---------- carné de asistencia ---------- */
section.streak { margin-top: 36px; }
.streak-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 14px;
    flex-wrap: wrap;
    gap: 8px;
}
.streak-head h2 {
    font-family: 'Lexend', sans-serif;
    font-size: 15px;
    font-weight: 600;
    margin: 0;
    color: var(--muted);
}
.streak-counts { display: flex; gap: 18px; font-size: 12px; color: var(--muted); }
.streak-counts b {
    font-family: 'JetBrains Mono', monospace;
    color: var(--gold);
    font-weight: 700;
    font-size: 14px;
}

.punchcard {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 18px;
    padding: 18px;
    display: flex;
    gap: 12px;
    justify-content: center;
}
.punch {
    flex: 1 1 0;
    max-width: 72px;
    aspect-ratio: 1;
    border-radius: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    font-family: 'JetBrains Mono', monospace;
    border: 2px dashed var(--line);
    color: var(--muted);
}
.punch .dow { font-size: 9.5px; opacity: .75; text-transform: uppercase; }
.punch .dom { font-size: 14px; font-weight: 700; }
.punch.done { background: var(--brand); border: 2px solid var(--brand-lift); color: #fff; }
.punch .punch-estrellas {
  font-size: 9px;
  line-height: 1;
  letter-spacing: .5px;
  color: var(--gold);
  margin-top: 2px;
}
/* Hoy gana al "hecho": es la casilla que el jugador busca primero. */
.punch.today { background: var(--gold); border: 2px solid var(--gold); color: var(--bg); }
.punch.today .dow { opacity: .85; }
/* Las estrellas son --gold igual que el fondo de "hoy": sin este cambio de
   color, un hoy ya completado con estrellas se vuelve invisible sobre su
   propio círculo. */
.punch.today .punch-estrellas { color: var(--bg); }

/* ---------- grupos musculares ---------- */
section.groups { margin-top: 52px; }
.groups-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 24px;
    flex-wrap: wrap;
    gap: 8px;
}
.groups-head h2 {
    font-family: 'Unbounded', system-ui, sans-serif;
    font-size: 25px;
    margin: 0;
    letter-spacing: -.8px;
}
.groups-head p { margin: 0; color: var(--muted); font-size: 13px; }

.group { margin-bottom: 28px; }
.group-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11.5px;
    letter-spacing: 1.6px;
    text-transform: uppercase;
    color: var(--gold);
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    gap: 11px;
}
.group-label::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.exercise-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
@media (max-width: 760px) { .exercise-row { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .exercise-row { grid-template-columns: 1fr; } }

.exercise {
    display: block;
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--blue);
    border-radius: 14px;
    padding: 16px 16px 15px;
    color: inherit;
    text-decoration: none;
    transition: transform .15s ease, border-color .15s ease, background .15s ease;
}
.exercise:hover { transform: translateY(-3px); background: var(--surface-2); border-left-color: var(--gold); }
.exercise-name { font-weight: 600; font-size: 14.5px; margin-bottom: 6px; }
.exercise-hint {
    font-size: 12.5px;
    color: var(--muted);
    line-height: 1.5;
    /* Los resúmenes del catálogo son más largos que los del mockup: se
       recortan aquí en vez de duplicar el texto en un campo aparte. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.sala-footer {
    max-width: 1000px;
    margin: 0 auto;
    padding: 22px 24px 44px;
    color: var(--muted);
    font-size: 12px;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    border-top: 1px solid var(--line);
}

.sala a:focus-visible,
.sala button:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
    .sala * { transition: none !important; }
}

/* ---------- archivo.html: mismo lenguaje visual que la sala, con las
   fichas de tipo (.exercise) reutilizadas para las fichas de reto ---------- */
.archive-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 28px; }
.archive-chip {
    font: inherit;
    cursor: pointer;
    padding: 9px 16px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: transparent;
    color: var(--muted);
    font-size: 13px;
    text-transform: capitalize;
    transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.archive-chip:hover { color: var(--fg); border-color: var(--blue); }
.archive-chip.is-active { color: #fff; background: var(--brand); border-color: var(--brand-lift); }

.archive-empty { color: var(--muted); }

/* Barra de "esto es un ejemplo", encima del tablero de prueba (?tipo=). */
.aviso-ejemplo {
    max-width: 1000px;
    margin: 0 auto 18px;
    padding: 14px 18px;
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--gold);
    border-radius: 14px;
}
.aviso-ejemplo p {
    margin: 0;
    color: var(--muted);
    font-size: 13px;
    line-height: 1.5;
}

/* ===== La Ronda Espacial (cinta_transportadora.js) ===== */
.cinta-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.cinta-stage {
  display: flex;
  justify-content: center;
  margin-bottom: 18px;
}

.cinta-circulo {
  position: relative;
  width: min(320px, 80vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, #241a4a, #140A3C 70%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
}

.cinta-hueco {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  color: var(--fg);
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  overflow: visible;
}

.cinta-hueco-retrato {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: contain;
  display: none;
}

.cinta-hueco.ocupado .cinta-hueco-retrato {
  display: block;
}

.cinta-hueco.ocupado .cinta-hueco-num {
  display: none;
}

.cinta-hueco.ocupado {
  border-color: var(--accent);
  background: rgba(209, 99, 204, .18);
}

.cinta-hueco:disabled {
  cursor: default;
  opacity: .7;
}

.cinta-hueco.volteando {
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .12);
  transform: translate(-50%, -50%) scale(1.12);
  transition: transform .15s ease, box-shadow .15s ease;
}

.cinta-hueco.vaciado {
  opacity: .35;
}

.cinta-brazo-eje {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
  background: var(--brand);
  z-index: 3;
}

.cinta-brazo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 6px;
  height: 38%;
  margin-top: 0;
  background: linear-gradient(to bottom, var(--brand), var(--accent));
  border-radius: 3px;
  transform-origin: top center;
  transform: translateX(-50%) rotate(0deg);
  transition: transform .3s cubic-bezier(.45, 0, .2, 1);
  pointer-events: none;
  z-index: 2;
}

.cinta-brazo-garra {
  position: absolute;
  left: 50%;
  bottom: -8px;
  width: 18px;
  height: 18px;
  margin-left: -9px;
  border-radius: 50%;
  border: 3px solid var(--accent);
  background: var(--bg);
}

.cinta-bandeja-wrap {
  margin-bottom: 14px;
}

.cinta-bandeja-label {
  color: var(--muted);
  font-size: .8rem;
  text-align: center;
  margin-bottom: 6px;
}

.cinta-bandeja {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
}

.cinta-caja {
  position: relative;
  width: 48px;
  height: 48px;
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  color: var(--fg);
  font-weight: 700;
  cursor: pointer;
  padding: 2px;
}

.cinta-caja-retrato {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.cinta-caja:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.cinta-caja.seleccionada {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(209, 99, 204, .35);
}

/* La fila de siluetas ES el objetivo, junto al tablero: un slot por
   posición del orden pedido, sombreado hasta que la nave lo entrega. */
.cinta-salida {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 12px;
  padding: 10px;
  border-radius: 12px;
  background: rgba(20, 10, 60, .25);
  border: 1px dashed var(--card-b);
  min-height: 44px;
}

.cinta-salida-slot {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .18);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform .2s ease;
}

.cinta-salida-slot img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.cinta-salida-silueta {
  filter: brightness(0) invert(1);
  opacity: .5;
}

.cinta-salida-real {
  filter: none;
  opacity: 1;
}

.cinta-salida-slot.correcto {
  transform: scale(1.1);
}

.cinta-salida-slot.incorrecto .cinta-salida-real {
  filter: grayscale(1) brightness(.6);
}

.cinta-ficha-volando {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, .4));
}

/* ===== Fábrica de Bloques ===== */
.fabrica-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.fabrica-tablero {
  display: grid;
  gap: 2px;
  max-width: min(420px, 90vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
  background: var(--card-b);
  border: 2px solid var(--card-b);
  border-radius: 6px;
  overflow: hidden;
}

.fabrica-celda {
  position: relative;
  /* El color de region lo fija cada celda por JS (style.backgroundColor);
     esta capa oscura semitransparente encima es lo que de verdad se ve --
     así el color queda como una tinta suave sobre el fondo oscuro del
     sitio en vez de un bloque saturado que tape el dígito. */
  background-image: linear-gradient(rgba(15, 18, 28, .74), rgba(15, 18, 28, .74));
  background-blend-mode: normal;
  border: 1px solid rgba(255, 255, 255, .1);
  color: var(--fg);
  font-weight: 700;
  font-size: 1.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  aspect-ratio: 1;
}

.fabrica-celda.borde-izq { border-left: 3px solid var(--fg); }
.fabrica-celda.borde-der { border-right: 3px solid var(--fg); }
.fabrica-celda.borde-arriba { border-top: 3px solid var(--fg); }
.fabrica-celda.borde-abajo { border-bottom: 3px solid var(--fg); }

.fabrica-celda-pista {
  position: absolute;
  top: 3px;
  left: 4px;
  font-size: .8rem;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .85), 0 0 4px rgba(0, 0, 0, .6);
  letter-spacing: .01em;
}

.fabrica-celda-valor {
  pointer-events: none;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}

.fabrica-celda.fija {
  color: #fff;
  cursor: default;
}

.fabrica-celda.fija::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(15, 18, 28, .35);
}

.fabrica-celda.seleccionada {
  box-shadow: inset 0 0 0 3px var(--brand);
}

.fabrica-celda:disabled {
  cursor: default;
  opacity: .85;
}

.fabrica-numpad {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 14px;
}

.fabrica-num {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  color: var(--fg);
  font-weight: 700;
  cursor: pointer;
}

.fabrica-num:hover {
  border-color: var(--accent);
}

.fabrica-num.seleccionado {
  border-color: var(--brand);
  background: var(--brand);
  color: #fff;
  box-shadow: 0 0 0 2px rgba(209, 99, 204, .35);
}

.fabrica-num-borrar {
  width: auto;
  padding: 0 14px;
  font-size: .8rem;
}

.fabrica-esquina,
.fabrica-cab {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: .7rem;
  font-weight: 700;
}

.fabrica-sospechosos {
  max-width: min(420px, 90vw);
  margin: 0 auto 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fabrica-sospechosos-titulo {
  text-align: center;
  font-weight: 700;
  margin: 0 0 4px;
}

.fabrica-sospechoso {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  color: var(--fg);
  cursor: pointer;
}

.fabrica-sospechoso:hover {
  border-color: var(--accent);
}

.fabrica-sospechoso-nombre {
  font-weight: 700;
}

.fabrica-sospechoso-coartada {
  font-size: .85rem;
  color: var(--muted);
}

.fabrica-sospechoso.culpable {
  border-color: var(--brand);
  box-shadow: 0 0 0 2px rgba(209, 99, 204, .35);
}

.fabrica-sospechoso.descartado {
  opacity: .55;
}

.fabrica-sospechoso:disabled {
  cursor: default;
}

/* ===== Androides en la Fábrica ===== */
.androides-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.androides-tablero-wrap {
  position: relative;
  max-width: min(420px, 90vw);
  margin: 0 auto 18px;
}

.androides-tablero {
  display: grid;
  gap: 2px;
  aspect-ratio: 1;
  background: var(--card-b);
  border: 2px solid var(--card-b);
  border-radius: 6px;
  overflow: hidden;
}

.androides-celda {
  position: relative;
  background-color: var(--surface-2, #212b3b);
  background-image: linear-gradient(rgba(15, 18, 28, .55), rgba(15, 18, 28, .55));
  border: 1px solid rgba(255, 255, 255, .1);
  color: #fff;
  font-weight: 700;
  font-size: 1.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  aspect-ratio: 1;
}

.androides-celda.con-clase {
  background-image: linear-gradient(rgba(15, 18, 28, .45), rgba(15, 18, 28, .45));
}

.androides-celda-valor {
  pointer-events: none;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .7);
}

.androides-celda.modelo-fijo .androides-celda-valor {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.androides-celda.clase-fija::after {
  content: '';
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  opacity: .8;
}

.androides-celda:disabled {
  cursor: default;
  opacity: .85;
}

.androides-marca {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .8rem;
  font-weight: 800;
  color: #fff;
  background: rgba(15, 18, 28, .85);
  border: 1px solid rgba(255, 255, 255, .3);
  pointer-events: none;
  z-index: 2;
}

.androides-marca.misma { color: #3DBE7A; }
.androides-marca.distinta { color: #E85B4A; }

.androides-panel {
  margin-bottom: 10px;
}

.androides-panel-titulo {
  text-align: center;
  color: var(--muted);
  font-size: .8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-bottom: 6px;
}

.androides-numpad {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 4px;
}

.androides-num {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  color: var(--fg);
  font-weight: 700;
  cursor: pointer;
}

.androides-num:hover {
  border-color: var(--accent);
}

.androides-num.seleccionado {
  border-color: var(--brand);
  background: var(--brand);
  color: #fff;
  box-shadow: 0 0 0 2px rgba(209, 99, 204, .35);
}

.androides-num-borrar {
  width: auto;
  padding: 0 14px;
  font-size: .8rem;
}

.androides-swatch {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 2px solid rgba(255, 255, 255, .15);
  cursor: pointer;
}

.androides-swatch:hover {
  border-color: var(--accent);
}

.androides-swatch.seleccionado {
  border-color: #fff;
  box-shadow: 0 0 0 2px var(--brand);
}

/* ===== Código Secreto (codigo_secreto.js) ===== */
.codigo-secreto-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.codigo-secreto-slots,
.codigo-secreto-paleta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 0 0 14px;
}

.codigo-secreto-slot,
.codigo-secreto-swatch {
  width: 48px;
  height: 48px;
  font-size: 1.6rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  cursor: pointer;
  transition: transform .15s ease, border-color .15s ease;
}

.codigo-secreto-swatch:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.codigo-secreto-slot.seleccionada {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(209, 99, 204, .35);
}

.codigo-secreto-slot.lleno {
  background: rgba(255, 255, 255, .04);
}

.codigo-secreto-slot:disabled,
.codigo-secreto-swatch:disabled {
  cursor: default;
  opacity: .6;
}

.codigo-secreto-historial {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 10px;
  max-height: 260px;
  overflow-y: auto;
}

.codigo-secreto-fila-historial {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line);
  flex-wrap: wrap;
}

.codigo-secreto-pegs {
  display: flex;
  gap: 4px;
  font-size: 1.2rem;
}

.codigo-secreto-marca {
  font-size: .85rem;
  color: var(--muted);
  white-space: nowrap;
}

/* ===== Compartir resultado (celebración) ===== */
.celebration-compartir {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
}

.compartir-preview {
  margin: 0;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1px solid var(--card-b);
  background: rgba(0, 0, 0, .25);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .82rem;
  line-height: 1.55;
  text-align: center;
  white-space: pre-wrap;
  word-break: break-word;
  max-width: 100%;
}

.celebration-compartir .btn {
  min-width: 190px;
}

/* ===== Planos del Invernadero ===== */
.invernadero-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

/* ===== Desenreda la Red ===== */
.red-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.invernadero-tablero {
  display: grid;
  gap: 2px;
  max-width: min(460px, 90vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
  background: var(--card-b);
  border: 2px solid var(--card-b);
  border-radius: 6px;
  overflow: hidden;
}

.invernadero-celda {
  position: relative;
  background: var(--surface-2, #212b3b);
  border: none;
  color: #fff;
  font-weight: 700;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  aspect-ratio: 1;
}

.invernadero-celda.con-modulo {
  color: #140A3C;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
}

.invernadero-celda.anclada {
  box-shadow: inset 0 0 0 3px var(--brand);
}

.invernadero-celda-num {
  pointer-events: none;
}

.invernadero-celda:disabled {
  cursor: default;
}

/* ===== Radar de Asteroides ===== */
.radar-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.radar-tablero {
  display: grid;
  gap: 2px;
  max-width: min(460px, 90vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
  background: var(--card-b);
  border: 2px solid var(--card-b);
  border-radius: 6px;
  overflow: hidden;
}

.radar-celda {
  position: relative;
  background: var(--surface-2, #212b3b);
  border: none;
  color: var(--fg);
  font-weight: 700;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  aspect-ratio: 1;
}

.radar-celda.con-pista {
  background: rgba(255, 255, 255, .06);
  color: var(--muted);
  cursor: default;
}

.radar-celda.marcada {
  background: rgba(232, 91, 74, .3);
}

.radar-marca {
  width: 55%;
  height: 55%;
  border-radius: 50%;
  background: transparent;
  pointer-events: none;
}

.radar-celda.marcada .radar-marca {
  background: #E85B4A;
}

.radar-celda:disabled {
  cursor: default;
}

/* ===== Ruta del Dron ===== */
.dron-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.dron-tablero {
  display: grid;
  gap: 2px;
  max-width: min(460px, 90vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
  background: var(--card-b);
  border: 2px solid var(--card-b);
  border-radius: 6px;
  overflow: hidden;
}

.dron-celda {
  position: relative;
  background: var(--surface-2, #212b3b);
  border: none;
  color: var(--fg);
  font-weight: 700;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  aspect-ratio: 1;
}

.dron-flecha {
  font-size: 1.2rem;
  line-height: 1;
}

.dron-distancia {
  font-size: .7rem;
  color: var(--muted);
}

.dron-celda.meta {
  background: rgba(255, 255, 255, .08);
  font-size: 1.3rem;
  cursor: default;
}

.dron-celda.en-ruta {
  background: rgba(61, 139, 224, .28);
}

.dron-celda.seleccionada {
  box-shadow: inset 0 0 0 3px var(--brand);
}

.dron-celda:disabled {
  cursor: default;
}

/* ===== El Cubo Transportista ===== */
.cubo-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.cubo-tablero {
  display: grid;
  gap: 2px;
  max-width: min(400px, 80vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
  background: var(--card-b);
  border: 2px solid var(--card-b);
  border-radius: 6px;
  overflow: hidden;
}

.cubo-celda {
  position: relative;
  background: var(--surface-2, #212b3b);
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cubo-celda.inicio::after {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--muted);
}

.cubo-celda.meta {
  background: rgba(61, 190, 122, .18);
}

.cubo-meta-num {
  font-weight: 800;
  font-size: 1.3rem;
  color: #3DBE7A;
}

.cubo-celda.con-cubo {
  box-shadow: inset 0 0 0 3px var(--brand);
}

.cubo-figura {
  display: grid;
  grid-template-columns: repeat(3, 44px);
  grid-template-rows: repeat(3, 44px);
  grid-template-areas:
    ".    norte  .   "
    "oeste arriba este"
    ".    sur    .   ";
  gap: 4px;
  justify-content: center;
  margin: 0 auto 18px;
}

.cubo-cara {
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  border-radius: 6px;
  background: var(--surface-2, #212b3b);
  border: 1px solid var(--card-b);
  color: var(--muted);
}

.cubo-cara-arriba {
  grid-area: arriba;
  font-size: 1.4rem;
  font-weight: 800;
  color: #fff;
  background: var(--brand);
  border-color: var(--brand);
}

.cubo-cara-norte { grid-area: norte; }
.cubo-cara-sur { grid-area: sur; }
.cubo-cara-este { grid-area: este; }
.cubo-cara-oeste { grid-area: oeste; }

.cubo-controles {
  display: grid;
  grid-template-columns: repeat(3, 52px);
  grid-template-rows: repeat(2, 52px);
  grid-template-areas:
    ".  n  ."
    "o  s  e";
  gap: 6px;
  justify-content: center;
  margin-bottom: 14px;
}

.cubo-flecha {
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  color: var(--fg);
  font-size: 1.3rem;
  cursor: pointer;
}

.cubo-flecha:hover {
  border-color: var(--accent);
}

.cubo-flecha:disabled {
  opacity: .5;
  cursor: default;
}

.cubo-flecha-n { grid-area: n; }
.cubo-flecha-o { grid-area: o; }
.cubo-flecha-e { grid-area: e; }
.cubo-flecha-s { grid-area: s; }

/* ===== Desenreda la Red ===== */
.red-lienzo {
  position: relative;
  width: min(460px, 90vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
  background: var(--surface-2, #212b3b);
  border: 2px solid var(--card-b);
  border-radius: 10px;
  overflow: hidden;
  touch-action: none;
}

.red-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.red-cable {
  stroke: var(--muted);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}

.red-cable.cruzado {
  stroke: #E85B4A;
  stroke-width: 1.8;
}

.red-nodo {
  position: absolute;
  width: 24px;
  height: 24px;
  margin: -12px 0 0 -12px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .5);
  cursor: grab;
  touch-action: none;
  z-index: 2;
}

.red-nodo.arrastrando {
  cursor: grabbing;
  transform: scale(1.15);
  z-index: 3;
}

.red-nodo:disabled {
  cursor: default;
}

/* ===== Señal Perdida ===== */
.senal-pistas {
  background: var(--surface-2, #212b3b);
  border: 1px solid var(--card-b);
  border-radius: 10px;
  padding: 10px 16px;
  margin: 0 auto 14px;
  max-width: min(460px, 90vw);
}

.senal-pistas h4 {
  margin: 4px 0 6px;
  font-size: .9rem;
  color: var(--muted);
}

.senal-pistas ul {
  margin: 0;
  padding-left: 18px;
  font-size: .85rem;
  line-height: 1.5;
}

.senal-mensaje {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  margin: 0 auto 16px;
}

.senal-mensaje-letra {
  width: 32px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 3px solid var(--brand);
  font-weight: 800;
  font-size: 1.2rem;
  color: var(--fg);
}

.senal-tablero {
  display: grid;
  gap: 2px;
  max-width: min(420px, 90vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
  background: var(--card-b);
  border: 2px solid var(--card-b);
  border-radius: 6px;
  overflow: hidden;
}

.senal-celda {
  position: relative;
  background: var(--surface-2, #212b3b);
  border: none;
  color: var(--fg);
  font-weight: 700;
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  aspect-ratio: 1;
}

.senal-celda.ocupada {
  background: rgba(209, 99, 204, .22);
}

.senal-celda:disabled {
  cursor: default;
}

.senal-bandeja {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 14px;
}

.senal-letra {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid var(--card-b);
  background: var(--surface-2, #212b3b);
  color: var(--fg);
  font-weight: 700;
  cursor: pointer;
}

.senal-letra:hover {
  border-color: var(--accent);
}

.senal-letra.seleccionada {
  border-color: var(--brand);
  background: var(--brand);
  color: #fff;
  box-shadow: 0 0 0 2px rgba(209, 99, 204, .35);
}

.senal-letra.colocada {
  opacity: .4;
  cursor: default;
}

/* ===== El Trazo Perimetral ===== */
.trazo-info {
  color: var(--muted);
  font-size: .85rem;
  margin: 4px 0 14px;
  text-align: center;
}

.trazo-tablero {
  position: relative;
  width: min(420px, 88vw);
  aspect-ratio: 1;
  margin: 0 auto 18px;
}

.trazo-punto {
  position: absolute;
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--muted);
  pointer-events: none;
}

.trazo-numero {
  position: absolute;
  transform: translate(-50%, -50%);
  font-weight: 800;
  font-size: .95rem;
  color: var(--fg);
  pointer-events: none;
  z-index: 1;
}

.trazo-arista {
  position: absolute;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  z-index: 2;
}

.trazo-arista::after {
  content: '';
  position: absolute;
  background: rgba(255, 255, 255, .12);
  border-radius: 2px;
}

.trazo-arista.activa::after {
  background: var(--brand);
}

.trazo-arista-h {
  height: 18px;
  margin-top: -9px;
}

.trazo-arista-h::after {
  left: 2px;
  right: 2px;
  top: 7px;
  height: 4px;
}

.trazo-arista-v {
  width: 18px;
  margin-left: -9px;
}

.trazo-arista-v::after {
  top: 2px;
  bottom: 2px;
  left: 7px;
  width: 4px;
}

.trazo-arista:disabled {
  cursor: default;
}
