/**
 * Pantalla de acceso a InTactics.
 *
 * El panel de la izquierda es un mapa nocturno de México y Estados Unidos con
 * las plazas de la empresa en su posición geográfica real; alrededor, cuatro
 * rincones que cuentan la operación (trayecto, flujo, radar y patio) y, al
 * centro, la marca. Todo es SVG y CSS: no se carga ninguna imagen de fondo.
 *
 * El HTML vive en app/views/login/index.blade.php y el movimiento en
 * public/js/acceso.js (y acceso-mapa.js, que trae el mapa).
 *
 * Nota: el mapa sale de Natural Earth (dominio público), convertido a trazos.
 */


  :root {
    --papel: #f7f4ef;
    --tinta: #16202f;
    --marino: #1e3359;
    --marino-hondo: #0f1c33;
    --acento: #c2703d;
    --arena: #f0b183;
    --verde: #2f7a5f;
    --gris: #6b7688;
    --linea: #d9d2c6;
    --cuerpo: 'Figtree', system-ui, sans-serif;
    --display: 'Instrument Serif', Georgia, serif;
  }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    min-height: 100vh;
    font-family: var(--cuerpo);
    font-size: 16px;
    color: var(--tinta);
    background: var(--papel);
    display: grid;
    grid-template-columns: minmax(0, 1fr) clamp(390px, 30vw, 520px);
  }
  /* ================== Panel de marca (izquierda) ================== */
  .panel {
    position: relative;
    overflow: hidden;
    /* noche cerrada, con una franja tenue en diagonal que hace de vía láctea */
    background:
      linear-gradient(118deg, transparent 38%, rgba(190,210,255,.06) 50%, transparent 62%),
      radial-gradient(60% 50% at 28% 14%, rgba(48,80,140,.42), transparent 66%),
      linear-gradient(165deg, #0d1c38 0%, #071026 58%, #04080f 100%);
    color: #eaf1fb;
    display: flex;
    flex-direction: column;
    padding: clamp(34px, 5vh, 58px) clamp(30px, 4vw, 60px);
  }
  /* ---------- El mapa: silueta de México y Estados Unidos con sus luces ----------
     Son los contornos reales (Natural Earth, dominio público) convertidos a
     trazos; las plazas de InTactics están en su posición geográfica exacta. */
  .mapa-fondo {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    z-index: 1;
    pointer-events: none;
  }
  .pais {
    fill: rgba(18,42,84,.42);
    stroke: rgba(126,176,240,.38);
    stroke-width: .7;
    stroke-linejoin: round;
  }
  .mapa-polvo circle { fill: #ffd9a0; }
  .mapa-ciudades circle {
    fill: #fff1d8;
    filter: drop-shadow(0 0 3px rgba(255,186,94,.95));
    animation: latirCiudad 5.5s ease-in-out infinite;
  }
  @keyframes latirCiudad {
    0%, 100% { opacity: .55; }
    50%      { opacity: 1; }
  }
  /* las rutas sobre el mapa */
  .ruta-mapa {
    fill: none;
    stroke: rgba(240,177,131,.85);
    stroke-width: 1.5;
    stroke-dasharray: 5 7;
    animation: recorrer 3.4s linear infinite;
  }
  .traza-mapa {
    fill: none;
    stroke: #ffd9a0;
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-dasharray: 70 900;
    filter: drop-shadow(0 0 5px rgba(255,200,130,.9));
    animation: viajar 9s cubic-bezier(.45,0,.55,1) infinite;
  }
  .caja-mapa { fill: #fff6ea; filter: drop-shadow(0 0 6px rgba(255,200,130,.95)); }
  .halo-mapa {
    fill: rgba(255,214,150,.3);
    transform-origin: center; transform-box: fill-box;
    animation: expandir 3s ease-out infinite;
  }
  .punto-mapa { fill: #fff8ee; filter: drop-shadow(0 0 4px rgba(255,190,110,.9)); }
  .plaza-mapa text {
    fill: rgba(255,244,230,.92);
    font-family: var(--cuerpo);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .1em;
  }
  /* El cielo: una capa fija detrás de todo, para que las estrellas se vean
     en cualquiera de los modos y no solo en la escena de la constelación. */
  .cielo-fondo {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    z-index: 0;
    pointer-events: none;
  }
  .marca { position: relative; z-index: 4; display: flex; align-items: center; gap: 22px; }
  /* Del logo se usa solo el patrón de puntos: la palabra InTactics va
     compuesta en tipografía, al lado. */
  .marca .simbolo {
    flex: none;
    aspect-ratio: 487 / 342;
    background: url('/v3/pantalla-acceso/logo_intactics_bg_white.png') no-repeat top center;
    background-size: 100% auto;
    animation: asomarMarca 1s cubic-bezier(.16,1,.3,1) both;
  }
  /* El logo va en sus colores, así que necesita piso claro: si no, el azul
     marino de la marca se pierde contra el cielo. El disco además hace las
     veces de luna en esta escena. */
  .disco {
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: radial-gradient(circle at 38% 32%, #fffdf8 0%, #f5f0e6 62%, #e6dccb 100%);
    box-shadow:
      0 0 42px rgba(255,243,219,.35),
      inset 0 -8px 22px rgba(30,51,89,.10);
    flex: none;
  }
  .disco-chico { width: clamp(96px, 9vw, 132px); aspect-ratio: 1; }
  .disco-chico .simbolo { width: 66%; }
  .disco-grande {
    width: clamp(150px, 15vw, 210px);
    aspect-ratio: 1;
    margin: 0 auto;
    animation: respirarLogo 6s ease-in-out infinite;
  }
  .disco-grande .simbolo-central { width: 66%; animation: none; }
  .marca .nombre {
    font-family: var(--cuerpo);
    font-weight: 700;
    font-size: clamp(38px, 4.4vw, 60px);
    line-height: .95;
    letter-spacing: -.025em;
    animation: asomarMarca 1s cubic-bezier(.16,1,.3,1) .12s both;
  }
  .marca .lema {
    margin-top: 10px;
    font-family: var(--cuerpo);
    font-size: 16px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: rgba(234,241,251,.62);
    animation: asomarMarca 1s cubic-bezier(.16,1,.3,1) .22s both;
  }
  @keyframes asomarMarca {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: none; }
  }
  /* ---------- Modo mosaico: las cuatro operaciones alrededor de la marca ----------
     Las esquinas van tenues y pequeñas; el centro manda. Si todo pesara igual,
     la pantalla se volvería ruido. */
      /* La capa de las esquinas va encima del mapa, así que tiene que dejar
     pasar el mouse: si no, los clics nunca llegarían a las plazas. */
  .tablero { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
  /* hunde el centro para que el logo se despegue del fondo */
  .tablero::after {
    content: '';
    position: absolute; inset: 0;
    background: radial-gradient(38% 34% at 63% 47%, rgba(7,16,38,.92) 22%, rgba(7,16,38,.45) 52%, transparent 78%);
    pointer-events: none;
  }
  .cuadrante {
    position: absolute;
    width: 43%;
    opacity: .7;
    animation: asomarCuadrante 1.4s cubic-bezier(.16,1,.3,1) both;
  }
  /* cada una jalada a su esquina, para despejar el centro */
  .cuadrante.sup-izq { top: 7%; left: -3%; }
  .cuadrante.sup-der { top: 7%; right: -3%; animation-delay: .15s; }
  .cuadrante.inf-izq { bottom: 3%; left: -3%; animation-delay: .3s; }
  .cuadrante.inf-der { bottom: 3%; right: -3%; animation-delay: .45s; }
  @keyframes asomarCuadrante {
    from { opacity: 0; transform: scale(.9); }
    to   { opacity: .7; transform: none; }
  }
  /* los hilos que llevan todo al centro */
  .conectores { position: absolute; inset: 0; width: 100%; height: 100%; }
  .conectores line {
    stroke: rgba(240,177,131,.22);
    stroke-width: .5;
  }
  .conectores circle {
    fill: rgba(255,246,234,.9);
    filter: drop-shadow(0 0 3px rgba(240,177,131,.9));
  }
  /* ---- el núcleo: la marca ---- */
  /* El logo no va al centro exacto: ahí caen N. Laredo y Reynosa. Se corre
     sobre el Golfo, que es mar y no tapa nada. */
  .nucleo {
    position: absolute;
    left: 63%; top: 47%;
    z-index: 4;
    text-align: center;
    /* el centrado vive dentro de los keyframes: si la animación terminara en
       `transform: none`, se perdería el translate y el logo se recorrería */
    animation: asomarNucleo 1.2s cubic-bezier(.16,1,.3,1) both;
  }
  @keyframes asomarNucleo {
    from { opacity: 0; transform: translate(-50%, calc(-50% + 18px)); }
    to   { opacity: 1; transform: translate(-50%, -50%); }
  }
  .nucleo .simbolo-central {
    aspect-ratio: 487 / 342;
    margin: 0 auto;
    background: url('/v3/pantalla-acceso/logo_intactics_bg_white.png') no-repeat top center;
    background-size: 100% auto;
    animation: respirarLogo 6s ease-in-out infinite;
  }
  @keyframes respirarLogo {
    0%, 100% { transform: translateY(0) scale(1); }
    50%      { transform: translateY(-6px) scale(1.03); }
  }
  .nucleo .nombre-central {
    margin-top: 14px;
    font-family: var(--cuerpo);
    font-weight: 700;
    font-size: clamp(32px, 3.4vw, 46px);
    line-height: .95;
    letter-spacing: -.025em;
  }
  .nucleo .lema-central {
    margin-top: 10px;
    font-size: 16px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: rgba(234,241,251,.6);
  }
  /* ondas que salen del logo, como un pulso del sistema */
  .onda {
    position: absolute;
    left: 50%; top: 42%;
    width: 180px; height: 180px;
    margin: -90px 0 0 -90px;
    border: 1px solid rgba(240,177,131,.5);
    border-radius: 50%;
    animation: emanar 6s ease-out infinite;
    pointer-events: none;
  }
  @keyframes emanar {
    0%   { transform: scale(.35); opacity: .85; }
    70%  { opacity: 0; }
    100% { transform: scale(2.6); opacity: 0; }
  }
  .ruta {
    fill: none; stroke: rgba(240,177,131,.8); stroke-width: 1.6;
    stroke-dasharray: 5 7;
    animation: recorrer 3.4s linear infinite;
  }
  @keyframes recorrer { to { stroke-dashoffset: -48; } }
  .traza {
    fill: none; stroke: var(--arena); stroke-width: 2.4; stroke-linecap: round;
    stroke-dasharray: 60 900;
    filter: drop-shadow(0 0 5px rgba(240,177,131,.75));
    animation: viajar 6s cubic-bezier(.45,0,.55,1) infinite;
  }
  @keyframes viajar {
    0%   { stroke-dashoffset: 960; opacity: 0; }
    10%  { opacity: 1; }
    90%  { opacity: 1; }
    100% { stroke-dashoffset: -60; opacity: 0; }
  }
  .plaza circle.halo {
    fill: rgba(240,177,131,.25);
    animation: expandir 3s ease-out infinite;
    transform-origin: center; transform-box: fill-box;
  }
  @keyframes expandir {
    0%   { transform: scale(.4); opacity: .9; }
    100% { transform: scale(2.6); opacity: 0; }
  }
  .plaza circle.punto { fill: var(--papel); }
  .plaza text { fill: rgba(234,241,251,.85); font-family: var(--cuerpo); font-size: 13px; letter-spacing: .08em; }
  .caja-viajera { fill: #fff6ea; filter: drop-shadow(0 0 8px rgba(240,177,131,.9)); }
  /* ---------- 2. Constelación: el patrón de la marca, como cielo ----------
     Tres capas: polvo de estrellas al fondo, las estrellas de la marca (los
     óvalos del logo) al frente, y de vez en cuando una fugaz. */

  /* polvo de estrellas */
  .estrella {
    fill: #ffffff;
    animation: titilar 3s ease-in-out infinite alternate;
  }
  @keyframes titilar {
    from { opacity: .12; }
    to   { opacity: .9; }
  }
  /* las estrellas de la marca */
  .grano {
    transform-box: fill-box; transform-origin: center;
    filter: drop-shadow(0 0 3px rgba(255,238,214,.75));
    animation: respirar 5s ease-in-out infinite, encender 1.1s ease-out both;
  }
  @keyframes respirar {
    0%, 100% { transform: translateY(0) scale(1); opacity: .88; }
    50%      { transform: translateY(-5px) scale(1.06); opacity: 1; }
  }
  @keyframes encender {
    from { opacity: 0; transform: scale(.2); }
    to   { opacity: 1; transform: scale(1); }
  }
  /* el destello que cruza por encima de las estrellas de la marca */
  .chispa {
    fill: #fff;
    opacity: 0;
    transform-box: fill-box; transform-origin: center;
    animation: destellar 9s ease-in-out infinite;
  }
  @keyframes destellar {
    0%, 92%   { opacity: 0; transform: scale(.2) rotate(0deg); }
    96%       { opacity: .95; transform: scale(1) rotate(45deg); }
    100%      { opacity: 0; transform: scale(.2) rotate(90deg); }
  }
  /* las líneas de la constelación: se quedan, tenues, como en un mapa estelar */
  .linea-cielo {
    stroke: rgba(255,238,214,.16);
    stroke-width: .7;
    fill: none;
  }
  /* los hilos que se tejen y destejen entre estrellas lejanas */
  .hilo {
    stroke: rgba(240,177,131,.45); stroke-width: .8; fill: none;
    stroke-dasharray: 120; stroke-dashoffset: 120;
    animation: tejer 4.5s ease-in-out infinite;
  }
  @keyframes tejer {
    0%   { stroke-dashoffset: 120; opacity: 0; }
    30%  { opacity: .9; }
    60%  { stroke-dashoffset: 0; opacity: .9; }
    100% { stroke-dashoffset: -120; opacity: 0; }
  }
  /* la fugaz */
  .fugaz {
    stroke: url(#colaFugaz);
    stroke-width: 1.6;
    stroke-linecap: round;
    opacity: 0;
    animation: cruzar 11s linear infinite;
  }
  @keyframes cruzar {
    0%, 78%  { opacity: 0; transform: translate(0, 0); }
    80%      { opacity: .95; }
    88%      { opacity: 0; transform: translate(190px, 105px); }
    100%     { opacity: 0; transform: translate(190px, 105px); }
  }
  /* ---------- 3. Flujo continuo ---------- */
  .corriente { fill: none; stroke: rgba(234,241,251,.18); stroke-width: 28; stroke-linecap: round; }
  .corriente-luz {
    fill: none; stroke: url(#degradadoFlujo); stroke-width: 28; stroke-linecap: round;
    stroke-dasharray: 90 620;
    animation: fluir 3.6s linear infinite;
  }
  @keyframes fluir { to { stroke-dashoffset: -710; } }
  .bulto { fill: var(--arena); opacity: .95; }
  .estacion line { stroke: rgba(234,241,251,.35); stroke-width: 1.4; }
  .estacion text { fill: rgba(234,241,251,.75); font-family: var(--cuerpo); font-size: 12.5px; letter-spacing: .1em; }
  /* Las copias del mosaico son las mismas animaciones, nada más reducidas.
     El texto va dentro del SVG, así que al encoger el dibujo el nombre se
     encogería también: por eso aquí se agranda en unidades del viewBox,
     para que al final se lea del mismo tamaño que en la versión grande. */
  .cuadrante .plaza text,
  .cuadrante .estacion text { font-size: 21px; letter-spacing: .06em; }
  .cuadrante .radar { width: min(92%, 235px); margin: 0 auto; }
  /* con las doce plazas el radar necesita ir centrado en su rincón:
     pegado al borde, las etiquetas de la izquierda se salían */
  .cuadrante.inf-izq .radar { margin: 0 auto; }
  .cuadrante .radar .eco { width: 6px; height: 6px; margin: -3px 0 0 -3px; }
  .cuadrante .radar .eco b { left: 13px; font-size: 13px; }
  .cuadrante .patio { height: 120px; gap: 7px; }
  .cuadrante .patio .contenedor { width: 46px; height: 20px; }
  .cuadrante .patio .contenedor::before { inset: 4px 5px; }
  .cuadrante .grua { max-width: 250px; height: 5px; margin-bottom: 12px; }
  .cuadrante .grua::after { height: 26px; }
  .cuadrante .piso-patio { max-width: 250px; }
  /* ---------- 4. Radar ---------- */
  .radar {
    position: relative; width: min(74%, 330px); aspect-ratio: 1; margin: 0 auto;
    border-radius: 50%; border: 1px solid rgba(240,177,131,.45);
    background: radial-gradient(circle, rgba(240,177,131,.12), transparent 72%);
  }
  .radar .anillo { position: absolute; inset: 0; margin: auto; border: 1px solid rgba(240,177,131,.3); border-radius: 50%; }
  .radar .anillo.a { width: 72%; height: 72%; }
  .radar .anillo.b { width: 46%; height: 46%; }
  .radar .anillo.c { width: 22%; height: 22%; border-color: rgba(240,177,131,.38); }
  .radar .barrido {
    position: absolute; inset: 0; border-radius: 50%;
    background: conic-gradient(from 0deg, transparent 0deg 300deg, rgba(240,177,131,.22) 350deg, rgba(255,246,234,.5) 360deg);
    animation: girarRadar 4.6s linear infinite;
  }
  @keyframes girarRadar { to { transform: rotate(360deg); } }
  .radar .eco {
    position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px;
    border-radius: 50%; background: #fff6ea; box-shadow: 0 0 10px var(--arena);
  }
  .radar .eco::after {
    content: ''; position: absolute; inset: -4px;
    border: 1px solid rgba(255,246,234,.8); border-radius: 50%;
    animation: expandirEco 3.4s ease-out infinite;
  }
  @keyframes expandirEco {
    from { transform: scale(.5); opacity: .9; }
    to   { transform: scale(3.4); opacity: 0; }
  }
  .radar .eco b {
    position: absolute; left: 20px; top: -6px;
    font-size: 13px; font-weight: 500; white-space: nowrap;
    color: rgba(234,241,251,.75);
  }
  /* ---------- 5. Patio (contenedores apilándose) ---------- */
  .patio { display: flex; align-items: flex-end; justify-content: center; gap: 10px; height: 260px; }
  .pila { display: flex; flex-direction: column-reverse; gap: 6px; }
  .contenedor {
    width: 76px; height: 34px;
    border-radius: 3px;
    background: linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,.06));
    border: 1px solid rgba(234,241,251,.35);
    position: relative;
    /* El patio no se arma una vez y se queda: cada caja baja, se queda un
       rato en la pila y la grúa se la lleva. Con duraciones distintas por
       caja (las reparte el JS) siempre hay algo moviéndose. */
    animation: trabajarPatio 16s cubic-bezier(.3,1.2,.5,1) infinite both;
  }
  .contenedor::before {
    content: ''; position: absolute; inset: 6px 8px;
    background-image: repeating-linear-gradient(90deg, rgba(234,241,251,.25) 0 2px, transparent 2px 7px);
  }
  .contenedor.marcado { background: linear-gradient(180deg, rgba(240,177,131,.85), rgba(194,112,61,.7)); border-color: rgba(255,246,234,.5); }
  @keyframes trabajarPatio {
    0%        { opacity: 0; transform: translateY(-120px) rotate(-5deg); }
    7%        { opacity: 1; transform: none; }
    72%       { opacity: 1; transform: none; }
    73%       { opacity: 1; transform: translateY(-3px) rotate(1deg); }
    86%, 100% { opacity: 0; transform: translateY(-120px) rotate(4deg); }
  }
  .grua {
    position: relative; width: 100%; max-width: 430px; height: 8px; margin: 0 auto 22px;
    background: rgba(234,241,251,.35); border-radius: 4px;
  }
  .grua::after {
    content: ''; position: absolute; top: 8px; left: 0;
    width: 2px; height: 42px; background: rgba(234,241,251,.4);
    animation: pasear 9s ease-in-out infinite;
  }
  @keyframes pasear {
    0%        { left: 12%; }
    45%, 55%  { left: 84%; }
    100%      { left: 12%; }
  }
  .piso-patio { width: min(100%, 430px); height: 2px; margin: 8px auto 0; background: rgba(234,241,251,.3); }
  /* ---------- 6. Trayecto (hitos de la operación) ---------- */
  .trayecto { width: 100%; max-width: 440px; margin: 0 auto; }
  .hito { position: relative; display: flex; gap: 18px; padding-bottom: 26px; }
  .hito:last-child { padding-bottom: 0; }
  .hito .marca-hito {
    position: relative; flex: none;
    width: 16px; height: 16px; margin-top: 3px;
    border-radius: 50%;
    border: 1.5px solid rgba(240,177,131,.55);
    background: rgba(15,28,51,.9);
  }
  .hito:not(:last-child) .marca-hito::after {
    content: ''; position: absolute; left: 50%; top: 18px;
    width: 1.5px; height: 34px; margin-left: -.75px;
    background: rgba(234,241,251,.18);
  }
  .hito .marca-hito i {
    position: absolute; inset: 3px;
    border-radius: 50%; background: var(--arena);
    transform: scale(0);
    animation: prender 9s linear infinite;
  }
  .hito .texto b { display: block; font-size: 17px; font-weight: 600; color: #f3f7fd; }
  .hito .texto span { font-size: 16px; color: rgba(234,241,251,.55); }
  .hito .texto { opacity: .4; animation: aclarar 9s linear infinite; }
  @keyframes prender {
    0%, 4%   { transform: scale(0); }
    8%, 96%  { transform: scale(1); }
    100%     { transform: scale(0); }
  }
  @keyframes aclarar {
    0%, 4%  { opacity: .35; }
    9%, 96% { opacity: 1; }
    100%    { opacity: .35; }
  }
  /* ================== Formulario (derecha) ================== */
  .formulario {
    position: relative;
    display: flex; flex-direction: column; justify-content: center;
    padding: clamp(36px, 5vh, 60px) clamp(30px, 3.4vw, 58px);
    background:
      radial-gradient(60% 50% at 80% 0%, rgba(194,112,61,.07), transparent 60%),
      var(--papel);
  }
  .formulario::before {
    content: '';
    position: absolute; inset: 0;
    background-image:
      linear-gradient(var(--linea) 1px, transparent 1px),
      linear-gradient(90deg, var(--linea) 1px, transparent 1px);
    background-size: 28px 28px;
    opacity: .35;
    mask-image: radial-gradient(90% 80% at 70% 40%, #000, transparent);
    pointer-events: none;
  }
  .contenido { position: relative; width: 100%; max-width: 400px; margin: 0 auto; }
  .encabezado { margin-bottom: clamp(22px, 3.5vh, 34px); }
  .folio {
    display: inline-flex; align-items: center; gap: 9px;
    padding: 6px 13px; margin-bottom: 16px;
    font-size: 16px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--gris);
    background: rgba(255,255,255,.7);
    border: 1px solid var(--linea);
    border-radius: 999px;
  }
  .folio i { width: 7px; height: 7px; border-radius: 50%; background: var(--verde); animation: latir 2.4s infinite; }
  @keyframes latir {
    0%   { box-shadow: 0 0 0 0 rgba(47,122,95,.5); }
    70%  { box-shadow: 0 0 0 8px rgba(47,122,95,0); }
    100% { box-shadow: 0 0 0 0 rgba(47,122,95,0); }
  }
  h1 {
    margin: 0;
    font-family: var(--display);
    font-size: clamp(34px, 4.2vw, 50px);
    font-weight: 400; line-height: 1.03; letter-spacing: -.02em;
  }
  h1 em { font-style: italic; color: var(--acento); }
  .entrada { margin: 12px 0 0; font-size: 17px; color: var(--gris); line-height: 1.55; }
  .campo { position: relative; margin-bottom: clamp(18px, 2.6vh, 26px); }
  .campo label {
    display: block; margin-bottom: 9px;
    font-size: 16px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
    color: var(--gris);
  }
  .campo input {
    width: 100%;
    padding: 9px 2px 13px;
    font-family: var(--cuerpo); font-size: 19px; color: var(--tinta);
    background: transparent; border: none; border-bottom: 1.5px solid var(--linea);
    outline: none;
  }
  .campo input::placeholder { color: #b6b0a5; }
  .campo .raya {
    position: absolute; left: 0; bottom: 0;
    width: 100%; height: 1.5px; background: var(--marino);
    transform: scaleX(0); transform-origin: left;
    transition: transform .45s cubic-bezier(.16,1,.3,1);
  }
  .campo input:focus ~ .raya { transform: scaleX(1); }
  .campo.token input { font-family: var(--display); font-size: 30px; letter-spacing: .55em; }
  .campo .contador {
    position: absolute; right: 2px; bottom: 15px;
    font-size: 16px; color: var(--gris);
    opacity: 0; transition: opacity .25s;
  }
  .campo.token input:focus ~ .contador,
  .campo.token input:not(:placeholder-shown) ~ .contador { opacity: 1; }
  .nota { margin: -8px 0 24px; font-size: 16px; color: var(--gris); }
  .nota b { color: var(--acento); font-weight: 600; }
  .entrar {
    position: relative; width: 100%; height: 58px;
    font-family: var(--cuerpo); font-size: 17px; font-weight: 600; letter-spacing: .04em;
    color: var(--papel); background: var(--marino);
    border: none; border-radius: 4px; cursor: pointer; overflow: hidden;
    transition: background .3s, transform .2s, box-shadow .3s;
  }
  .entrar span { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 12px; }
  .entrar svg { transition: transform .35s cubic-bezier(.16,1,.3,1); }
  .entrar:hover svg { transform: translateX(6px); }
  .entrar:hover { background: var(--marino-hondo); transform: translateY(-2px); box-shadow: 0 16px 30px -18px rgba(15,28,51,.9); }
  .entrar[data-cargando="1"] span { opacity: 0; }
  .entrar[data-cargando="1"]::after {
    content: '';
    position: absolute; left: 50%; top: 50%;
    width: 20px; height: 20px; margin: -10px 0 0 -10px;
    border: 2px solid rgba(247,244,239,.3); border-top-color: var(--papel);
    border-radius: 50%; animation: girar .7s linear infinite;
  }
  @keyframes girar { to { transform: rotate(360deg); } }
  /* con la columna angosta, el pie se acomoda en dos renglones antes que
     partir el enlace a media palabra */
  .pie {
    margin-top: 24px;
    display: flex; flex-wrap: wrap; justify-content: space-between;
    gap: 8px 14px;
    font-size: 16px; color: var(--gris);
  }
  .pie a { white-space: nowrap; }
  .pie a { color: var(--marino); text-decoration: none; border-bottom: 1px solid rgba(30,51,89,.25); }
  .pie a:hover { border-bottom-color: var(--marino); }
  /* ================== Velo de "ya vamos entrando" ==================
     La sesión tarda unos segundos en abrir. Sin esto la pantalla se quedaba
     igualita y la gente le picaba otra vez al botón. */
  .velo {
    position: fixed; inset: 0; z-index: 50;
    display: flex; align-items: center; justify-content: center;
    padding: 24px;
    background: rgba(15, 28, 51, .72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    opacity: 0; visibility: hidden;
    transition: opacity .25s ease, visibility .25s ease;
  }
  .velo.visible { opacity: 1; visibility: visible; }
  .velo-caja {
    width: min(360px, 100%);
    padding: 34px 30px 30px;
    text-align: center;
    background: var(--papel);
    border-radius: 16px;
    box-shadow: 0 30px 70px -30px rgba(0,0,0,.8);
    transform: translateY(10px) scale(.97);
    transition: transform .3s cubic-bezier(.16,1,.3,1);
  }
  .velo.visible .velo-caja { transform: none; }
  .velo-rueda {
    display: block; width: 40px; height: 40px; margin: 0 auto 18px;
    border: 3px solid rgba(30,51,89,.18); border-top-color: var(--marino);
    border-radius: 50%; animation: girar .8s linear infinite;
  }
  .velo-titulo {
    margin: 0;
    font-family: var(--display); font-size: 25px; font-weight: 400;
    color: var(--marino);
  }
  .velo-nota {
    margin: 8px 0 0;
    font-size: 16px; line-height: 1.5; color: var(--gris);
  }
  @media (prefers-reduced-motion: reduce) {
    .velo-rueda { animation-duration: 2s; }
    .velo-caja { transition: none; transform: none; }
  }
  .aparece { animation: subir .8s cubic-bezier(.16,1,.3,1) both; }
  .aparece:nth-child(1) { animation-delay: .05s; }
  .aparece:nth-child(2) { animation-delay: .13s; }
  .aparece:nth-child(3) { animation-delay: .21s; }
  .aparece:nth-child(4) { animation-delay: .29s; }
  .aparece:nth-child(5) { animation-delay: .37s; }
  .aparece:nth-child(6) { animation-delay: .45s; }
  @keyframes subir {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: none; }
  }
  /* En pantallas bajas el mosaico se apretuja: se encoge todo un poco. */
  @media (max-height: 820px) {
    .cuadrante { width: 38%; }
    .cuadrante.sup-izq, .cuadrante.sup-der { top: 6%; }
    .cuadrante.inf-izq, .cuadrante.inf-der { bottom: 6%; }
    .nucleo .simbolo-central { width: clamp(78px, 7.5vw, 112px); }
    .nucleo .nombre-central { font-size: clamp(30px, 3.4vw, 44px); }
    .onda { width: 140px; height: 140px; margin: -70px 0 0 -70px; }
  }
  /* En celular no caben las cuatro esquinas: se queda la marca sola. */
  @media (max-width: 980px) {
    .cuadrante, .conectores { display: none; }
  }
  @media (max-width: 980px) {
    body { grid-template-columns: 1fr; }
    .panel { min-height: 46vh; }
    .marca { gap: 16px; }
    .formulario { padding-bottom: 96px; }
  }
  @media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
  }

/* ------------------------------------------------------------------ *
 * Piezas que solo existen en la pantalla de verdad
 * ------------------------------------------------------------------ */

/* Los SVG de las esquinas tomaban su ancho del contenedor de la maqueta. */
.cuadrante svg {
  width: 100%;
  display: block;
  overflow: visible;
}

/* El recado del servidor: contraseña equivocada, token vencido, sesión
   cerrada. Va arriba del saludo, que es lo primero que se lee. */
.recado {
  margin-bottom: 20px;
  padding: 14px 18px;
  border-radius: 8px;
  background: #fdf0e7;
  border: 1px solid #e8c3a6;
  border-left: 4px solid var(--acento);
  animation: subir .6s cubic-bezier(.16,1,.3,1) both;
}

.recado p {
  margin: 0;
  font-size: 16px;
  line-height: 1.5;
  color: #7c3d18;
}

/* ------------------------------------------------------------------ *
 * El radar con las doce sucursales
 * ------------------------------------------------------------------ */

/* El radar no tiene doce plazas prendidas al mismo tiempo: cada una se
   enciende cuando el barrido le pasa por encima y se va apagando atrás, como
   en un radar de verdad. El retraso de cada eco lo reparte el JS según su
   ángulo; el `inherit` de aquí es lo que hace que el anillo y el nombre se
   enciendan EN EL MISMO instante que su punto (si no, todos los nombres
   aparecían juntos). */
.cuadrante .radar .eco {
  animation: contactoRadar 4.6s linear infinite;
}

@keyframes contactoRadar {
  0%        { opacity: 1; transform: scale(1.6); }
  7%        { opacity: 1; transform: scale(1); }
  40%       { opacity: .5; }
  75%, 100% { opacity: .16; transform: scale(1); }
}

.cuadrante .radar .eco::after {
  animation: expandirEco 4.6s ease-out infinite;
  animation-delay: inherit;
}

.cuadrante .radar .eco b {
  opacity: 0;
  animation: pasarBarrido 4.6s linear infinite;
  animation-delay: inherit;
}

@keyframes pasarBarrido {
  0%   { opacity: 1; }
  18%  { opacity: .85; }
  38%  { opacity: 0; }
  100% { opacity: 0; }
}

/* Las de Estados Unidos van en azul frío; las de México, en el ámbar de
   siempre. Así se ve de un golpe que la operación cruza. */
.cuadrante .radar .eco-usa {
  background: #cfe6ff;
  box-shadow: 0 0 10px rgba(130,180,245,.9);
}

.cuadrante .radar .eco-usa b { color: rgba(207,230,255,.9); }

/* En el mapa, la mitad de arriba del punto es el lado gringo del cruce. */
.punto-usa {
  fill: #cfe6ff;
  filter: drop-shadow(0 0 3px rgba(130,180,245,.85));
}

/* ------------------------------------------------------------------ *
 * Las plazas responden al mouse
 * ------------------------------------------------------------------ */

/* El mapa entero no recibe clics (pointer-events: none), pero las plazas sí:
   un hijo puede volver a activarlos aunque el padre los tenga apagados. */
.plaza-mapa {
  pointer-events: auto;
  cursor: pointer;
}

.plaza-mapa .punto-mapa,
.plaza-mapa .punto-usa,
.plaza-mapa text {
  transition: all .25s cubic-bezier(.16, 1, .3, 1);
  transform-origin: center;
  transform-box: fill-box;
}

.plaza-mapa:hover .punto-mapa,
.plaza-mapa.tocada .punto-mapa {
  transform: scale(1.7);
  fill: #ffffff;
  filter: drop-shadow(0 0 9px rgba(255, 210, 150, 1));
}

.plaza-mapa:hover .punto-usa,
.plaza-mapa.tocada .punto-usa {
  transform: scale(1.7);
}

.plaza-mapa:hover text,
.plaza-mapa.tocada text {
  fill: #ffffff;
  font-weight: 600;
  font-size: 12px;
}

/* El halo se detiene y se abre: deja de latir mientras el mouse está encima,
   para que no compita con el resalte. */
.plaza-mapa:hover .halo-mapa {
  animation-play-state: paused;
  fill: rgba(255, 214, 150, .45);
  r: 11;
}

/* La onda que sale al hacer clic. Se crea y se borra desde el JS. */
.onda-plaza {
  fill: none;
  stroke: #ffe3b8;
  stroke-width: 1.4;
  transform-origin: center;
  transform-box: fill-box;
  animation: soltarOnda 1.5s cubic-bezier(.2, .7, .3, 1) forwards;
  pointer-events: none;
}

@keyframes soltarOnda {
  from { transform: scale(.3); opacity: .95; stroke-width: 2.4; }
  to   { transform: scale(7); opacity: 0; stroke-width: .5; }
}

@media (prefers-reduced-motion: reduce) {
  .onda-plaza { display: none; }
}


/* ------------------------------------------------------------------ *
 * La ruta se ilumina al tocar su plaza
 * ------------------------------------------------------------------ */

/* El punteado de la ruta se engruesa y aclara mientras dura el resalte. */
.ruta-mapa {
  transition: stroke .3s, stroke-width .3s, filter .3s;
}

.ruta-mapa.encendida {
  stroke: rgba(255, 227, 184, 1);
  stroke-width: 2.2;
  filter: drop-shadow(0 0 5px rgba(255, 200, 130, .85));
}

/* Y la traza vuelve a salir desde el principio, más rápido y más brillante,
   para que se vea de dónde sale y hasta dónde llega la carga. */
.traza-mapa.encendida {
  animation: viajar 2.6s cubic-bezier(.3, 0, .5, 1) 1 both;
  stroke: #fff4e2;
  stroke-width: 3.2;
  filter: drop-shadow(0 0 9px rgba(255, 210, 140, 1));
}
