/* ============================================================================
   ILUSTRACIONES — los apoyos y las construcciones de verdad
   (public/app/js/ilustraciones.js, clases .vi-*)
   ----------------------------------------------------------------------------
   Solo tokens de tokens.css. Los tonos de las caras son mezclas de --ink con
   --paper (color-mix); sin color-mix, todas las caras quedan en --paper y el
   dibujo se lee por su contorno. Papeles:
     --ink            contorno de los sólidos, varillas, barandal, símbolos
     --ink2           achurados, líneas ocultas, rótulos y sus guías
     --ink3, --sep2   líneas de proyección y ejes de las burbujas
     --defl           lo impedido: flechas tachadas y el fantasma que empuja
     --accent         lo libre y lo resaltado (--accent-text en los rótulos)
     --beam, --beam-edge   la viga del curso (el símbolo)
   Claro: lo de arriba es lo más claro (el papel) y lo de la derecha, lo más
   oscuro. Oscuro: la mezcla se invierte para que la luz siga viniendo de
   arriba (un dibujo positivo, como el medallón de Salviati).
   Textos sobre --paper: ink, ink2, defl y accent-text (los pares que ya mide
   tools/contraste.js; test-ilustraciones.js los vuelve a medir).
   Animación: solo transform y opacity, con transform-box: view-box (el origen
   lo pone ilustraciones.js en px del dibujo). Con prefers-reduced-motion y al
   imprimir no hay animación: queda el estado final y los fantasmas quietos
   (.vi-rm) de lo que se mueve libre.
   ========================================================================== */

/* ------------------------------------------------------------------ BASE */
.vi-svg {
  /* llena el ancho que le den; si el contenedor tiene alto (el escenario de la
     lección), no lo rebasa: el viewBox lo encoge sin deformarlo */
  display: block; width: 100%; max-width: 100%; height: auto; max-height: 100%; overflow: visible;
  color: var(--ink); font-family: var(--ui);
  /* respaldo sin color-mix: caras en papel */
  --vi-c0: var(--paper); --vi-c1: var(--paper); --vi-c2: var(--paper);
  --vi-a0: var(--paper); --vi-a1: var(--paper); --vi-a2: var(--paper);
  --vi-n0: var(--paper); --vi-n1: var(--paper); --vi-n2: var(--paper);
  --vi-m0: var(--paper); --vi-m1: var(--paper); --vi-m2: var(--paper);
  --vi-t0: var(--paper); --vi-t1: var(--paper); --vi-t2: var(--paper);
  --vi-w: var(--paper); --vi-o: var(--paper); --vi-shim: var(--ink2);
}
@supports (color: color-mix(in srgb, currentColor 50%, transparent)) {
  .vi-svg {
    --vi-c0: var(--paper);
    --vi-c1: color-mix(in srgb, var(--ink) 6%, var(--paper));
    --vi-c2: color-mix(in srgb, var(--ink) 13%, var(--paper));
    --vi-a0: color-mix(in srgb, var(--ink) 13%, var(--paper));
    --vi-a1: color-mix(in srgb, var(--ink) 24%, var(--paper));
    --vi-a2: color-mix(in srgb, var(--ink) 36%, var(--paper));
    --vi-n0: color-mix(in srgb, var(--ink) 50%, var(--paper));
    --vi-n1: color-mix(in srgb, var(--ink) 60%, var(--paper));
    --vi-n2: color-mix(in srgb, var(--ink) 70%, var(--paper));
    --vi-m0: color-mix(in srgb, var(--ink) 3%, var(--paper));
    --vi-m1: color-mix(in srgb, var(--ink) 8%, var(--paper));
    --vi-m2: color-mix(in srgb, var(--ink) 15%, var(--paper));
    --vi-t0: color-mix(in srgb, var(--ink) 4%, var(--paper));
    --vi-t1: color-mix(in srgb, var(--ink) 9%, var(--paper));
    --vi-t2: color-mix(in srgb, var(--ink) 14%, var(--paper));
    --vi-w: color-mix(in srgb, var(--accent) 12%, var(--paper));
    --vi-o: color-mix(in srgb, var(--ink) 30%, var(--paper));
    --vi-shim: var(--paper);
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .vi-svg {
      --vi-c0: color-mix(in srgb, var(--ink) 21%, var(--paper));
      --vi-c1: color-mix(in srgb, var(--ink) 13%, var(--paper));
      --vi-c2: color-mix(in srgb, var(--ink) 7%, var(--paper));
      --vi-a0: color-mix(in srgb, var(--ink) 40%, var(--paper));
      --vi-a1: color-mix(in srgb, var(--ink) 29%, var(--paper));
      --vi-a2: color-mix(in srgb, var(--ink) 19%, var(--paper));
      --vi-n0: color-mix(in srgb, var(--ink) 11%, var(--paper));
      --vi-n1: color-mix(in srgb, var(--ink) 7%, var(--paper));
      --vi-n2: color-mix(in srgb, var(--ink) 4%, var(--paper));
      --vi-m0: color-mix(in srgb, var(--ink) 18%, var(--paper));
      --vi-m1: color-mix(in srgb, var(--ink) 11%, var(--paper));
      --vi-m2: color-mix(in srgb, var(--ink) 6%, var(--paper));
      --vi-t0: color-mix(in srgb, var(--ink) 15%, var(--paper));
      --vi-t1: color-mix(in srgb, var(--ink) 9%, var(--paper));
      --vi-t2: color-mix(in srgb, var(--ink) 5%, var(--paper));
      --vi-w: color-mix(in srgb, var(--accent) 17%, var(--paper));
      --vi-o: color-mix(in srgb, var(--ink) 2%, var(--paper));
      --vi-shim: var(--ink2);
    }
  }
  :root[data-theme="dark"] .vi-svg {
    --vi-c0: color-mix(in srgb, var(--ink) 21%, var(--paper));
    --vi-c1: color-mix(in srgb, var(--ink) 13%, var(--paper));
    --vi-c2: color-mix(in srgb, var(--ink) 7%, var(--paper));
    --vi-a0: color-mix(in srgb, var(--ink) 40%, var(--paper));
    --vi-a1: color-mix(in srgb, var(--ink) 29%, var(--paper));
    --vi-a2: color-mix(in srgb, var(--ink) 19%, var(--paper));
    --vi-n0: color-mix(in srgb, var(--ink) 11%, var(--paper));
    --vi-n1: color-mix(in srgb, var(--ink) 7%, var(--paper));
    --vi-n2: color-mix(in srgb, var(--ink) 4%, var(--paper));
    --vi-m0: color-mix(in srgb, var(--ink) 18%, var(--paper));
    --vi-m1: color-mix(in srgb, var(--ink) 11%, var(--paper));
    --vi-m2: color-mix(in srgb, var(--ink) 6%, var(--paper));
    --vi-t0: color-mix(in srgb, var(--ink) 15%, var(--paper));
    --vi-t1: color-mix(in srgb, var(--ink) 9%, var(--paper));
    --vi-t2: color-mix(in srgb, var(--ink) 5%, var(--paper));
    --vi-w: color-mix(in srgb, var(--accent) 17%, var(--paper));
    --vi-o: color-mix(in srgb, var(--ink) 2%, var(--paper));
    --vi-shim: var(--ink2);
  }
}

/* ----------------------------------------------------------------- CARAS */
.vi-c0 { fill: var(--vi-c0); } .vi-c1 { fill: var(--vi-c1); } .vi-c2 { fill: var(--vi-c2); }
.vi-a0 { fill: var(--vi-a0); } .vi-a1 { fill: var(--vi-a1); } .vi-a2 { fill: var(--vi-a2); }
.vi-n0 { fill: var(--vi-n0); } .vi-n1 { fill: var(--vi-n1); } .vi-n2 { fill: var(--vi-n2); }
.vi-m0 { fill: var(--vi-m0); } .vi-m1 { fill: var(--vi-m1); } .vi-m2 { fill: var(--vi-m2); }
.vi-t0 { fill: var(--vi-t0); } .vi-t1 { fill: var(--vi-t1); } .vi-t2 { fill: var(--vi-t2); }
.vi-w0, .vi-w1, .vi-w2 { fill: var(--vi-w); stroke: var(--ink2); stroke-width: .7; }
.vi-o0, .vi-o1, .vi-o2 { fill: var(--vi-o); stroke: var(--ink); stroke-width: .9; stroke-opacity: .85; }   /* un vano: lo oscuro de adentro */
.vi-c0, .vi-c1, .vi-c2, .vi-a0, .vi-a1, .vi-a2, .vi-n0, .vi-n1, .vi-n2,
.vi-m0, .vi-m1, .vi-m2, .vi-t0, .vi-t1, .vi-t2 { stroke: var(--ink); stroke-width: .9; stroke-opacity: .85; }
/* bandas de un costado curvo: sin contorno (la silueta va aparte, .vi-ol); el
   trazo del mismo tono tapa la costura entre bandas */
.vi-sm { stroke-width: .6; stroke-opacity: 1; }
.vi-sm.vi-a0 { stroke: var(--vi-a0); } .vi-sm.vi-a1 { stroke: var(--vi-a1); } .vi-sm.vi-a2 { stroke: var(--vi-a2); }
.vi-sm.vi-c0 { stroke: var(--vi-c0); } .vi-sm.vi-c1 { stroke: var(--vi-c1); } .vi-sm.vi-c2 { stroke: var(--vi-c2); }
.vi-ol { fill: none; stroke: var(--ink); stroke-width: .9; stroke-opacity: .85; }
/* cara cortada (sección): papel y su achurado */
.vi-cut { fill: var(--paper); stroke: var(--ink); stroke-width: 1.2; }

/* ------------------------------------------------------------- ACHURADOS */
.vi-hd { stroke: var(--ink2); stroke-width: 1.35; }            /* concreto: puntos */
.vi-ht { stroke: var(--ink2); stroke-width: .7; }              /* concreto: agregado */
.vi-ha, .vi-hm { stroke: var(--ink2); stroke-width: .7; }      /* acero y mampostería */
.vi-he { stroke: var(--ink2); stroke-width: .75; }             /* terreno */
.vi-brick { stroke: var(--ink2); stroke-width: .55; stroke-opacity: .75; }

/* ---------------------------------------------------------------- LÍNEAS */
.vi-bar { stroke: var(--ink); stroke-width: 2.2; }             /* varilla en el plano del corte */
.vi-bar2 { stroke: var(--ink); stroke-width: 1.5; }
.vi-bar3 { stroke: var(--ink2); stroke-width: 1; }
.vi-barh { stroke: var(--ink2); stroke-width: 1.2; stroke-dasharray: 5 3; }    /* varilla oculta */
.vi-esth { stroke: var(--ink2); stroke-width: .8; stroke-dasharray: 3 2.5; }   /* estribo oculto */
.vi-est { stroke: var(--ink); stroke-width: 1; }
.vi-bard { fill: var(--ink); stroke: none; }
.vi-hid { stroke: var(--ink2); stroke-width: .9; stroke-dasharray: 4 3; }      /* arista oculta */
.vi-brk { stroke: var(--ink); stroke-width: .9; }
.vi-spk { stroke: var(--ink); stroke-width: 1.3; }             /* la marca que deja ver rodar al rodillo */
.vi-shim { stroke: var(--vi-shim); stroke-width: 1.2; }
.vi-glass { fill: var(--vi-w); stroke: var(--ink2); stroke-width: .8; }
.vi-wave { stroke: var(--ink2); stroke-width: .9; }
.vi-rail { stroke: var(--ink); stroke-width: 1.4; }
.vi-rail2 { stroke: var(--ink2); stroke-width: .9; }

/* ------------------------------------------------------ RÓTULOS Y TÍTULO */
.vi-ld { stroke: var(--ink2); stroke-width: .8; }
.vi-ldd { fill: var(--ink2); stroke: none; }
.vi-t, .vi-gzt { paint-order: stroke; stroke: var(--paper); stroke-width: 3px; stroke-linejoin: round; }
.vi-t { font: 600 10.5px/1 var(--ui); letter-spacing: .05em; fill: var(--ink2); }
.is-sm .vi-t { font-size: 9px; }
.vi-tt { font: 700 13px/1 var(--ui); letter-spacing: .05em; fill: var(--ink); stroke: none; }
.is-sm .vi-tt { font-size: 11.5px; }
.vi-ts { font: 600 9.5px/1 var(--ui); letter-spacing: .05em; fill: var(--ink2); stroke: none; }
.is-sm .vi-ts { font-size: 8.5px; }
.vi-tl { stroke: var(--ink); stroke-width: 1.6; }
.vi-bub { fill: var(--paper); stroke: var(--ink2); stroke-width: 1; }
.vi-bubt { font: italic 14px/1 var(--math); fill: var(--ink); stroke: none; }
.vi-lgt { font: 500 11px/1 var(--ui); fill: var(--ink2); stroke: none; }
.is-sm .vi-lgt { font-size: 10px; }

/* ----------------------------------------- LAS FLECHAS DEL PLANO (ejes) */
.vi-gzh { stroke: var(--paper); stroke-width: 5.5; stroke-opacity: .9; }
.vi-gzl { stroke-width: 2; }
.vi-gzk { stroke: none; }
.vi-gz.is-libre .vi-gzl, .vi-lg.is-libre .vi-gzl { stroke: var(--accent); }
.vi-gz.is-libre .vi-gzk, .vi-lg.is-libre .vi-gzk { fill: var(--accent); }
.vi-gz.is-impedido .vi-gzl, .vi-lg.is-impedido .vi-gzl { stroke: var(--defl); }
.vi-gz.is-impedido .vi-gzk, .vi-lg.is-impedido .vi-gzk { fill: var(--defl); }
.vi-gzx { stroke: var(--defl); stroke-width: 2.4; }
.vi-gzt { font: 600 12px/1 var(--ui); }
.vi-gzt.vi-it { font: italic 15px/1 var(--math); }
.is-sm .vi-gzt { font-size: 10.5px; }
.is-sm .vi-gzt.vi-it { font-size: 13px; }
.vi-gz.is-libre .vi-gzt { fill: var(--accent-text); }
.vi-gz.is-impedido .vi-gzt { fill: var(--defl); }
.vi-gzp { fill: var(--paper); stroke: var(--ink); stroke-width: 1.3; }

/* ------------------------------------------------ EL SÍMBOLO DEL CURSO */
.vi-sy { stroke: var(--ink); stroke-width: 1.5; }
.vi-syw { stroke-width: 2.4; }
.vi-syf { fill: var(--paper); }
.vi-syh { stroke: var(--ink2); stroke-width: 1; }
.vi-syb { fill: var(--beam); stroke: var(--beam-edge); stroke-width: 1; }
.vi-ring { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-dasharray: 5 3.5; }
.vi-ringl { stroke: var(--accent); stroke-width: 1.2; }

/* ------------------------------------------------ EL MODELO (escenas) */
.vi-prj { stroke: var(--ink3); stroke-width: .9; stroke-dasharray: 3 3; }
.vi-prj.is-resalta { stroke: var(--accent); stroke-width: 1.2; }
.vi-axl { stroke: var(--sep2); stroke-width: 1; stroke-dasharray: 2 3; }
.vi-msup.is-resalta .vi-sy { stroke: var(--accent); stroke-width: 2.2; }
.vi-msup.is-resalta .vi-syh { stroke: var(--accent); }

/* ------------------------------------------------------------- RESALTAR */
.is-resalta :is(.vi-c0, .vi-c1, .vi-c2, .vi-a0, .vi-a1, .vi-a2, .vi-n0, .vi-n1, .vi-n2, .vi-m0, .vi-m1, .vi-m2, .vi-ol, .vi-cut) {
  stroke: var(--accent); stroke-width: 1.4; stroke-opacity: 1;
}
.vi-hlr { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.6; stroke-dasharray: 5 3.5; }

/* ----------------------------------------------------- FANTASMAS (anim) */
.vi-gh { fill: none; stroke-width: 1.5; stroke-dasharray: 5 4; }
.vi-an-g .vi-gh { stroke: var(--defl); }        /* lo que intenta y no puede */
.vi-rm .vi-gh { stroke: var(--accent); }        /* lo libre, quieto (sin animación) */
.vi-an-g { opacity: 0; }
.vi-rm { display: none; }

/* ============================================================ ANIMACIÓN
   'intenta': ciclo de 6 s con tres tiempos (x, y, giro). --vi-k (0, 1, 2)
   recorre cada grupo a su tiempo; --vi-a y --vi-b son sus dos posiciones
   (un sentido y el otro); --vi-n, las vueltas (2); --vi-d0, lo que tarda
   antes (el acercamiento).                                                 */
.vi-svg .vi-an, .vi-svg .vi-zsym, .vi-svg .vi-ziso { transform-box: view-box; }
.vi-gz-x { --vi-k: 0; } .vi-gz-y { --vi-k: 1; } .vi-gz-g { --vi-k: 2; }
.vi-anim .vi-an-g { animation: vi-ghost 6s ease-in-out calc(var(--vi-d0, 0s) + .5s + var(--vi-k, 0) * 2s) var(--vi-n, 2) both; }
.vi-anim .vi-an-m { animation: vi-move 6s ease-in-out calc(var(--vi-d0, 0s) + .5s + var(--vi-k, 0) * 2s) var(--vi-n, 2) both; }
.vi-anim .vi-gz-x { animation: vi-fx 6s linear calc(var(--vi-d0, 0s) + .5s) var(--vi-n, 2) both; }
.vi-anim .vi-gz-y { animation: vi-fy 6s linear calc(var(--vi-d0, 0s) + .5s) var(--vi-n, 2) both; }
.vi-anim .vi-gz-g { animation: vi-fg 6s linear calc(var(--vi-d0, 0s) + .5s) var(--vi-n, 2) both; }
.vi-anim .vi-gz .vi-gzx { animation: vi-hit 6s ease-out calc(var(--vi-d0, 0s) + .5s + var(--vi-k, 0) * 2s) var(--vi-n, 2) both; }
@keyframes vi-ghost {
  0%, 4% { opacity: 0; transform: none; }
  7% { opacity: 1; transform: none; }
  12% { opacity: 1; transform: var(--vi-a); }
  15.5% { opacity: 1; transform: none; }
  20.5% { opacity: 1; transform: var(--vi-b); }
  24% { opacity: 1; transform: none; }
  29%, 100% { opacity: 0; transform: none; }
}
@keyframes vi-move {
  0%, 4% { transform: none; }
  12.5%, 15.5% { transform: var(--vi-a); }
  24% { transform: var(--vi-b); }
  30%, 100% { transform: none; }
}
/* la tacha late cuando el fantasma choca (sin escalar: el halo no se descompone) */
@keyframes vi-hit {
  0%, 11.5% { stroke-width: 2.4; }
  13% { stroke-width: 4.4; }
  15.5%, 20% { stroke-width: 2.4; }
  21.5% { stroke-width: 4.4; }
  24%, 100% { stroke-width: 2.4; }
}
@keyframes vi-fx { 0%, 30% { opacity: 1; } 33%, 97% { opacity: .25; } 100% { opacity: 1; } }
@keyframes vi-fy { 0%, 30% { opacity: .25; } 33%, 63% { opacity: 1; } 66%, 97% { opacity: .25; } 100% { opacity: 1; } }
@keyframes vi-fg { 0%, 63% { opacity: .25; } 66%, 100% { opacity: 1; } }

/* acercamiento: el símbolo del curso crece y se deshace; el detalle llega
   desde el mismo punto, como si la cámara entrara en otro plano          */
.vi-zsym { opacity: 0; }
.vi-svg.vi-zoom { overflow: hidden; }          /* la cámara: lo que crece se recorta en el marco */
.vi-zoom .vi-zsym { animation: vi-zsym 2.8s cubic-bezier(.5, 0, .3, 1) both; }
.vi-zoom .vi-ziso { animation: vi-ziso 2.8s cubic-bezier(.3, 0, .2, 1) both; }
.vi-zoom .vi-zring { animation: vi-zring 2.8s ease both; }
.vi-zoom .vi-zinset { animation: vi-zinset 2.8s ease both; }
@keyframes vi-zsym { 0%, 34% { opacity: 1; transform: none; } 74%, 100% { opacity: 0; transform: scale(3.4); } }
@keyframes vi-ziso { 0%, 40% { opacity: 0; transform: scale(.3); } 88%, 100% { opacity: 1; transform: none; } }
@keyframes vi-zring { 0%, 5% { opacity: 0; } 18%, 100% { opacity: 1; } }
@keyframes vi-zinset { 0%, 84% { opacity: 0; } 100% { opacity: 1; } }

/* el apoyo resaltado de una escena */
.vi-hlr { animation: vi-pulse 1.6s ease-in-out .3s 3; }
@keyframes vi-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }

/* movimiento reducido e impresión: el estado final, quieto; lo libre se ve
   como fantasma fijo donde llega */
@media (prefers-reduced-motion: reduce) {
  .vi-svg, .vi-svg * { animation: none !important; transition: none !important; }
  .vi-svg .vi-rm { display: inline; }
}
@media print {
  .vi-svg, .vi-svg * { animation: none !important; transition: none !important; }
  .vi-svg .vi-rm { display: inline; }
}
