/* ═══════════════════════════════════════════════════════════════════════════
   VITRINA 3D DE TARIFAS
   ---------------------------------------------------------------------------
   La sección mostraba doce filas de tabla de un tirón. Ordenada, pero es un
   muro de números: nadie compara doce tramos a la vez, cada cliente busca el
   suyo. Ahora los tramos se recorren de a uno en una vitrina en perspectiva y
   la tabla completa queda a un botón de distancia.

   Los datos son LOS MISMOS: el JS lee las filas que ya pintó `renderTarifRows`
   desde /api/public/tarifas. No hay una segunda llamada ni una copia de los
   precios en ningún lado.

   SIN PANEL DE FONDO. Las tarjetas son oscuras y flotan sobre el blanco de la
   página: un rectángulo negro de lado a lado partía la landing en dos y hacía
   que la sección pareciera pegada de otro sitio. Lo que da unidad es la
   sombra que cada tarjeta proyecta sobre el papel, no una caja que las
   encierre.

   Rendimiento: las tarjetas se mueven solo con `transform` y `opacity`. Las
   sombras son `box-shadow` fijas y el vidrio es un gradiente, no un
   `backdrop-filter`: un filtro sobre nueve tarjetas girando en 3D es la forma
   más rápida de tirar los cuadros al piso en un equipo modesto.
   ═══════════════════════════════════════════════════════════════════════════ */

.tf3d{
  --tf3d-tarjeta:#141620;
  --tf3d-tarjeta-alta:#1c1f2b;
  --tf3d-borde:rgba(255,255,255,.1);
  --tf3d-rosa:#f0509a;
  --tf3d-rosa-claro:#ff8ec0;
  --tf3d-rosa-hondo:#c9256f;
  --tf3d-texto:#f6f8fa;
  --tf3d-tenue:rgba(232,237,243,.66);

  position:relative;
  margin:0 auto 30px;
  max-width:1180px;
  /* Sin fondo: la vitrina vive sobre el papel de la página. */
  background:none;
}

/* ── Botón del tarifario completo ─────────────────────────────────────────── */

.tf3dBar{
  display:flex;
  justify-content:center;
  padding:0 20px 22px;
}

.tf3dToggle{
  display:inline-flex;
  align-items:center;
  gap:10px;
  padding:11px 22px;
  border:1px solid rgba(15,36,56,.16);
  border-radius:999px;
  background:#fff;
  color:#0f2438;
  font-family:'Archivo',Sora,Arial,sans-serif;
  font-size:.79rem;
  font-weight:700;
  letter-spacing:.01em;
  cursor:pointer;
  box-shadow:0 6px 18px rgba(15,36,56,.09);
  transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;
}

.tf3dToggle:hover{
  border-color:rgba(240,80,154,.55);
  box-shadow:0 10px 26px rgba(240,80,154,.18);
  transform:translateY(-1px);
}

.tf3dToggle:focus-visible{outline:2px solid var(--tf3d-rosa);outline-offset:3px}

/* Chevron dibujado con bordes: sin SVG ni fuente de iconos que cargar. */
.tf3dToggleIco{
  width:8px;height:8px;
  border-right:2px solid var(--tf3d-rosa);
  border-bottom:2px solid var(--tf3d-rosa);
  transform:translateY(-2px) rotate(45deg);
  transition:transform .25s ease;
}

.tf3dToggle[aria-expanded="true"] .tf3dToggleIco{transform:translateY(1px) rotate(-135deg)}

/* ── Escenario ────────────────────────────────────────────────────────────── */

.tf3dStage{
  position:relative;
  height:540px;
  /* La perspectiva vive en el escenario y no en cada tarjeta: así todas
     comparten el mismo punto de fuga y el conjunto se lee como una vitrina
     y no como nueve elementos girados por su cuenta. */
  perspective:1450px;
  perspective-origin:50% 44%;
  /* El arrastre horizontal no debe robarle el scroll vertical a la página. */
  touch-action:pan-y;
}

.tf3dTrack{
  position:absolute;
  inset:0;
  transform-style:preserve-3d;
  /* CLAVE. El track ocupa todo el escenario y vive en z=0, mientras que las
     tarjetas se hunden con translateZ negativo. Dentro de un contexto
     `preserve-3d` el impacto del puntero lo decide la posición REAL en el
     espacio, no el z-index: el track quedaba delante de las tarjetas y se
     comía todos los clics — pulsar una tarjeta lateral no hacía nada porque
     el clic nunca llegaba a ella.
     Con el track transparente al puntero, cada tarjeta recibe lo suyo. El
     arrastre no se pierde: su disparador es `.tf3dStage`, que envuelve a
     todo y sigue recibiendo el gesto. */
  pointer-events:none;
}

/* Las tarjetas sí reciben el puntero, aunque su contenedor no. */
.tf3dCard{pointer-events:auto}

/* ── Tarjeta ──────────────────────────────────────────────────────────────── */

.tf3dCard{
  position:absolute;
  top:50%;
  left:50%;
  width:366px;
  height:478px;
  margin:-239px 0 0 -183px;   /* centrado sin translate: el translate lo usa el JS */
  display:flex;
  flex-direction:column;
  border-radius:26px;
  background:
    linear-gradient(163deg,var(--tf3d-tarjeta-alta) 0%,var(--tf3d-tarjeta) 46%,#0f111a 100%);
  /* GROSOR. Las sombras hacen distinto trabajo: el canto de luz superior da
     el espesor del borde, la corta despega la tarjeta del papel y la larga la
     sitúa en el espacio. Un `border` plano no da volumen; un canto iluminado
     arriba y oscuro abajo, sí — es como se lee el grosor de una pieza real.
     Ver `.tf3dCard--honda` más abajo: la larga solo se pone donde se nota. */
  overflow:hidden;
  transform-style:preserve-3d;
  backface-visibility:hidden;
  cursor:grab;
  user-select:none;
  /* Sombra base, barata: la profunda se añade solo cerca del frente. */
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    inset 0 -1px 0 rgba(0,0,0,.5),
    0 2px 4px rgba(10,14,24,.3),
    0 14px 26px rgba(10,14,24,.26);
}

/* `will-change` reservado a las tarjetas que de verdad se están moviendo.
   Declararlo en las once dejaba once capas de compositor vivas de forma
   permanente — memoria de GPU ocupada para nada y una vitrina pesada. */
.tf3dCard--enJuego{will-change:transform,opacity}

/* Sombra profunda solo para la del frente y sus dos vecinas. Un difuminado de
   noventa píxeles se compone caro y en las del fondo no se distingue. */
.tf3dCard--honda{
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    inset 0 -1px 0 rgba(0,0,0,.5),
    inset 1px 0 0 rgba(255,255,255,.06),
    inset -1px 0 0 rgba(0,0,0,.4),
    0 2px 4px rgba(10,14,24,.3),
    0 18px 34px rgba(10,14,24,.28),
    0 44px 90px rgba(10,14,24,.3);
}

/* El filo de luz que recorre el borde. Es un gradiente cónico recortado a un
   marco de 1,5 px: da el brillo de canto que tiene el vidrio y que ningún
   `border-color` sólido consigue. */
.tf3dCard::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:5;
  border-radius:26px;
  padding:1.5px;
  background:linear-gradient(150deg,
    rgba(255,255,255,.34) 0%,
    rgba(255,255,255,.05) 26%,
    rgba(240,80,154,.16) 54%,
    rgba(255,255,255,.03) 78%,
    rgba(255,255,255,.2) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask-composite:exclude;
  pointer-events:none;
}

.tf3dCard--activa{
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.2),
    inset 0 -1px 0 rgba(0,0,0,.5),
    0 0 0 1px rgba(240,80,154,.34),
    0 3px 6px rgba(10,14,24,.32),
    0 24px 46px rgba(10,14,24,.34),
    0 56px 110px rgba(10,14,24,.34),
    0 0 78px rgba(240,80,154,.16);
}

.tf3dCard--activa::after{
  background:linear-gradient(150deg,
    rgba(255,255,255,.4) 0%,
    rgba(240,80,154,.5) 24%,
    rgba(255,140,196,.28) 52%,
    rgba(240,80,154,.4) 76%,
    rgba(255,255,255,.3) 100%);
}

.tf3d.tf3d--arrastrando .tf3dCard{cursor:grabbing}

/* Cabecera con foto: es la misma imagen del tarifario, ya optimizada. */
.tf3dCardTop{
  position:relative;
  height:150px;
  padding:15px 17px;
  display:flex;
  flex-direction:column;
  gap:10px;
  background-image:
    linear-gradient(103deg,rgba(12,14,22,.95) 0%,rgba(14,16,26,.78) 40%,rgba(16,18,28,.3) 74%,rgba(20,14,26,.24) 100%),
    url('assets/services/carga-aerea.jpg');
  background-size:cover;
  background-position:center 44%;
  /* Once tarjetas comparten la misma foto: el navegador la decodifica una
     vez, pero conviene que no bloquee el primer pintado de la vitrina. */
  content-visibility:auto;
  contain-intrinsic-size:150px;
}

/* Velo inferior: funde la foto con el cuerpo para que no haya un corte recto. */
.tf3dCardTop::after{
  content:"";
  position:absolute;
  left:0;right:0;bottom:0;
  height:52px;
  background:linear-gradient(to bottom,transparent,var(--tf3d-tarjeta));
  pointer-events:none;
}

.tf3dTopFila{
  position:relative;
  z-index:2;
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:10px;
}

.tf3dChip{
  display:inline-flex;
  align-items:center;
  gap:7px;
  padding:6px 12px;
  border:1px solid rgba(255,255,255,.15);
  border-radius:999px;
  background:rgba(10,12,18,.62);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1);
  color:var(--tf3d-rosa-claro);
  font-size:.68rem;
  font-weight:700;
  letter-spacing:.01em;
  white-space:nowrap;
}

.tf3dChip svg{width:13px;height:13px;flex:none}

.tf3dRuta{
  color:var(--tf3d-texto);
  font-family:'JetBrains Mono',monospace;
  font-size:.68rem;
  font-weight:700;
  letter-spacing:.05em;
}

.tf3dRuta b{color:var(--tf3d-rosa);font-weight:700}

/* Nombre del tramo: es el rótulo grande, como en la referencia. */
.tf3dNombre{
  position:relative;
  z-index:2;
  margin:2px 0 0;
  color:#fff;
  font-family:'Archivo',Sora,Arial,sans-serif;
  font-size:1.85rem;
  font-weight:800;
  line-height:1;
  letter-spacing:-.035em;
  text-shadow:0 3px 14px rgba(0,0,0,.5);
}

/* Rango de peso, con su icono de pesa. */
.tf3dPeso{
  position:relative;
  z-index:2;
  display:inline-flex;
  align-items:center;
  gap:9px;
  color:var(--tf3d-rosa-claro);
  font-family:'Archivo',Sora,Arial,sans-serif;
  font-size:1.02rem;
  font-weight:750;
  letter-spacing:-.01em;
}

.tf3dPesoIco{
  display:grid;
  place-items:center;
  width:29px;height:29px;
  color:var(--tf3d-rosa-claro);
  border:1px solid rgba(240,80,154,.3);
  border-radius:9px;
  background:rgba(240,80,154,.12);
}

.tf3dPesoIco svg{width:15px;height:15px}

.tf3dCardBody{
  flex:1;
  display:flex;
  flex-direction:column;
  gap:10px;
  padding:12px 17px 17px;
}

/* El precio es lo que la persona vino a ver: el bloque más grande de todos. */
.tf3dPrecio{
  display:flex;
  align-items:baseline;
  gap:8px;
  padding:14px 17px;
  border-radius:16px;
  background:linear-gradient(103deg,rgba(240,80,154,.2),rgba(240,80,154,.06) 62%,rgba(240,80,154,.12));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.12),
    inset 0 0 0 1px rgba(240,80,154,.3),
    0 6px 18px rgba(201,37,111,.16);
}

.tf3dPrecioEtq{
  color:var(--tf3d-tenue);
  font-size:.72rem;
  font-weight:600;
}

.tf3dPrecioMoneda{
  color:#fff;
  font-family:'Archivo',Sora,Arial,sans-serif;
  font-size:1.24rem;
  font-weight:800;
  letter-spacing:-.02em;
}

/* El número, en degradado: es el remate de la tarjeta. */
.tf3dPrecioVal{
  font-family:'Archivo',Sora,Arial,sans-serif;
  font-size:2.7rem;
  font-weight:800;
  line-height:.92;
  letter-spacing:-.05em;
  background:linear-gradient(178deg,#ffd9ea 4%,var(--tf3d-rosa) 52%,var(--tf3d-rosa-hondo) 100%);
  -webkit-background-clip:text;
          background-clip:text;
  color:transparent;
  /* El degradado sobre texto no admite sombra propia; el resplandor va detrás
     con un drop-shadow, que sí respeta la silueta de las cifras. */
  filter:drop-shadow(0 3px 12px rgba(240,80,154,.32));
}

.tf3dPrecioUni{
  color:var(--tf3d-tenue);
  font-size:.88rem;
  font-weight:600;
}

/* Los cargos. Dos cajas anchas con icono, como en la referencia: se leen
   mejor que tres columnas apretadas. */
.tf3dDatos{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:9px;
}

.tf3dDato{
  display:flex;
  align-items:center;
  gap:10px;
  padding:10px 12px;
  border-radius:13px;
  background:rgba(255,255,255,.035);
  box-shadow:inset 0 0 0 1px var(--tf3d-borde),inset 0 1px 0 rgba(255,255,255,.06);
}

.tf3dDatoIco{
  display:grid;
  place-items:center;
  width:30px;height:30px;
  flex:none;
  color:var(--tf3d-rosa);
  border-radius:9px;
  background:rgba(240,80,154,.12);
  box-shadow:inset 0 0 0 1px rgba(240,80,154,.24);
}

.tf3dDatoIco svg{width:15px;height:15px}

.tf3dDatoTxt{min-width:0}

.tf3dDatoTxt dt{
  margin:0 0 2px;
  color:var(--tf3d-tenue);
  font-size:.68rem;
  font-weight:600;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}

.tf3dDatoTxt dd{
  margin:0;
  color:var(--tf3d-rosa-claro);
  font-family:'Archivo',Sora,Arial,sans-serif;
  font-size:.92rem;
  font-weight:750;
  letter-spacing:-.01em;
  white-space:nowrap;
}

/* Nota de la categoría, con su sello. */
.tf3dNota{
  display:flex;
  align-items:center;
  gap:11px;
  padding:2px 2px 0;
}

.tf3dNotaIco{
  display:grid;
  place-items:center;
  width:36px;height:36px;
  flex:none;
  color:var(--tf3d-rosa);
  border-radius:50%;
  background:rgba(240,80,154,.1);
  box-shadow:inset 0 0 0 1px rgba(240,80,154,.24);
}

.tf3dNotaIco svg{width:18px;height:18px}

.tf3dNota p{
  margin:0;
  color:var(--tf3d-tenue);
  font-size:.79rem;
  font-weight:500;
  line-height:1.35;
}

.tf3dCta{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:12px;
  margin-top:auto;
  padding:13px 18px 13px 26px;
  border-radius:999px;
  background:linear-gradient(100deg,var(--tf3d-rosa) 0%,#e33a87 52%,var(--tf3d-rosa-hondo) 100%);
  color:#fff;
  font-family:'Archivo',Sora,Arial,sans-serif;
  font-size:.92rem;
  font-weight:750;
  text-decoration:none;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.3),
    0 10px 26px rgba(201,37,111,.36);
  transition:transform .2s ease,box-shadow .2s ease;
}

.tf3dCta:hover{
  transform:translateY(-1px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.34),0 14px 32px rgba(201,37,111,.46);
}

.tf3dCtaFlecha{
  display:grid;
  place-items:center;
  width:30px;height:30px;
  flex:none;
  color:#fff;
  border-radius:50%;
  background:rgba(255,255,255,.16);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.34);
}

.tf3dCtaFlecha svg{width:15px;height:15px}

/* Las tarjetas laterales SÍ reciben clic: pulsarlas es como se las trae al
   frente, y es lo primero que intenta cualquiera al verlas.
   Lo que se desactiva es solo el botón de las que no están al frente — con
   una tarjeta girada y medio tapada, el clic caía en su «Cotizar ahora» en
   vez de centrarla. */
.tf3dCard[aria-hidden="true"] .tf3dCta{pointer-events:none}

/* Y se avisa de que son pulsables. */
.tf3dCard[aria-hidden="true"]{cursor:pointer}

/* ── Reflejo en el suelo ──────────────────────────────────────────────────── */

/* Sin panel de fondo, lo que asienta la vitrina sobre el papel es esta
   sombra elíptica bajo la tarjeta del frente. */
.tf3dPiso{
  position:absolute;
  left:50%;
  bottom:28px;
  width:420px;
  height:34px;
  margin-left:-210px;
  border-radius:50%;
  background:radial-gradient(ellipse at center,rgba(24,20,38,.26),rgba(24,20,38,.1) 46%,transparent 72%);
  pointer-events:none;
}

/* ── Flechas y puntos ─────────────────────────────────────────────────────── */

.tf3dArrow{
  position:absolute;
  top:50%;
  z-index:40;
  width:46px;height:46px;
  margin-top:-23px;
  border:1px solid rgba(15,36,56,.14);
  border-radius:50%;
  background:#fff;
  box-shadow:0 8px 22px rgba(15,36,56,.14);
  cursor:pointer;
  transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;
}

.tf3dArrow:hover{
  border-color:rgba(240,80,154,.5);
  box-shadow:0 12px 28px rgba(240,80,154,.24);
  transform:scale(1.05);
}

.tf3dArrow:focus-visible{outline:2px solid var(--tf3d-rosa);outline-offset:3px}
.tf3dArrow--prev{left:10px}
.tf3dArrow--next{right:10px}

.tf3dArrow::before{
  content:"";
  position:absolute;
  top:50%;left:50%;
  width:9px;height:9px;
  border-top:2px solid #0f2438;
  border-left:2px solid #0f2438;
}

.tf3dArrow--prev::before{transform:translate(-30%,-50%) rotate(-45deg)}
.tf3dArrow--next::before{transform:translate(-70%,-50%) rotate(135deg)}

.tf3dDots{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:7px;
  padding:6px 20px 0;
}

.tf3dDot{
  width:8px;height:8px;
  padding:0;
  border:0;
  border-radius:50%;
  background:rgba(15,36,56,.2);
  cursor:pointer;
  transition:background .2s ease,width .2s ease;
}

.tf3dDot[aria-selected="true"]{
  width:24px;
  border-radius:999px;
  background:linear-gradient(90deg,var(--tf3d-rosa),var(--tf3d-rosa-hondo));
}

.tf3dDot:focus-visible{outline:2px solid var(--tf3d-rosa);outline-offset:2px}

/* ── El tarifario completo, plegado ───────────────────────────────────────── */

/* Solo se pliega si el JS llegó a marcarlo: sin JS la tabla se ve entera,
   que es la única fuente de las tarifas cuando no hay vitrina. */
.tf3d-plegado{display:none}

/* ── Pantallas chicas ─────────────────────────────────────────────────────── */

@media(max-width:900px){
  .tf3dStage{height:520px;perspective:1120px}
  .tf3dCard{width:320px;height:466px;margin:-233px 0 0 -160px}
  .tf3dNombre{font-size:1.62rem}
  .tf3dPrecioVal{font-size:2.4rem}
  .tf3dPiso{width:360px;margin-left:-180px}
}

@media(max-width:640px){
  .tf3d{margin-bottom:20px}
  .tf3dStage{height:492px;perspective:880px}
  .tf3dCard{width:280px;height:446px;margin:-223px 0 0 -140px;border-radius:22px}
  .tf3dCard::after{border-radius:22px}
  .tf3dCardTop{height:134px;padding:13px 14px}
  .tf3dCardBody{padding:11px 14px 14px;gap:9px}
  .tf3dNombre{font-size:1.44rem}
  .tf3dPeso{font-size:.92rem}
  .tf3dPrecioVal{font-size:2.1rem}
  .tf3dPrecio{padding:12px 14px}
  .tf3dDatoTxt dd{font-size:.84rem}
  .tf3dNota p{font-size:.73rem}
  .tf3dCta{font-size:.84rem;padding:12px 14px 12px 20px}
  .tf3dArrow{width:40px;height:40px;margin-top:-20px}
  .tf3dArrow--prev{left:2px}
  .tf3dArrow--next{right:2px}
  .tf3dToggle{font-size:.73rem;padding:10px 17px}
  .tf3dPiso{width:290px;margin-left:-145px;bottom:22px}
}

@media (prefers-reduced-motion: reduce){
  .tf3dCard,.tf3dCta,.tf3dToggle,.tf3dArrow{transition:none}
}

/* ════════════════════════════════════════════════════════════════════════════
   RECORTE LATERAL DE LA VITRINA
   ----------------------------------------------------------------------------
   El coverflow coloca las tarjetas vecinas fuera del escenario a propósito: esa
   fuga hacia los lados es lo que da la sensación de profundidad. Pero nada las
   recortaba, así que en un móvil de 360 px el documento llegaba a medir 2.872 px
   de ancho y la página entera se desplazaba en horizontal.

   Se recorta en el escenario, que es el marco natural de la vitrina.

   `clip` y no `hidden` por una razón concreta: `overflow-x:hidden` obliga al eje
   vertical a `auto` y crea un contenedor de scroll —cortaría las sombras de las
   tarjetas y rompería cualquier `position:sticky` de más arriba—. `clip` recorta
   sin crear ese contexto, así que el eje Y sigue siendo `visible` de verdad.
   ════════════════════════════════════════════════════════════════════════════ */
.tf3dStage{
  overflow-x:clip;
  /* El recorte va justo en el borde: sin margen las sombras laterales de la
     tarjeta central se cortarían en seco. */
  overflow-clip-margin:24px;
}
