/* ==========================================================================
   Sistema de diseño · Agencia IA — EFECTOS (v1 · 26-sep-2026)
   --------------------------------------------------------------------------
   Patrones de motion y textura sacados del video «100% cashback» de Higgsfield
   (ver Agencia IA/marca/PATRONES-HIGGSFIELD.md). Sirven para CUALQUIER piel:
   solo leen roles (--acento, --peligro, --tinta…) y dos colores de efecto que
   la piel puede fijar: --piel-efecto-luz y --piel-efecto-contraste.

   Se cargan DESPUÉS de tokens.css y de la piel:
     <link rel="stylesheet" href="base/efectos.css">
     <script src="base/efectos.js" defer></script>

   Todo efecto con movimiento respeta prefers-reduced-motion y
   data-movimiento="reducido": se muestra el estado final, sin animar.
   Prefijo de clases: .ef-*  ·  atributos: data-ef-*
   ========================================================================== */

:where(:root, [data-piel], [data-tema]) {
  --efecto-luz: var(--piel-efecto-luz, var(--acento));
  --efecto-contraste: var(--piel-efecto-contraste, var(--peligro));
  --fuente-mono: var(--piel-fuente-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  --ef-desenfoque: 70px;
  --ef-luz-suave: color-mix(in oklab, var(--efecto-luz) 55%, transparent);
  --ef-contraste-suave: color-mix(in oklab, var(--efecto-contraste) 40%, transparent);
}

/* --------------------------------------------------------------------------
   1 · AURA — manchas de luz difuminadas que respiran (fondos de escena)
   -------------------------------------------------------------------------- */
.ef-aura { position: relative; isolation: isolate; overflow: hidden; }
.ef-aura::before,
.ef-aura::after {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  width: 42%; max-width: 560px; aspect-ratio: 1; border-radius: 50%;
  filter: blur(var(--ef-desenfoque));
  animation: ef-deriva 17s var(--curva-estandar) infinite alternate;
}
.ef-aura::before { background: var(--efecto-luz); top: -30%; left: -16%; opacity: .36; }
.ef-aura::after { background: var(--efecto-contraste); bottom: -30%; right: -12%; opacity: .26; animation-duration: 21s; animation-direction: alternate-reverse; }
[data-tema="sitio-noche"] .ef-aura::before, .ef-aura[data-tema="sitio-noche"]::before { opacity: .28; }
[data-tema="sitio-noche"] .ef-aura::after, .ef-aura[data-tema="sitio-noche"]::after { opacity: .18; }
@keyframes ef-deriva { to { transform: translate(14%, 9%) scale(1.14); } }

/* --------------------------------------------------------------------------
   2 · RETÍCULA y REGISTRO — la cuadrícula técnica y las cruces «+» de esquina
   -------------------------------------------------------------------------- */
.ef-reticula {
  --ef-celda: 48px;
  background-image:
    linear-gradient(var(--linea) 1px, transparent 1px),
    linear-gradient(90deg, var(--linea) 1px, transparent 1px);
  background-size: var(--ef-celda) var(--ef-celda);
  background-position: -1px -1px;
}
.ef-registro { position: relative; }
.ef-registro::after {
  content: ""; position: absolute; inset: var(--esp-4); pointer-events: none; z-index: var(--z-elevado);
  --c: var(--linea-fuerte);
  background:
    linear-gradient(var(--c), var(--c)) 0 5px / 11px 1px no-repeat,
    linear-gradient(var(--c), var(--c)) 5px 0 / 1px 11px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 5px / 11px 1px no-repeat,
    linear-gradient(var(--c), var(--c)) calc(100% - 5px) 0 / 1px 11px no-repeat,
    linear-gradient(var(--c), var(--c)) 0 calc(100% - 5px) / 11px 1px no-repeat,
    linear-gradient(var(--c), var(--c)) 5px 100% / 1px 11px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% calc(100% - 5px) / 11px 1px no-repeat,
    linear-gradient(var(--c), var(--c)) calc(100% - 5px) 100% / 1px 11px no-repeat;
}

/* Regla: marcas de medición en el borde izquierdo (escenas de noche) */
.ef-regla { position: relative; }
.ef-regla::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 14px; pointer-events: none;
  background: repeating-linear-gradient(to bottom, var(--ef-contraste-suave) 0 1px, transparent 1px 12px),
              repeating-linear-gradient(to bottom, var(--efecto-contraste) 0 1px, transparent 1px 72px);
  background-size: 7px 100%, 14px 100%; background-repeat: no-repeat;
  opacity: .7;
}

/* --------------------------------------------------------------------------
   3 · LLAVES y CORCHETES — el recurso gráfico de marca: {API} · [SEPTIEMBRE]
   -------------------------------------------------------------------------- */
.ef-llaves::before, .ef-llaves::after,
.ef-corchetes::before, .ef-corchetes::after {
  color: var(--efecto-luz); font-weight: 400; display: inline-block;
}
.ef-llaves::before { content: "{"; margin-right: .06em; }
.ef-llaves::after { content: "}"; margin-left: .06em; }
.ef-corchetes::before { content: "["; margin-right: .04em; }
.ef-corchetes::after { content: "]"; margin-left: .04em; }
/* Sobre claro el lima necesita un filo para verse: */
[data-tema="panel-claro"] .ef-llaves::before, [data-tema="panel-claro"] .ef-llaves::after,
[data-tema="panel-claro"] .ef-corchetes::before, [data-tema="panel-claro"] .ef-corchetes::after,
:where(:root:not([data-tema="sitio-noche"])) .ef-llaves::before {
  -webkit-text-stroke: .025em color-mix(in oklab, var(--efecto-luz) 45%, #000);
}
:where(:root:not([data-tema="sitio-noche"])) .ef-llaves::after,
:where(:root:not([data-tema="sitio-noche"])) .ef-corchetes::before,
:where(:root:not([data-tema="sitio-noche"])) .ef-corchetes::after {
  -webkit-text-stroke: .025em color-mix(in oklab, var(--efecto-luz) 45%, #000);
}
[data-tema="sitio-noche"] .ef-llaves::before, [data-tema="sitio-noche"] .ef-llaves::after,
[data-tema="sitio-noche"] .ef-corchetes::before, [data-tema="sitio-noche"] .ef-corchetes::after { -webkit-text-stroke: 0; }

/* --------------------------------------------------------------------------
   4 · ETIQUETA — píldora rectangular de golpe («ON HIGGSFIELD API», «CASHBACK POOL»)
   -------------------------------------------------------------------------- */
.ef-etiqueta {
  display: inline-flex; align-items: center; gap: .4em;
  padding: .18em .55em .14em; border-radius: 4px;
  font-family: var(--fuente-display); font-weight: 700; text-transform: uppercase; letter-spacing: -.01em;
  background: var(--efecto-contraste); color: #fff; line-height: 1.1;
}
.ef-etiqueta--luz { background: var(--efecto-luz); color: #0b0c0e; }
.ef-etiqueta--tinta { background: var(--tinta); color: var(--fondo); }
.ef-etiqueta--delta { font-family: var(--fuente-cifra); font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   5 · SUBRAYADOR — el lima pasa detrás de la palabra clave
   -------------------------------------------------------------------------- */
.ef-subrayador {
  background: linear-gradient(var(--ef-luz-suave), var(--ef-luz-suave)) no-repeat 0 90% / 0% .44em;
  padding: 0 .06em; -webkit-box-decoration-break: clone; box-decoration-break: clone;
  transition: background-size .9s var(--curva-salida);
}
.ef-subrayador.ef-on { background-size: 100% .44em; }
[data-tema="sitio-noche"] .ef-subrayador { background-image: linear-gradient(color-mix(in oklab, var(--efecto-luz) 35%, transparent), color-mix(in oklab, var(--efecto-luz) 35%, transparent)); }

/* --------------------------------------------------------------------------
   6 · TARJETA DE LUZ — blanco arriba que se vuelve lima abajo, con resplandor
   (la tarjeta de saldo del video). Luce sobre noche; en claro va sin resplandor.
   -------------------------------------------------------------------------- */
.ef-tarjeta-luz {
  position: relative; border-radius: calc(var(--radio-tarjeta) * 1.3);
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 34%, color-mix(in oklab, var(--efecto-luz) 70%, #ffffff) 70%, var(--efecto-luz) 100%);
  color: #0b0c0e; padding: var(--esp-6);
  box-shadow: 0 1px 0 rgba(255,255,255,.6) inset;
}
[data-tema="sitio-noche"] .ef-tarjeta-luz,
.ef-tarjeta-luz[data-resplandor] {
  box-shadow: 0 -28px 90px -18px color-mix(in oklab, var(--efecto-luz) 75%, transparent),
              0 40px 120px -40px color-mix(in oklab, var(--efecto-luz) 55%, transparent);
}
.ef-tarjeta-luz .ef-raya { display: block; height: 2px; width: 30%; margin-left: auto; margin-top: var(--esp-3); background: currentColor; opacity: .7; }

/* --------------------------------------------------------------------------
   7 · ESTADOS — punto plano con pulso de radar (sin brillo 3D, pedido de Paul 26-sep)
   pensando = azul · construyendo = naranja · listo = verde lima
   El color nunca va solo: siempre acompaña a una palabra («Listo», «Construyendo»).
   -------------------------------------------------------------------------- */
.ef-orbe { --c: #5b9bff; position: relative; display: inline-block; width: 12px; height: 12px; border-radius: 50%; flex: none; background: var(--c); }
.ef-orbe::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--c);
  animation: ef-ping 1.9s var(--curva-salida) infinite; }
.ef-orbe--pensando { --c: #5b9bff; }
.ef-orbe--construyendo { --c: #ff8a1f; }
.ef-orbe--listo { --c: #9fe81a; }
.ef-orbe--quieto::after { animation: none; opacity: 0; }
@keyframes ef-ping { 0% { transform: scale(1); opacity: .6; } 100% { transform: scale(2.4); opacity: 0; } }

/* --------------------------------------------------------------------------
   8 · ENTRADA — lo que llega a la vista entra con zoom suave y se posa
   (data-ef-entra; efectos.js pone .ef-on y el índice de escalonado)
   -------------------------------------------------------------------------- */
[data-ef-entra] {
  opacity: 0; transform: translateY(var(--dist-media)) scale(.96);
  transition: opacity var(--dur-lenta) var(--curva-salida), transform calc(var(--dur-lenta) * 2) var(--curva-salida);
  transition-delay: calc(var(--ef-i, 0) * 90ms);
}
[data-ef-entra].ef-on { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   9 · RESOLVER — texto que se arma desde caracteres al azar (efectos.js)
   -------------------------------------------------------------------------- */
.ef-glifo { color: var(--efecto-luz); }
.ef-glifo:nth-child(3n) { color: var(--efecto-contraste); }
[data-tema="panel-claro"] .ef-glifo, :where(:root:not([data-tema="sitio-noche"])) .ef-glifo { color: color-mix(in oklab, var(--efecto-luz) 55%, #000); }
[data-tema="panel-claro"] .ef-glifo:nth-child(3n), :where(:root:not([data-tema="sitio-noche"])) .ef-glifo:nth-child(3n) { color: var(--efecto-contraste); }
[data-tema="sitio-noche"] .ef-glifo { color: var(--efecto-luz); }
.ef-cursor::after { content: "["; color: var(--efecto-luz); margin-left: .04em; animation: ef-parpadeo 1s steps(1) infinite; }
@keyframes ef-parpadeo { 50% { opacity: 0; } }

/* --------------------------------------------------------------------------
   10 · GLITCH — cortes y separación de color al entrar o cambiar (efectos.js)
   -------------------------------------------------------------------------- */
.ef-glitch { animation: ef-glitch .42s steps(2, end) 1; }
@keyframes ef-glitch {
  0%   { text-shadow: .06em 0 var(--efecto-luz), -.06em 0 var(--efecto-contraste); clip-path: inset(0 0 55% 0); transform: translateX(-.04em); }
  25%  { text-shadow: -.08em 0 var(--efecto-luz), .05em 0 var(--efecto-contraste); clip-path: inset(40% 0 20% 0); transform: translateX(.05em); }
  50%  { text-shadow: .04em 0 var(--efecto-luz), -.04em 0 var(--efecto-contraste); clip-path: inset(10% 0 60% 0); transform: none; }
  75%  { text-shadow: -.03em 0 var(--efecto-luz), .03em 0 var(--efecto-contraste); clip-path: inset(0 0 0 0); }
  100% { text-shadow: none; clip-path: none; transform: none; }
}

/* --------------------------------------------------------------------------
   11 · CONTADOR — la cifra corre; lo que baja se tiñe de contraste, lo que
   sube de luz; el delta aparece arriba (efectos.js → Efectos.contar)
   -------------------------------------------------------------------------- */
.ef-contador { font-family: var(--fuente-cifra); font-variant-numeric: tabular-nums; letter-spacing: -.03em; transition: color var(--dur-lenta) var(--curva-estandar); }
.ef-contador.ef-baja { color: var(--efecto-contraste); }
.ef-contador.ef-sube { color: color-mix(in oklab, var(--efecto-luz) 60%, #000); }
[data-tema="sitio-noche"] .ef-contador.ef-sube { color: var(--efecto-luz); }
.ef-delta { display: inline-block; font-family: var(--fuente-cifra); font-weight: 700; font-variant-numeric: tabular-nums; opacity: 0; transform: translateY(8px); transition: opacity .35s var(--curva-salida), transform .5s var(--curva-salida); }
.ef-delta.ef-on { opacity: 1; transform: none; }
.ef-delta--baja { color: var(--efecto-contraste); }
.ef-delta--sube { color: var(--efecto-luz); }
[data-tema="panel-claro"] .ef-delta--sube, :where(:root:not([data-tema="sitio-noche"])) .ef-delta--sube { color: #0b0c0e; background: var(--efecto-luz); padding: 0 .25em; border-radius: 4px; }
[data-tema="sitio-noche"] .ef-delta--sube { color: var(--efecto-luz); background: none; padding: 0; }

/* --------------------------------------------------------------------------
   12 · HUD — cajas de rastreo con coordenadas sobre lo importante (efectos.js)
   -------------------------------------------------------------------------- */
.ef-hud-capa { position: absolute; inset: 0; pointer-events: none; z-index: var(--z-elevado); }
.ef-hud-caja { position: absolute; border: 1px solid var(--efecto-luz); opacity: 0; transition: opacity .25s linear; }
.ef-hud-caja:nth-child(2n) { border-color: var(--efecto-contraste); }
.ef-hud-caja.ef-on { opacity: 1; }
.ef-hud-caja span { position: absolute; top: -1.5em; left: -1px; font-family: var(--fuente-mono); font-size: 11.5px; line-height: 1.3; white-space: nowrap; color: var(--efecto-contraste); background: color-mix(in oklab, var(--fondo) 70%, transparent); padding: 0 3px; }
.ef-hud-capa svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.ef-hud-capa line { stroke: color-mix(in oklab, var(--tinta) 45%, transparent); stroke-width: 1; }

/* --------------------------------------------------------------------------
   13 · ASCII y CÓDIGO FANTASMA — textura de caracteres y código tenue
   -------------------------------------------------------------------------- */
.ef-ascii { position: relative; isolation: isolate; }
.ef-ascii > canvas.ef-ascii-lienzo { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }
.ef-codigo {
  position: absolute; pointer-events: none; user-select: none; white-space: pre;
  font-family: var(--fuente-mono); font-size: 12.5px; line-height: 1.55;
  color: color-mix(in oklab, var(--tinta) 20%, transparent);
}

/* --------------------------------------------------------------------------
   14 · RUEDA — lista que gira en abanico con ▶ en el elegido (efectos.js)
   -------------------------------------------------------------------------- */
.ef-rueda { position: relative; list-style: none; height: 15em; overflow: hidden; perspective: 900px; }
.ef-rueda > li {
  position: absolute; left: 1.6em; top: 50%; white-space: nowrap;
  font-family: var(--fuente-display); font-weight: 700; text-transform: uppercase; letter-spacing: -.02em;
  /* --d = distancia al elegido (con signo); --ad = |d| y --ad1 = min(1,|d|), los pone efectos.js.
     Gira alrededor de un centro 30em a la izquierda (el abanico) y se achica sobre su propio borde. */
  transform-origin: 0 50%;
  transform: translateY(-50%) translateX(-30em) rotate(calc(var(--d, 0) * 7deg)) translateX(30em) scale(calc(1 - var(--ad1, 0) * .26));
  opacity: calc(1 - var(--ad, 0) * .24);
  filter: blur(calc(max(0, var(--ad, 0) - 1) * .8px));
  transition: transform .7s var(--curva-salida), opacity .5s var(--curva-estandar), filter .5s var(--curva-estandar);
}
.ef-rueda > li.ef-activo::before { content: "▶"; position: absolute; left: -1.5em; font-size: .6em; top: 50%; transform: translateY(-50%); color: var(--tinta); }

/* --------------------------------------------------------------------------
   15 · DUOTONO — foto o video mapeado de contraste (sombras) a luz (brillos)
   (efectos.js crea el filtro SVG con los colores de la piel)
   -------------------------------------------------------------------------- */
.ef-duotono { filter: url(#ef-duotono); }

/* --------------------------------------------------------------------------
   Movimiento reducido: estado final, sin animar
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ef-aura::before, .ef-aura::after, .ef-orbe::after, .ef-cursor::after { animation: none; }
  .ef-glitch { animation: none; }
  [data-ef-entra] { opacity: 1; transform: none; transition: none; }
  .ef-subrayador { background-size: 100% .44em; transition: none; }
  .ef-rueda > li { transition: none; }
}
[data-movimiento="reducido"] .ef-aura::before, [data-movimiento="reducido"] .ef-aura::after,
[data-movimiento="reducido"] .ef-orbe::after, [data-movimiento="reducido"] .ef-cursor::after,
[data-movimiento="reducido"] .ef-glitch { animation: none; }
[data-movimiento="reducido"] [data-ef-entra] { opacity: 1; transform: none; transition: none; }
[data-movimiento="reducido"] .ef-subrayador { background-size: 100% .44em; transition: none; }

/* --------------------------------------------------------------------------
   16 · ESCENA DE SCROLL — la escena se queda fija y el scroll la recorre
   (data-ef-scroll en el envoltorio alto; efectos.js calcula el avance 0→1)
   <div class="ef-scroll" data-ef-scroll style="--ef-alto:320vh">
     <div class="ef-scroll__fijo"> …escena… </div>
   </div>
   -------------------------------------------------------------------------- */
.ef-scroll { position: relative; height: var(--ef-alto, 300vh); }
.ef-scroll__fijo {
  position: sticky; top: var(--ef-arriba, 0px);
  height: calc(100svh - var(--ef-arriba, 0px));
  display: flex; flex-direction: column; justify-content: center; overflow: hidden;
}
.ef-rueda[data-ritmo="scroll"] > li { transition: transform .14s linear, opacity .14s linear, filter .14s linear; }

/* --------------------------------------------------------------------------
   17 · CIRCUITO — líneas tecnológicas que llegan desde los bordes, dibujan el
   marco de una tarjeta y la llenan por fases; luego corren pulsos de luz.
   (data-ef-circuito dentro de una escena de scroll, o solo al verse)
   -------------------------------------------------------------------------- */
.ef-circuito { position: relative; width: 100%; height: 100%; min-height: 540px; }
.ef-circuito__trazos { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.ef-circuito__trazos .ef-traza { fill: none; stroke: color-mix(in oklab, var(--tinta) 42%, transparent); stroke-width: 1.25; stroke-linejoin: round; }
.ef-circuito__trazos .ef-traza.ef-viva { stroke: color-mix(in oklab, var(--tinta) 70%, transparent); }
.ef-circuito__trazos .ef-marco { fill: none; stroke: var(--tinta); stroke-width: 1.6; }
.ef-circuito__trazos .ef-nodo { fill: var(--efecto-luz); stroke: var(--tinta); stroke-width: 1.2; opacity: 0; transition: opacity .2s; }
.ef-circuito__trazos .ef-nodo.ef-on { opacity: 1; }
.ef-circuito__trazos .ef-fuente { fill: var(--tinta); opacity: 0; transition: opacity .2s; }
.ef-circuito__trazos .ef-fuente.ef-on { opacity: 1; }
.ef-circuito__trazos .ef-pulso { fill: var(--efecto-luz); stroke: var(--tinta); stroke-width: 1; }
[data-tema="sitio-noche"] .ef-circuito__trazos .ef-pulso { stroke: none; filter: drop-shadow(0 0 6px var(--efecto-luz)); }
.ef-circuito__etiqueta {
  position: absolute; font-family: var(--fuente-mono); font-size: 12.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--tinta); white-space: nowrap; opacity: 0; transition: opacity .3s;
  background: color-mix(in oklab, var(--fondo) 82%, transparent); padding: 2px 6px; border-radius: 4px;
}
.ef-circuito__etiqueta.ef-on { opacity: 1; }
.ef-circuito__etiqueta.ef-llega { color: #0b0c0e; background: var(--efecto-luz); }
.ef-circuito__tarjeta {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(.985);
  width: min(660px, 80%); border-radius: 24px; padding: clamp(18px, 3vw, 30px);
  background: transparent; transition: background-color .5s, box-shadow .7s, transform .7s var(--curva-salida);
}
.ef-circuito__tarjeta.ef-lleno {
  background: var(--superficie); transform: translate(-50%, -50%);
  box-shadow: 0 34px 90px -44px color-mix(in oklab, var(--efecto-luz) 90%, transparent);
}
[data-ef-fase] { opacity: 0; transform: translateY(10px); transition: opacity .45s var(--curva-salida), transform .7s var(--curva-salida); }
[data-ef-fase].ef-on { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .ef-scroll { height: auto; }
  .ef-scroll__fijo { position: relative; height: auto; min-height: 100svh; }
  [data-ef-fase] { opacity: 1; transform: none; transition: none; }
}
[data-movimiento="reducido"] .ef-scroll { height: auto; }
[data-movimiento="reducido"] .ef-scroll__fijo { position: relative; height: auto; min-height: 100svh; }
[data-movimiento="reducido"] [data-ef-fase] { opacity: 1; transform: none; transition: none; }

/* --------------------------------------------------------------------------
   18 · PALANCA DE FRASES — el titular cambia al jalar la palanca (a la derecha)
   y baja sola cada pocos segundos. Se puede arrastrar, tocar o activar con teclado.
   <div data-ef-frases='[["Tu negocio","En automático","Sin contratar a nadie"], …]' data-ef-auto="6000">
     … [data-ef-frase="a|b|c"] …  <button class="ef-palanca">…</button>
   -------------------------------------------------------------------------- */
.ef-palanca {
  position: absolute; right: clamp(12px, 2.4vw, 30px); top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 24px;
  background: none; border: 0; padding: 8px 6px; cursor: grab; touch-action: none; color: var(--tinta);
  z-index: var(--z-elevado);
}
.ef-palanca:active { cursor: grabbing; }
.ef-palanca__riel {
  position: relative; width: 14px; height: clamp(120px, 22vh, 190px); border-radius: 999px;
  background: var(--superficie-2); box-shadow: inset 0 0 0 1px var(--linea-fuerte);
}
.ef-palanca__riel::before { /* marcas del riel */
  content: ""; position: absolute; left: 50%; top: 14px; bottom: 14px; width: 1px; transform: translateX(-50%);
  background: repeating-linear-gradient(to bottom, var(--linea-fuerte) 0 1px, transparent 1px 12px);
}
.ef-palanca__perilla {
  position: absolute; left: 50%; top: -6px; width: 34px; height: 34px; margin-left: -17px; border-radius: 50%;
  background: var(--tinta); box-shadow: 0 6px 16px -6px rgba(0,0,0,.45), inset 0 0 0 3px var(--efecto-luz);
  will-change: transform;
}
.ef-palanca__perilla::after { content: ""; position: absolute; inset: 11px; border-radius: 50%; background: var(--efecto-luz); }
.ef-palanca__texto { font-family: var(--fuente-mono); font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--tinta-suave); writing-mode: vertical-rl; }
.ef-palanca:focus-visible { outline: 2px solid var(--foco); outline-offset: 4px; border-radius: 12px; }
.ef-palanca__progreso { position: absolute; left: 50%; bottom: -14px; width: 22px; height: 3px; margin-left: -11px; border-radius: 3px; background: var(--linea); overflow: hidden; }
.ef-palanca__progreso i { display: block; height: 100%; width: 0; background: var(--tinta); }
[data-ef-frases] [data-ef-frase] { transition: opacity .2s; }
.ef-oculto-lector { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Etiquetas del circuito con logos (monocromos, en tinta) */
.ef-circuito__etiqueta { display: inline-flex; align-items: center; gap: 6px; }
.ef-logo { width: 16px; height: 16px; display: block; flex: none; }
[data-tema="sitio-noche"] .ef-circuito__etiqueta:not(.ef-llega) .ef-logo { filter: invert(1); }
.ef-logo-txt { font-family: var(--fuente-mono); font-size: 10.5px; letter-spacing: .04em; line-height: 1; padding: 3px 5px; border: 1px solid currentColor; border-radius: 4px; }
.ef-circuito--angosto .ef-circuito__nombre { display: none; }
.ef-circuito--angosto .ef-circuito__etiqueta { padding: 3px; gap: 4px; }
