/* ==========================================================================
   components.css - Kitsotaro
   Botones, superficies, pestanas, barra de navegacion, footer y anillo.
   Mobile first. Hover solo dentro de @media (hover: hover).
   Todos los valores salen de tokens.css.
   ========================================================================== */

/* ---------- Botones ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: 0 var(--sp-5);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.btn-sm {
  padding: 0 var(--sp-4);
  font-size: var(--fs-sm);
  border-radius: var(--r-xs);
}

.btn-p {
  background: var(--p);
  color: var(--on-p);
  box-shadow: var(--sh-p);
}

.btn-a {
  background: var(--a);
  color: var(--on-a);
  box-shadow: var(--sh-a);
}

.btn-s {
  background: var(--surface);
  border-color: var(--line);
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel);
}

.btn-g {
  background: transparent;
  color: var(--ink-2);
}

.btn-glass {
  position: relative;
  min-height: var(--btn-lg);
  padding: 0 var(--sp-6);
  border-radius: var(--r-md);
  border-color: var(--line);
  font-size: var(--fs-base);
  background: var(--glass);
  -webkit-backdrop-filter: blur(var(--blur-btn));
  backdrop-filter: blur(var(--blur-btn));
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel), var(--glass-glow);
}

.btn:active {
  transform: translateY(1px);
}

@media (hover: hover) {
  .btn:hover {
    transform: translateY(-1px);
  }

  .btn-p:hover {
    background: var(--p-hover);
  }

  .btn-a:hover {
    background: var(--a-hover);
  }

  .btn-s:hover,
  .btn-glass:hover {
    box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
  }

  .btn-g:hover {
    background: var(--chip);
    color: var(--ink);
  }
}

/* ---------- Superficies ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel);
}

.glass {
  background: var(--glass);
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(var(--blur-glass)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--blur-glass)) saturate(var(--glass-sat));
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel);
}

.float {
  box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
}

/* Lamina grande de vidrio que contiene tarjetas */
.sheet {
  padding: clamp(var(--sp-5), 4vw, var(--sp-10));
  border: 1px solid var(--line);
  border-radius: var(--r-2xl);
  background: var(--sheet);
  -webkit-backdrop-filter: blur(var(--blur-sheet));
  backdrop-filter: blur(var(--blur-sheet));
  box-shadow: var(--sh-sheet), inset 0 1px 0 var(--bevel);
}

/* ---------- Chips (etiquetas pequenas) ---------- */
.chip-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--chip);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  color: var(--ink);
}

.chip-tag .dot {
  width: var(--sp-2);
  height: var(--sp-2);
  border-radius: 50%;
  background: currentColor;
}

/* ---------- Pestanas con indicador deslizante (.seg) ---------- */
/* Celular: una sola fila con scroll horizontal. Escritorio: fila normal. */
.seg {
  position: relative;
  display: flex;
  flex-wrap: nowrap;
  gap: 2px;
  width: max-content;
  max-width: 100%;
  padding: var(--sp-1);
  border-radius: var(--r-pill);
  background: var(--chip);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--sp-1);
  scrollbar-width: none;
}

.seg::-webkit-scrollbar {
  display: none;
}

/* Desvanecido de cada borde mientras de ese lado quede contenido por ver (lo pone nav.js) */
.seg.has-more {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--fade-edge)), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - var(--fade-edge)), transparent);
}

.seg.has-less {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--fade-edge));
  mask-image: linear-gradient(to right, transparent, #000 var(--fade-edge));
}

.seg.has-less.has-more {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--fade-edge), #000 calc(100% - var(--fade-edge)), transparent);
  mask-image: linear-gradient(to right, transparent, #000 var(--fade-edge), #000 calc(100% - var(--fade-edge)), transparent);
}

/* Arrastre con raton (nav.js): el ajuste a cada pestana espera a que se suelte */
.seg.has-more,
.seg.has-less {
  cursor: grab;
}

.seg.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  -webkit-user-select: none;
  user-select: none;
}

.seg.is-dragging button {
  cursor: grabbing;
}

.seg button {
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  scroll-snap-align: start;
  min-height: var(--tap);
  padding: 0 var(--sp-4);
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1;
  color: var(--ink-2);
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-base) var(--ease-out);
}

.seg button[aria-pressed="true"] {
  color: var(--on-p);
}

/* La ultima pestana se alinea al final para que el scroll llegue al borde */
.seg button:last-child {
  scroll-snap-align: end;
}

/* Sin JS: el activo lleva su propio fondo */
.seg:not(.has-thumb) button[aria-pressed="true"] {
  background: var(--p);
  box-shadow: var(--sh-ind);
}

/* Indicador: nombre unico, no reutilizar en otra parte del sitio */
.seg-thumb {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
  border-radius: var(--r-pill);
  background: var(--p);
  box-shadow: var(--sh-ind);
  pointer-events: none;
  transition:
    transform var(--dur-slow) var(--ease-spring),
    width var(--dur-slow) var(--ease-spring),
    height var(--dur-base) var(--ease-out);
}

@media (min-width: 860px) {
  .seg {
    display: inline-flex;
    flex-wrap: wrap;
    width: auto;
    overflow: visible;
  }

  .seg.has-more,
  .seg.has-less {
    -webkit-mask-image: none;
    mask-image: none;
    cursor: auto;
  }
}

/* ---------- Barra de navegacion en pildora ---------- */
.site-header {
  position: sticky;
  top: calc(env(safe-area-inset-top, 0px) + var(--sp-3));
  z-index: var(--z-nav);
  margin-top: var(--sp-3);
}

.site-nav {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2);
  border-radius: var(--r-pill);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
  color: var(--ink);
  text-decoration: none;
  border-radius: var(--r-pill);
}

.brand-mark {
  flex: none;
  display: grid;
  grid-template: 100% / 100%;        /* celda fija: el alto en % del logo se calcula sobre el circulo */
  place-items: center;
  width: var(--mark-size);
  height: var(--mark-size);
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--logo-bg);
  color: var(--logo-ink);
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel);
}

/* Logo oficial como <img> (dos colores, no sirve la mascara): brand-kitsotaro-negro.svg en tema claro,
   brand-kitsotaro-blanco.svg en tema oscuro. Vertical (640x872): se fija el alto y el ancho sale solo. */
.brand-logo {
  width: auto;
  height: var(--brand-logo);
  object-fit: contain;
}

.brand-text {
  min-width: 0;
}

.brand-text b {
  display: block;
  font-size: var(--fs-base);
  line-height: var(--lh-snug);
}


.nav-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

/* Pildora dentro de la pildora: mismo radio para que el margen se vea parejo.
   En celular el boton de cotizacion se oculta del header. */
.nav-cta {
  display: none;
  border-radius: var(--r-pill);
}

.menu-btn {
  width: var(--tap);
  padding: 0;
  border-radius: 50%;
}

.menu-btn .icon-close,
.site-nav.is-open .menu-btn .icon-menu {
  display: none;
}

.site-nav.is-open .menu-btn .icon-close {
  display: inline-block;
}

/* Panel desplegable (celular) */
.nav-links {
  transform-origin: top center;
  position: absolute;
  top: calc(100% + var(--nav-panel-gap));
  left: 0;
  right: 0;
  display: none;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  /* fondo solido: un desenfoque dentro de la barra (que ya es vidrio) no desenfoca la pagina */
  background: var(--surface-2);
  box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
}

.site-nav.is-open .nav-links {
  display: flex;
  animation: panel-drop var(--dur-base) var(--ease-out) both;
}

/* Cascada: cada enlace cae un poco despues del anterior */
.site-nav.is-open .nav-links a {
  animation: drop-in var(--dur-base) var(--ease-out) both;
}

.site-nav.is-open .nav-links a:nth-child(2) { animation-delay: calc(var(--stagger) * 1); }
.site-nav.is-open .nav-links a:nth-child(3) { animation-delay: calc(var(--stagger) * 2); }
.site-nav.is-open .nav-links a:nth-child(4) { animation-delay: calc(var(--stagger) * 3); }
.site-nav.is-open .nav-links a:nth-child(5) { animation-delay: calc(var(--stagger) * 4); }
.site-nav.is-open .nav-links a:nth-child(6) { animation-delay: calc(var(--stagger) * 5); }

/* Animaciones de desplegables: hacia abajo en celular, lateral en escritorio */
@keyframes panel-drop {
  from {
    opacity: 0;
    transform: translateY(calc(var(--sp-2) * -1)) scaleY(0.96);
  }
}

@keyframes drop-in {
  from {
    opacity: 0;
    transform: translateY(calc(var(--sp-3) * -1));
  }
}

@keyframes slide-in {
  from {
    opacity: 0;
    transform: translateX(calc(var(--sp-6) * -1));
  }
}

.nav-links a {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 var(--sp-4);
  border-radius: var(--r-pill);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--ink-2);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-base) var(--ease-out);
}

.nav-links a[aria-current="page"] {
  font-weight: var(--fw-semibold);
  color: var(--blue-deep);
}

/* Pastilla del enlace activo. Esta escrita en el HTML de cada pagina;
   al cambiar de pagina el navegador la desliza (view-transition-name). */
.nav-pill {
  position: absolute;
  inset: 0;
  z-index: -1;
  border: 1px solid var(--line);
  border-radius: inherit;
  background: var(--surface);
  box-shadow: var(--sh-pill);
  pointer-events: none;
}

/* Durante la transicion: la pastilla va en una capa (1) y los textos de los
   enlaces en otra encima (2), para que la pastilla nunca tape las palabras. */
::view-transition-group(nav-pill) {
  z-index: 1;
  animation-duration: var(--dur-slow);
  animation-timing-function: var(--ease-spring);
}

/* Una sola capsula: sin cruce de la imagen vieja con la nueva (eso creaba
   una "capsula fantasma" que se estiraba al cambiar entre enlaces de distinto
   ancho). La nueva se ajusta al tamano de la capsula en cada momento. */
::view-transition-old(nav-pill) {
  display: none;
}

::view-transition-new(nav-pill) {
  width: 100%;
  height: 100%;
  animation: none;
}

::view-transition-group(nav-links) {
  z-index: 2;
  animation-duration: var(--dur-slow);
}

@media (hover: hover) {
  .nav-links a:hover {
    color: var(--ink);
  }

  .nav-links a[aria-current="page"]:hover {
    color: var(--blue-deep);
  }
}

@media (min-width: 520px) {
  .site-header {
    top: calc(env(safe-area-inset-top, 0px) + var(--sp-4));
    margin-top: var(--sp-5);
  }
}

@media (min-width: 860px) {
  .nav-links {
    position: relative;
    top: auto;
    display: flex;
    flex-direction: row;
    padding: 0;
    border: 0;
    border-radius: var(--r-pill);
    background: none;
    box-shadow: none;
  }

  .nav-links {
    view-transition-name: nav-links;
  }

  .nav-pill {
    view-transition-name: nav-pill;
  }

  .nav-cta {
    display: inline-flex;
  }

  .menu-btn {
    display: none;
  }
}

/* ---------- Footer compacto (lamina de vidrio dentro del contenedor) ---------- */
/* Celular: todo apilado a la izquierda y boton a ancho completo */
.site-footer {
  position: relative;
  margin-block: var(--sp-16) var(--sp-6);
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

/* Luces detras del footer: sin color detras, el vidrio se veria blanco liso */
.site-footer::before {
  content: "";
  position: absolute;
  inset: calc(var(--sp-10) * -1) 0;
  z-index: var(--z-bg);
  pointer-events: none;
  background:
    radial-gradient(40% 70% at 24% 70%, var(--light-1), transparent 70%),
    radial-gradient(36% 66% at 76% 35%, var(--light-2), transparent 70%),
    radial-gradient(30% 60% at 52% 80%, var(--light-3), transparent 70%);
  /* se desvanece hacia las orillas: sin bordes rectos visibles */
  -webkit-mask-image: radial-gradient(closest-side, #000 55%, transparent);
  mask-image: radial-gradient(closest-side, #000 55%, transparent);
}

.footer-card {
  background: var(--sheet-clear);
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
}

.footer-top {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-5);
}

.footer-brand {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.footer-phrase {
  max-width: 46ch;
  font-size: var(--fs-md);
  color: var(--ink-2);
}

.footer-cta {
  width: 100%;
}

.footer-mid {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-links a,
.footer-mail,
.footer-bottom a {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  border-radius: var(--r-xs);
  color: var(--ink-2);
  text-decoration: none;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--ink-3);
}

.footer-bottom a {
  color: var(--ink-3);
}

@media (hover: hover) {
  .footer-links a:hover,
  .footer-mail:hover,
  .footer-bottom a:hover {
    color: var(--link);
  }
}

@media (min-width: 860px) {
  .footer-top,
  .footer-mid {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .footer-cta {
    width: auto;
  }
}

/* ---------- Circulo de icono y anillo giratorio (.fx-ring) ---------- */
.ring {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--ring-size);
  height: var(--ring-size);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--sh-1);
}

button.ring {
  cursor: pointer;
}

/* Efecto opt-in: quitar la clase deja el circulo intacto.
   El degradado es fijo y gira el aro completo con transform (sin repintar):
   en un circulo girar la mascara no cambia su forma. */
.fx-ring {
  position: relative;
}

.fx-ring::before {
  content: "";
  position: absolute;
  inset: -2px;
  padding: var(--ring-w);
  border-radius: inherit;
  pointer-events: none;
  background: conic-gradient(
    var(--ring-1), var(--ring-2), var(--ring-3), var(--ring-1),
    var(--ring-4), var(--ring-5), var(--ring-1)
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  mask-composite: exclude;
}

@media (prefers-reduced-motion: no-preference) {
  .fx-ring::before {
    animation: fx-spin var(--spin-ring) linear infinite;
    will-change: transform;
  }
}

@keyframes fx-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Anillo en una caja que no es circulo: la capa .fx-ring-edge lleva la mascara
   del borde y queda quieta; dentro gira un cuadrado con el degradado que
   cubre la caja en cualquier angulo. Sin .fx-ring la capa no se muestra. */
.fx-ring-edge {
  display: none;
}

.fx-ring > .fx-ring-edge {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 2;
  padding: var(--ring-w);
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  mask-composite: exclude;
}

/* Cuadrado de 120% del ancho centrado en la caja (cubre su diagonal en 16:9);
   margin-top en % se mide sobre el ancho */
.fx-ring-edge::before {
  content: "";
  position: absolute;
  top: 50%;
  left: -10%;
  width: 120%;
  aspect-ratio: 1;
  margin-top: -60%;
  background: conic-gradient(
    var(--ring-1), var(--ring-2), var(--ring-3), var(--ring-1),
    var(--ring-4), var(--ring-5), var(--ring-1)
  );
}

@media (prefers-reduced-motion: no-preference) {
  .fx-ring-edge::before {
    animation: fx-spin var(--spin-ring) linear infinite;
    will-change: transform;
  }
}

/* ---------- Enlace "Saltar al contenido" (visible solo con teclado) ---------- */
.skip-link:focus-visible {
  position: fixed;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: var(--z-modal);
  width: auto;
  height: auto;
  margin: 0;
  padding: 0 var(--sp-5);
  overflow: visible;
  clip: auto;
}

/* ---------- Utilidades de maquetacion: pila, fila y cabecera de pagina ---------- */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

.page-head {
  margin-top: var(--sp-10);
}

/* ---------- Pagina 404 ---------- */
.nf {
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  min-height: 70vh;
  min-height: 70dvh;
  margin-block: var(--sp-8);
  padding-block: var(--sp-10);
  text-align: center;
}

/* Red de lineas finas diagonales, casi imperceptible y desvanecida hacia los bordes */
.nf::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    repeating-linear-gradient(45deg, var(--net-line) 0 1px, transparent 1px var(--sp-16)),
    repeating-linear-gradient(-45deg, var(--net-line) 0 1px, transparent 1px var(--sp-16));
  -webkit-mask-image: radial-gradient(closest-side, #000 40%, transparent);
  mask-image: radial-gradient(closest-side, #000 40%, transparent);
}

/* Circulo de luz suave detras del 404 */
.nf::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 34%;
  z-index: -1;
  width: min(100%, var(--nf-glow-size));
  aspect-ratio: 1;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, var(--halo), transparent 72%);
  pointer-events: none;
}

.nf-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
}

.nf h1 {
  font-size: var(--fs-h2);
  letter-spacing: var(--tracking-h2);
  line-height: var(--lh-snug);
}

.nf .sub {
  margin-inline: auto;
}

/* Celular: botones a ancho completo y apilados */
.nf-actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  width: 100%;
  margin-top: var(--sp-4);
}

@media (min-width: 520px) {
  .nf-actions {
    flex-direction: row;
    justify-content: center;
    width: auto;
  }
}

/* ---------- Efecto glitch del 404 ---------- */
.glitch-wrap {
  position: relative;
  max-width: 100%;
}

.glitch {
  position: relative;
  isolation: isolate;
  margin: 0;
  font-size: var(--fs-404);
  font-weight: var(--fw-black);
  letter-spacing: var(--tracking-h1);
  line-height: 1;
  color: var(--nf-ink);
  user-select: none;
}

/* Capas cian y magenta: ocultas (franja de alto cero) fuera de la rafaga */
.glitch::before,
.glitch::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  z-index: 1;
  clip-path: inset(50% 0 50% 0);
  pointer-events: none;
}

.glitch::before {
  color: var(--glitch-cyan);
}

.glitch::after {
  color: var(--glitch-magenta);
}

/* Franjas finas que aparecen solo durante la rafaga */
.glitch-lines {
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
  background:
    linear-gradient(var(--glitch-cyan), var(--glitch-cyan)) 0 24% / 100% 2px no-repeat,
    linear-gradient(var(--glitch-magenta), var(--glitch-magenta)) 20% 58% / 70% 3px no-repeat,
    linear-gradient(var(--nf-ink), var(--nf-ink)) 60% 80% / 45% 2px no-repeat;
}

@media (prefers-reduced-motion: no-preference) {
  .glitch {
    animation: glitch-base var(--dur-glitch) steps(1, end) infinite;
  }

  .glitch::before {
    animation: glitch-a var(--dur-glitch) steps(1, end) infinite;
  }

  .glitch::after {
    animation: glitch-b var(--dur-glitch) steps(1, end) infinite;
  }

  .glitch-lines {
    animation: glitch-lines var(--dur-glitch) steps(1, end) infinite;
  }
}

/* Quieto: leve desfase cian/magenta fijo detras del texto */
@media (prefers-reduced-motion: reduce) {
  .glitch::before,
  .glitch::after {
    z-index: -1;
    clip-path: none;
  }

  .glitch::before {
    transform: translateX(calc(var(--glitch-shift) * -1));
  }

  .glitch::after {
    transform: translateX(var(--glitch-shift));
  }
}

/* Ciclo de 4 s: quieto hasta el 88 %, rafaga de ~0.3 s (88 % a 96 %) */
@keyframes glitch-base {
  0%, 88%, 96%, 100% { transform: none; }
  90% { transform: translateX(2px) skewX(-4deg); }
  93% { transform: translateX(-3px); }
}

@keyframes glitch-a {
  0%, 88% { clip-path: inset(50% 0 50% 0); transform: none; }
  89% { clip-path: inset(8% 0 72% 0); transform: translateX(-10px); }
  91% { clip-path: inset(58% 0 22% 0); transform: translateX(8px); }
  93% { clip-path: inset(34% 0 48% 0); transform: translateX(-14px); }
  95% { clip-path: inset(78% 0 6% 0); transform: translateX(5px); }
  96%, 100% { clip-path: inset(50% 0 50% 0); transform: none; }
}

@keyframes glitch-b {
  0%, 88% { clip-path: inset(50% 0 50% 0); transform: none; }
  89% { clip-path: inset(66% 0 14% 0); transform: translateX(12px); }
  91% { clip-path: inset(20% 0 64% 0); transform: translateX(-8px); }
  94% { clip-path: inset(44% 0 38% 0); transform: translateX(10px); }
  96%, 100% { clip-path: inset(50% 0 50% 0); transform: none; }
}

@keyframes glitch-lines {
  0%, 88% { opacity: 0; transform: none; }
  89% { opacity: 1; transform: translateX(-12px); }
  92% { opacity: 0.8; transform: translateX(16px); }
  94% { opacity: 1; transform: translateX(-6px); }
  96%, 100% { opacity: 0; transform: none; }
}

/* ---------- Paginas legales (/terminos, /privacidad) ---------- */
.legal .stack {
  gap: var(--sp-3);
}

.legal-intro,
.legal-toc,
.legal-body {
  max-width: var(--measure);
}

.legal-intro {
  margin-top: var(--sp-6);
  color: var(--ink-2);
}

/* Indice de secciones */
.legal-toc {
  margin-top: var(--sp-8);
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}

.legal-toc h2 {
  margin-bottom: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--ink-3);
}

.legal-toc ol {
  display: grid;
  gap: 0 var(--sp-6);
}

.legal-toc a {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  text-decoration: none;
}

@media (hover: hover) {
  .legal-toc a:hover {
    text-decoration: underline;
  }
}

/* Cuerpo del texto */
.legal-body {
  margin-top: var(--sp-10);
}

.legal-body section {
  margin-block: 0 var(--sp-10);
}

.legal-body section:last-child {
  margin-bottom: 0;
}

.legal-body h2 {
  margin-bottom: var(--sp-4);
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-h3);
}

.legal-body p,
.legal-body ol,
.legal-body ul {
  color: var(--ink-2);
}

.legal-body p + p,
.legal-body p + ol,
.legal-body ol + p,
.legal-body p + .legal-note,
.legal-body .legal-note + p {
  margin-top: var(--sp-4);
}

.legal-body ol {
  margin: 0;
  padding-left: var(--sp-6);
}

.legal-body li + li {
  margin-top: var(--sp-3);
}

.legal-body ol.alpha {
  list-style: lower-alpha;
}

.legal-body strong {
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

/* Regla destacada (sin efectos) */
.legal-note {
  padding: var(--sp-4) var(--sp-5);
  border-left: 3px solid var(--a);
  border-radius: var(--r-xs);
  background: var(--chip);
  color: var(--ink);
}

@media (min-width: 860px) {
  .legal-toc ol {
    grid-template-columns: 1fr 1fr;
  }
}

/* ==========================================================================
   FASE 3 - Portafolio: filtros, tarjetas de pieza y reproductor
   ========================================================================== */

/* ---------- Hero del portafolio: texto y leyenda de niveles ---------- */
.page-head .sub strong {
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

.level-legend {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-3);
  margin: 0;
}

.level-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4);
}

.level-card p {
  font-size: var(--fs-md);
  color: var(--ink-2);
}

/* Desplegable: cerrado en celular, abierto en escritorio (lo abre portafolio.js) */
.level-help summary {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--ink-2);
  list-style: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.level-help summary::-webkit-details-marker {
  display: none;
}

.level-help summary .icon {
  --icon-size: var(--icon-sm);
  transition: transform var(--dur-base) var(--ease-out);
}

.level-help[open] summary .icon {
  transform: rotate(180deg);
}

.level-help[open] summary {
  margin-bottom: var(--sp-3);
}

@media (hover: hover) {
  .level-help summary:hover {
    color: var(--ink);
  }
}

/* Nombre del nivel + indicador de 3 barras */
.level-name {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: var(--ink);
}

.level-bars {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  height: var(--sp-4);
}

.level-bars i {
  width: var(--sp-1);
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--blue-ink) 20%, transparent);
}

.level-bars i:nth-child(1) { height: var(--sp-2); }
.level-bars i:nth-child(2) { height: var(--sp-3); }
.level-bars i:nth-child(3) { height: var(--sp-4); }

.level-bars[data-nivel="basico"] i:nth-child(-n+1),
.level-bars[data-nivel="avanzado"] i:nth-child(-n+2),
.level-bars[data-nivel="superior"] i {
  background: var(--blue-ink);
}

@media (prefers-reduced-motion: reduce) {
  .level-help summary .icon {
    transition: none;
  }
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: var(--sp-2);
  min-height: var(--tap);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--link);
  text-decoration: none;
}

.link-arrow .icon {
  --icon-size: var(--icon-sm);
  transition: transform var(--dur-fast) var(--ease-out);
}

@media (hover: hover) {
  .link-arrow:hover .icon {
    transform: translateX(var(--sp-1));
  }
}

/* Al abrir: tarjetas en cascada hacia abajo (celular) o de izquierda a derecha (escritorio) */
.level-help.is-anim .level-card {
  animation: drop-in var(--dur-slow) var(--ease-out) both;
}

.level-help.is-anim .level-card:nth-child(2) { animation-delay: calc(var(--stagger) * 2); }
.level-help.is-anim .level-card:nth-child(3) { animation-delay: calc(var(--stagger) * 4); }

@media (min-width: 860px) {
  .level-legend {
    grid-template-columns: repeat(3, 1fr);
  }

  .level-help.is-anim .level-card {
    animation-name: slide-in;
  }
}

/* ---------- Filtros ---------- */
/* Pegados bajo el header como la barra de /servicios. portafolio.js pone
   .is-stuck: las etiquetas se desvanecen y las barras pasan a vidrio. La
   altura no cambia, asi las tarjetas no saltan. El tope descuenta la primera
   etiqueta: pegada, la barra de Linea queda donde la de /servicios. */
.catalog-filters {
  position: sticky;
  top: calc(var(--svc-nav-top) - var(--filter-lift));
  z-index: calc(var(--z-nav) - 1);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
}

.catalog-filters .filter-label,
.catalog-filters .filter-group,
.catalog-filters .seg {
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    background-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}

/* Pegados: el hueco de las etiquetas deja pasar clics y toques a las tarjetas */
.catalog-filters.is-stuck {
  pointer-events: none;
}

.catalog-filters.is-stuck .filter-label {
  opacity: 0;
}

.catalog-filters.is-stuck .seg {
  pointer-events: auto;
  background: var(--glass);
  -webkit-backdrop-filter: blur(var(--blur-glass)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--blur-glass)) saturate(var(--glass-sat));
  box-shadow: var(--sh-1), inset 0 0 0 1px var(--line), inset 0 1px 0 var(--bevel);
}

/* Celular y tableta: Nivel en barra compacta (la mitad de alto) para que,
   pegada, tape menos. Excepcion a --tap: el minimo de WCAG es 24 px. */
@media (max-width: 859px) {
  /* Pegados: Nivel sube al hueco de su etiqueta, pegado a Linea */
  .catalog-filters.is-stuck .filter-group + .filter-group {
    transform: translateY(calc((var(--filter-lift) + var(--sp-2)) * -1));
  }

  .seg[data-filtro="nivel"] button {
    min-height: var(--tap-sm);
    padding: 0 var(--sp-3);
    font-size: var(--fs-xs);
  }
}

.filter-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
}

.filter-label {
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  font-weight: var(--fw-semibold);
  color: var(--ink-2);
}

.catalog-empty {
  padding: var(--sp-8) 0;
  text-align: center;
}

@media (min-width: 860px) {
  .catalog-filters {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--sp-6);
  }
}

/* ---------- Cuadricula ---------- */
.vgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--grid-min)), 1fr));
  gap: var(--sp-5);
  margin: 0;
  padding: 0;
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.vgrid > li {
  display: flex;
}

.vgrid > li[hidden] {
  display: none;
}

/* Salida al cambiar de filtro (la pone portafolio.js) */
.vgrid.is-out {
  opacity: 0;
  transform: scale(0.985);
}

/* Entrada escalonada */
.vgrid > li.is-in {
  animation: vcard-in var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}

@keyframes vcard-in {
  from {
    opacity: 0;
    transform: translateY(var(--sp-3)) scale(0.98);
  }
}

/* ---------- Tarjeta de pieza (.vcard) ---------- */
.vcard {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-3);
  font: inherit;
  text-align: left;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}

.vcard:active {
  transform: translateY(1px);
}

/* Miniatura hundida: el degradado ocupa el lugar mientras no hay imagen */
.vthumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-md);
  overflow: hidden;
  background: linear-gradient(135deg, var(--video-a), var(--video-b));
  box-shadow: var(--well);
}

.vthumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 90% at 78% 20%, var(--video-glow), transparent 60%);
  pointer-events: none;
}

.vthumb img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.vthumb.has-img img {
  opacity: 1;
}

/* Miniatura vertical: completa, sin recortar, sobre el fondo oscuro */
.vthumb[data-orient="v"] img {
  object-fit: contain;
}

/* Boton de play al centro (la miniatura deja el centro libre) */
.vthumb-ph {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
}

.vthumb-ph .ring,
.viewer-ph .ring {
  background: var(--play-glass);
  color: var(--ctrl-ink);
  -webkit-backdrop-filter: blur(var(--blur-btn));
  backdrop-filter: blur(var(--blur-btn));
}

.dur-badge {
  position: absolute;
  right: var(--sp-2);
  bottom: var(--sp-2);
  z-index: 2;
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-xs);
  background: var(--ctrl-bg);
  color: var(--ctrl-ink);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.vcard-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: 0 var(--sp-1) var(--sp-1);
}

.vcard-title {
  font-size: var(--fs-base);
  font-weight: var(--fw-h3);
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-h3);
}

.vcard-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.vcard .chip-tag {
  font-size: var(--fs-xs);
  color: var(--ink-2);
}

.vcard-ext {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--link);
}

.vcard-ext .icon {
  --icon-size: var(--icon-sm);
}

@media (hover: hover) {
  .vcard:hover {
    transform: translateY(calc(var(--sp-1) * -1));
    box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
  }
}

/* ---------- Reproductor (ventana encima) ---------- */
html.has-modal {
  overflow: hidden;
}

.player-dialog {
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding:
    calc(env(safe-area-inset-top, 0px) + var(--sp-3))
    var(--sp-3)
    calc(env(safe-area-inset-bottom, 0px) + var(--sp-3));
  border: 0;
  background: transparent;
  color: var(--ctrl-ink);
}

.player-dialog[open] {
  display: grid;
  place-items: center;
}

.player-dialog::backdrop {
  background: var(--scrim);
  -webkit-backdrop-filter: blur(var(--blur-scrim));
  backdrop-filter: blur(var(--blur-scrim));
}

.player-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-width: 0;                      /* un titulo largo se corta, no ensancha la ventana */
  max-width: var(--wrap);
}

.player-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
}

.player-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.player-site[hidden] {
  display: none;
}

.player-close {
  flex: none;
  width: var(--tap);
  padding: 0;
}

/* Escenario: toma la proporcion real (--ar) y nunca pasa del alto de la pantalla */
.player-stage {
  --ar: 1.7778;
  position: relative;
  width: min(100%, calc((100vh - var(--player-chrome)) * var(--ar)));
  width: min(100%, calc((100dvh - var(--player-chrome)) * var(--ar)));
  aspect-ratio: var(--ar);
}

.player-dialog[data-mode="video"] .viewer,
.player-dialog[data-mode="image"] .screen {
  display: none;
}

.screen {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--video-a), var(--video-b));
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  container-type: inline-size;
}

.screen.is-full {
  border-radius: 0;
}

.screen video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.screen.is-idle {
  cursor: none;
}

/* Boton grande: visible en pausa; mientras carga, el anillo gira sin icono */
.screen-play {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 2;
  width: var(--play-size);
  height: var(--play-size);
  transform: translate(-50%, -50%);
  background: var(--play-glass);
  color: var(--ctrl-ink);
  -webkit-backdrop-filter: blur(var(--blur-btn));
  backdrop-filter: blur(var(--blur-btn));
}

.screen-play .icon {
  --icon-size: var(--icon-lg);
}

.screen.is-playing .screen-play,
.screen.is-error .screen-play {
  display: none;
}

.screen.is-loading .screen-play {
  display: grid;
  pointer-events: none;
}

.screen.is-loading .screen-play .icon {
  visibility: hidden;
}

.screen-toast {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 4;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-sm);
  background: var(--ctrl-bg);
  color: var(--ctrl-ink);
  font-weight: var(--fw-bold);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.9);
  transition:
    opacity var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
  pointer-events: none;
}

.screen-toast.on {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.screen-msg:not([hidden]) {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: var(--sp-6);
  text-align: center;
  color: var(--ctrl-ink);
}

/* Pantalla final: video en pausa con dos botones de vidrio al centro */
/* Celular (pantalla angosta): uno encima del otro, mismo ancho. Desde 520px: en fila. */
.screen-end {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: none;
  grid-template-columns: max-content;
  align-content: center;
  justify-content: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
}

.screen.is-ended .screen-end {
  display: grid;
}

@container (min-width: 520px) {
  .screen-end {
    grid-template-columns: none;
    grid-auto-flow: column;
  }
}

/* Al terminar: el video se desenfoca, se oscurece un poco y crece apenas */
.screen video {
  transition:
    filter var(--dur-end) var(--ease-inout),
    transform var(--dur-end) var(--ease-inout);
}

.screen.is-ended video {
  filter: blur(var(--end-blur)) brightness(var(--end-dim));
  transform: scale(var(--end-zoom));
}

/* Los botones entran con un zoom suave, uno tras otro */
.screen.is-ended .end-btn {
  animation: end-in var(--dur-end) var(--ease-inout) both;
}

.screen.is-ended .end-btn:nth-child(2) {
  animation-delay: calc(var(--stagger) * 2);
}

@keyframes end-in {
  from {
    opacity: 0;
    transform: scale(0.92);
  }
}

.screen.is-ended .screen-play,
.screen.is-ended .screen-bottom {
  display: none;
}

.end-btn {
  min-height: var(--tap);
  border-color: var(--line);
  background: var(--glass-solid);
  color: var(--ink);
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel);
}

.end-btn[hidden] {
  display: none;
}

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .end-btn {
    background: var(--glass);
    -webkit-backdrop-filter: blur(var(--blur-glass));
    backdrop-filter: blur(var(--blur-glass));
  }
}

@media (hover: hover) {
  .end-btn:hover {
    box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
  }
}

/* Duracion + controles, abajo */
.screen-bottom {
  position: absolute;
  left: var(--sp-2);
  right: var(--sp-2);
  bottom: var(--sp-2);
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-2);
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.screen-bottom .dur-badge {
  position: static;
}

.screen.is-started .screen-dur,
.screen.is-error .screen-bottom {
  display: none;
}

.screen.is-idle .screen-bottom {
  opacity: 0;
  transform: translateY(var(--sp-2));
  pointer-events: none;
}

/* Barra de controles. Compacta: barra arriba y botones abajo */
.ctrl {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  gap: var(--sp-1);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  background: var(--ctrl-bg);
  -webkit-backdrop-filter: blur(var(--blur-glass));
  backdrop-filter: blur(var(--blur-glass));
  color: var(--ctrl-ink);
}

.ctrl-buttons {
  display: flex;
  align-items: center;
  gap: 2px;
}

.ctrl-gap {
  flex: 1;
}

.cb {
  display: grid;
  place-items: center;
  flex: none;
  min-width: var(--tap);
  min-height: var(--tap);
  padding: 0 var(--sp-2);
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--ctrl-ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.cb-text {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

.ctrl-time {
  display: none;
  padding: 0 var(--sp-2);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ctrl-ink-2);
}

.ctrl-bar {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
  min-height: var(--sp-6);
  border-radius: var(--r-xs);
  cursor: pointer;
  touch-action: none;
}

/* Area tactil mas alta que la barra visible */
.ctrl-bar::before {
  content: "";
  position: absolute;
  inset: calc(var(--sp-2) * -1) 0;
}

.ctrl-track {
  position: relative;
  width: 100%;
  height: var(--bar-h);
  overflow: hidden;
  border-radius: var(--r-pill);
  background: var(--ctrl-track);
}

.ctrl-fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--sky), var(--aqua));
  transform: scaleX(0);
  transform-origin: left center;
}

.ctrl-vol {
  display: flex;
  align-items: center;
}

.ctrl-range {
  display: none;
  width: var(--vol-w);
  margin: 0 var(--sp-2) 0 0;
  accent-color: var(--sky);
  cursor: pointer;
}

/* Pantalla ancha (520px o mas): una sola fila, con tiempo */
@container (min-width: 520px) {
  .ctrl {
    flex-direction: row;
    align-items: center;
  }

  .ctrl-buttons {
    display: contents;
  }

  .ctrl-gap {
    display: none;
  }

  .ctrl-time {
    display: inline;
  }

  .ctrl-bar {
    flex: 1;
    order: 1;
    min-height: var(--tap);
    margin: 0 var(--sp-2);
  }

  .ctrl .cb-text,
  .ctrl-vol,
  .ctrl .cb-fs {
    order: 2;
  }
}

@media (hover: hover) and (min-width: 520px) {
  .ctrl-range {
    display: block;
  }
}

@media (hover: hover) {
  .cb:hover {
    background: var(--cb-hover);
  }
}

/* ---------- Vista de imagen (Linea D) ---------- */
.viewer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--video-a), var(--video-b));
}

.viewer-ph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}

.viewer-img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
}

.viewer.has-img .viewer-img {
  opacity: 1;
}

.viewer.has-img .viewer-ph {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .vgrid,
  .vcard,
  .vthumb img,
  .screen-bottom,
  .screen-toast {
    transition: none;
  }

  .vgrid > li.is-in {
    animation: none;
  }
}

/* ==========================================================================
   FASE 4 - Home
   ========================================================================== */

.home {
  position: relative;
}

.home > section,
.home-rest > section {
  margin-block: var(--sp-16);
}

.home > .hero {
  margin-top: var(--sp-6);
}

.section-head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-bottom: var(--sp-6);
}

.grad-text {
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.eyebrow {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--link);
}

/* ---------- Hero (celular: foto arriba, texto abajo) ---------- */
.hero {
  position: relative;
  display: grid;
  gap: var(--sp-8);
  align-items: center;
}

.hero-copy {
  position: relative;
  z-index: var(--z-raised);
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

.hero-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-4);
  margin-top: var(--sp-2);
}

.hero-tools-label {
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

.hero-tools-list {
  display: flex;
  gap: var(--sp-4);
  margin: 0;
}

.hero-tools-list img {
  width: var(--tool-logo);
  height: var(--tool-logo);
  filter: var(--tool-filter);
  opacity: var(--tool-o);
  transition: filter var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}

@media (hover: hover) {
  .hero-tools-list img:hover {
    filter: var(--tool-filter-hover);
    opacity: 1;
  }
}

/* Formas decorativas (opcionales). Capa propia sobre el home: home-scroll.js
   las coloca en las esquinas del hero y, en pantallas horizontales, las lleva
   cruzadas a las esquinas del video. Ocultas hasta tener posicion. */
.home-shapes {
  position: absolute;
  inset: 0;
  z-index: var(--z-raised);
  pointer-events: none;
  /* Capa aislada: sin esto, el flote de las formas (que giran) hacia
     repintar la pagina entera. El margen evita recortar sus puntas. */
  contain: strict;
  overflow-clip-margin: var(--shape-clip);
}

@media (prefers-reduced-motion: no-preference) {
  .home-shapes {
    will-change: transform;
  }
}

.hero-shape {
  position: absolute;
  top: 0;
  left: 0;
  opacity: var(--shape-o);
}

.home-shapes:not(.is-placed) .hero-shape {
  visibility: hidden;
}

.hero-shape-1 {
  width: var(--shape-1);
}

.hero-shape-2 {
  width: var(--shape-2);
}

@media (prefers-reduced-motion: no-preference) {
  .hero-shape {
    animation: hero-float var(--dur-float) var(--ease-inout) infinite alternate;
  }
}

@keyframes hero-float {
  to {
    transform: translateY(calc(var(--sp-3) * -1)) rotate(var(--shape-tilt));
  }
}

/* Columna de la foto: el escenario y las piezas flotantes */
.hero-media {
  position: relative;
  z-index: var(--z-raised);
  order: -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
  max-width: var(--stage-w);
  margin-inline: auto;
  container-type: inline-size;   /* cqw: la burbuja se ubica con el ancho del escenario */
}

.stage {
  position: relative;
  width: 100%;
  aspect-ratio: 400 / 460;
  perspective: var(--perspective);
  border-radius: var(--r-xl);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Sombra azul bajo el marco */
.stage::before {
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  bottom: calc(var(--sp-4) * -1);
  height: var(--sp-10);
  border-radius: 50%;
  background: var(--stage-glow);
  filter: blur(var(--glow-blur));
  z-index: var(--z-bg);
}

.stage-halo {
  position: absolute;
  z-index: var(--z-bg);
  inset: 10% -6% -8%;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--halo), transparent 72%);
  pointer-events: none;
}

.stage-tilt,
.stage-flip {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

/* Parallax (opt-in): hero.js mueve --mx y --my entre -1 y 1 */
.fx-tilt .stage-tilt {
  transform:
    rotateX(calc(var(--my, 0) * var(--tilt-x) * -1))
    rotateY(calc(var(--mx, 0) * var(--tilt-y)));
}

/* Giro (opt-in): sin la clase cambia de cara sin animar */
.fx-flip .stage-flip {
  transition: transform var(--dur-flip) var(--ease-out);
}

.stage.is-flipped .stage-flip {
  transform: rotateY(180deg);
}

/* Enfasis tras un rato sin actividad (hero.js pone .is-nudging): un giro
   parcial de ida y vuelta. Usa "rotate", que se suma al giro principal. */
@media (prefers-reduced-motion: no-preference) {
  .fx-flip.is-nudging .stage-flip {
    animation: stage-nudge var(--dur-nudge) var(--ease-inout);
  }
}

@keyframes stage-nudge {
  0%, 100% {
    rotate: y 0deg;
  }

  45% {
    rotate: y var(--nudge-angle);
  }
}

.stage-face {
  position: absolute;
  inset: 0;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.stage-svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 var(--sp-4) var(--sp-6) var(--frame-drop));
}

.stage-glass {
  stroke: var(--bevel);
  stroke-width: 2;
}

/* La foto se recorta con el marco; con data-cutout la cabeza sale por arriba */
.stage-photo {
  clip-path: url(#hf-frame);
}

.stage[data-cutout] .stage-photo {
  clip-path: url(#hf-pop);
}

.stage-back {
  display: grid;
  place-items: center;
  transform: rotateY(180deg);
}

.stage-coin {
  display: grid;
  grid-template: 100% / 100%;        /* celda fija: el alto en % del logo se calcula sobre el circulo */
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--logo-bg);
  color: var(--logo-ink);
  box-shadow: var(--sh-2), inset 0 2px 0 var(--bevel), var(--glass-glow);
}

.stage-logo {
  width: auto;
  height: var(--coin-logo);
  object-fit: contain;
}

/* Piezas flotantes: se mueven un poco en contra del marco */
.hero-orb-wrap,
.hero-social,
.hero-stat {
  position: absolute;
  z-index: var(--z-chip);
  transform: translate(
    calc(var(--mx, 0) * var(--float-x) * -1),
    calc(var(--my, 0) * var(--float-y) * -1)
  );
  pointer-events: none;
}

/* Burbuja de WhatsApp en la esquina inferior izquierda de la foto (y la flecha
   de redes a su derecha, si hay redes activas). El escenario mide 460/400 de
   alto respecto a su ancho: su borde inferior esta en 115cqw. */
.hero-orb-wrap {
  left: calc(var(--orb-size) * -0.3);
  top: calc(115cqw - var(--orb-size) * 0.8);
  z-index: calc(var(--z-chip) + 1);
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}

.hero-orb {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--orb-size);
  height: var(--orb-size);
  border-radius: 50%;
  color: var(--wa);
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}

.hero-orb .icon {
  width: var(--icon-orb);
  height: var(--icon-orb);
}

@media (hover: hover) {
  .hero-orb {
    transition: transform var(--dur-base) var(--ease-out);
  }

  .hero-orb:hover {
    transform: scale(1.06);
  }
}

/* Flecha indicadora: abre y cierra las redes. Cerrada apunta hacia arriba
   (las redes suben); abierta, hacia abajo (para recogerlas). */
.social-toggle {
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}

.social-arrow {
  display: grid;
  place-items: center;
  width: var(--arrow-size);
  height: var(--arrow-size);
  border-radius: 50%;
  rotate: 180deg;
  transition: rotate var(--dur-slow) var(--ease-spring);
}

.social-arrow .icon {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

.social-toggle[aria-expanded="true"] .social-arrow {
  rotate: 0deg;
}

@media (prefers-reduced-motion: no-preference) {
  .social-arrow {
    animation: arrow-bob var(--dur-bob) var(--ease-inout) infinite alternate;
  }
}

@keyframes arrow-bob {
  to {
    translate: 0 calc(var(--sp-1) * -1);
  }
}

/* WhatsApp: con el logo a la vista se mueve al contorno del circulo
   (hero.js pone el desplazamiento en "translate") */
.hero-orb-wrap {
  transition: translate var(--dur-flip) var(--ease-out);
}

/* Redes: burbujas mas pequenas que WhatsApp. Cerradas, apiladas detras de el;
   abiertas, suben siguiendo el contorno del marco de la foto o, con el logo,
   el contorno del circulo. hero.js pone --x y --y (centro de cada burbuja). */
.hero-social {
  position: absolute;
  inset: 0;
  z-index: var(--z-chip);
  margin: 0;
  pointer-events: none;
}

.hero-social > li {
  position: absolute;
  top: 0;
  left: 0;
}

.social-link {
  position: absolute;
  display: grid;
  place-items: center;
  width: var(--social-size);
  height: var(--social-size);
  margin: calc(var(--social-size) / -2) 0 0 calc(var(--social-size) / -2);
  border-radius: 50%;
  color: var(--ink);
  box-shadow: none;
  translate: var(--x, 0) var(--y, 0);
  pointer-events: auto;
  transition:
    translate var(--dur-slow) var(--ease-spring),
    scale var(--dur-slow) var(--ease-out),
    opacity var(--dur-slow) var(--ease-out);
  transition-delay: calc(var(--i, 0) * var(--stagger));
}

/* La sombra de .float vive en una capa que solo cambia de opacidad: animar
   box-shadow repintaba la burbuja en cada cuadro del recorrido. Con z-index -1
   queda sobre el vidrio y bajo el icono, como la sombra original. */
.social-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
  pointer-events: none;
  transition: opacity var(--dur-slow) var(--ease-out);
  transition-delay: inherit;
}

.social-link .icon {
  width: var(--icon-size);
  height: var(--icon-size);
}

/* Agrupadas: sin sombra (las sombras encimadas hacian una mancha);
   la sombra aparece al desplegarse por el contorno */
.hero-social:not(.is-open) .social-link {
  scale: var(--stack-scale);
  pointer-events: none;
  /* al cerrar, todas vuelven juntas */
  transition-delay: 0s;
}

.hero-social:not(.is-open) .social-link::after {
  opacity: 0;
}

.hero-social:not(.is-ready) .social-link {
  opacity: 0;
  transition: none;
}

.hero-social:not(.is-ready) .social-link::after {
  transition: none;
}

@media (hover: hover) {
  .hero-social.is-open .social-link:hover {
    color: var(--link);
  }
}

.hero-stat {
  display: flex;
  flex-direction: column;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-lg);
  line-height: var(--lh-snug);
}

.hero-stat-1 {
  top: 8%;
  right: 0;
  align-items: center;
  text-align: center;
}

.hero-stat-2 {
  bottom: 14%;
  right: 0;
}

.hero-stat-label {
  font-size: var(--fs-xs);
  color: var(--ink-2);
}

/* Angulo animado del degradado del numero (solo lo usa .hero-stat-num) */
@property --ang {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@keyframes fx-ring-spin {
  to {
    --ang: 360deg;
  }
}

/* Numero con el degradado conico del anillo (.fx-ring), girando.
   Ocupa todo el ancho de la tarjeta para que el centro del giro quede en su borde. */
.hero-stat-num {
  align-self: stretch;
  font-size: var(--fs-stat);
  font-weight: var(--fw-black);
  letter-spacing: var(--tracking-h1);
  line-height: 1;
  background: conic-gradient(
    from var(--ang) at var(--stat-pivot),
    var(--stat-1), var(--stat-2), var(--stat-3), var(--stat-1),
    var(--stat-4), var(--stat-5), var(--stat-1),
    var(--stat-2), var(--stat-3), var(--stat-1),
    var(--stat-4), var(--stat-5), var(--stat-1)
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

@media (prefers-reduced-motion: no-preference) {
  .hero-stat-num {
    animation: fx-ring-spin var(--spin-stat) linear infinite;
  }
}

.hero-stat-big {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  color: var(--ink);
}

/* Linea decorativa tipo grafica (mascara con degradado) */
.hero-stat-line {
  display: block;
  height: var(--stat-line-h);
  margin-top: var(--sp-2);
  background: linear-gradient(90deg, var(--cobalt), var(--sky));
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 34' preserveAspectRatio='none'%3E%3Cpath d='M2 28 L22 24 L40 27 L58 18 L76 21 L96 10 L118 3' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 34' preserveAspectRatio='none'%3E%3Cpath d='M2 28 L22 24 L40 27 L58 18 L76 21 L96 10 L118 3' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

/* ---------- Video de presentacion ---------- */
.intro-btn {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  overflow: hidden;
  background: linear-gradient(135deg, var(--video-a), var(--video-b));
  box-shadow: var(--sh-2);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.intro-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 90% at 78% 20%, var(--video-glow), transparent 60%);
  pointer-events: none;
}

.intro-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.intro-btn.has-img .intro-poster {
  opacity: 1;
}

.intro-play {
  z-index: 1;
  width: var(--play-size);
  height: var(--play-size);
  background: var(--play-glass);
  color: var(--ctrl-ink);
  -webkit-backdrop-filter: blur(var(--blur-btn));
  backdrop-filter: blur(var(--blur-btn));
  transition: transform var(--dur-base) var(--ease-out);
}

.intro-play .icon {
  width: var(--icon-lg);
  height: var(--icon-lg);
}

.intro-label {
  position: absolute;
  left: var(--sp-3);
  bottom: var(--sp-3);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--ctrl-bg);
  color: var(--ctrl-ink);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1;
}

.intro-label .icon {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

@media (hover: hover) {
  .intro-btn:hover .intro-play {
    transform: scale(1.08);
  }
}

/* ---------- Scroll de logos de habilidades ---------- */
.skills-title {
  margin-bottom: var(--sp-4);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  text-align: center;
  color: var(--ink-3);
}

.marquee {
  overflow: hidden;
  padding-block: var(--sp-3);
  -webkit-mask: linear-gradient(90deg, transparent, #000 var(--fade-edge), #000 calc(100% - var(--fade-edge)), transparent);
  mask: linear-gradient(90deg, transparent, #000 var(--fade-edge), #000 calc(100% - var(--fade-edge)), transparent);
}

.marquee-track {
  display: flex;
  width: max-content;
}

/* .marquee delante: le gana a ul[role="list"] de base.css (padding: 0).
   El padding derecho es el hueco entre la ultima pildora y la copia. */
.marquee .marquee-group {
  display: flex;
  gap: var(--sp-3);
  margin: 0;
  padding-right: var(--sp-3);
}

.skill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-4) var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--ink-2);
  white-space: nowrap;
}

.skill img {
  width: var(--logo-size);
  height: var(--logo-size);
}

/* Logos de un solo color (negros): en tema oscuro se aclaran */
.skill .logo-mono {
  filter: var(--logo-mono);
}

@media (prefers-reduced-motion: no-preference) {
  .marquee-track {
    animation: marquee var(--dur-marquee) linear infinite;
  }
}

@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

/* Sin JS y sin movimiento: fila quieta con su propio scroll, sin la copia */
@media (prefers-reduced-motion: reduce) {
  .marquee:not(.is-js) {
    overflow-x: auto;
  }

  .marquee:not(.is-js) .marquee-group[aria-hidden="true"] {
    display: none;
  }
}

/* Con JS (marquee.js): avanza sola y se arrastra con raton o dedo.
   touch-action deja el scroll vertical al navegador. */
.marquee.is-js {
  cursor: grab;
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}

.marquee.is-js .marquee-track {
  animation: none;
  will-change: transform;
}

.marquee.is-dragging {
  cursor: grabbing;
}

.marquee img {
  -webkit-user-drag: none;
  pointer-events: none;
}

/* ---------- Tarjetas de linea de servicio ---------- */
.lines {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--grid-min)), 1fr));
  gap: var(--sp-5);
  margin: 0;
}

.lines > li {
  display: flex;
}

.line-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  width: 100%;
  padding: var(--sp-3);
  transition:
    transform var(--dur-slow) var(--ease-out),
    opacity var(--dur-slow) var(--ease-out),
    filter var(--dur-slow) var(--ease-out),
    box-shadow var(--dur-slow) var(--ease-out);
}

/* Vista previa: poster y loop corto (home.js); el degradado ocupa el lugar
   mientras no hay imagen */
.line-preview {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 16 / 10;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  background: linear-gradient(135deg, var(--surface-2), var(--chip));
  box-shadow: var(--well);
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}

button.line-preview {
  cursor: pointer;
}

.line-poster,
.line-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}

.line-preview.has-img .line-poster,
.line-card.is-playing .line-video {
  opacity: 1;
}

.line-preview .ring {
  z-index: 1;
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-base) var(--ease-out);
}

/* Mientras se mueve el loop, el anillo se aparta */
.line-card.is-playing .line-preview .ring {
  opacity: 0;
}

@media (hover: hover) {
  button.line-preview:hover .ring {
    transform: scale(1.06);
  }
}

.line-txt {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: 0 var(--sp-2);
}

.line-txt p {
  font-size: var(--fs-md);
  color: var(--ink-2);
}

/* Precio y "Ver precios": abajo en las 4 tarjetas (margin-top auto), al
   mismo nivel en escritorio */
.line-foot {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin-top: auto;
  padding: 0 var(--sp-2) var(--sp-1);
}

/* Un solo precio en una linea: "Desde $18" en negrita + unidad en texto normal */
.price {
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  color: var(--ink-3);
}

.price b {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  color: var(--ink);
}

/* Cierre centrado debajo de las tarjetas: Produccion Superior y boton al portafolio */
.lines-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
  text-align: center;
}

.lines-note {
  font-size: var(--fs-md);
  color: var(--ink-2);
}

.lines-note b {
  font-weight: var(--fw-bold);
  color: var(--ink);
  white-space: nowrap;
}

.lines-note a {
  font-weight: var(--fw-semibold);
  color: var(--link);
}

/* Antes del boton, var(--sp-5) en total (el gap ya pone var(--sp-3)) */
.lines-foot .btn-more {
  margin-top: calc(var(--sp-5) - var(--sp-3));
}

/* Boton secundario grande con flecha (cierre de las lineas) */
.btn-more {
  gap: var(--sp-3);
  min-height: var(--btn-lg);
  padding: 0 var(--sp-6);
  border-radius: var(--r-md);
  font-size: var(--fs-base);
}

@media (hover: hover) {
  .btn-more:hover .icon {
    transform: translateX(var(--sp-1));
  }
}

.btn-more .icon {
  transition: transform var(--dur-fast) var(--ease-out);
}

/* Icono con el degradado conico giratorio de los anillos (opt-in).
   Sin la clase, el icono toma el color del texto. */
.fx-spin-icon {
  position: relative;
}

/* El degradado gira en una capa mas grande (cubre las esquinas en cualquier
   angulo); la mascara del icono, que queda quieta, lo recorta */
.fx-spin-icon::before {
  content: "";
  position: absolute;
  inset: -50%;
  background: conic-gradient(
    var(--ink), var(--ring-3), var(--ring-4), var(--ring-2), var(--ink)
  );
}

@media (prefers-reduced-motion: no-preference) {
  .fx-spin-icon::before {
    animation: fx-spin var(--spin-ring) linear infinite;
    will-change: transform;
  }
}

/* Efecto ampliar (opt-in, solo con raton): la tarjeta bajo el cursor crece
   y las demas se atenuan */
@media (hover: hover) {
  .fx-enlarge:has(.line-card:hover) .line-card {
    opacity: var(--enlarge-dim);
    transform: scale(var(--enlarge-shrink));
    filter: saturate(0.8);
  }

  .fx-enlarge:has(.line-card:hover) .line-card:hover {
    z-index: var(--z-raised);
    opacity: 1;
    transform: translateY(var(--enlarge-lift)) scale(var(--enlarge-scale));
    filter: none;
    box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
  }
}

/* ---------- Bloque de contacto (placa metalica) ---------- */
.contact-block {
  position: relative;
  display: grid;
  gap: var(--sp-8);
  align-items: center;
  padding: clamp(var(--sp-6), 5vw, var(--sp-12));
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  overflow: hidden;
  background: linear-gradient(135deg, var(--metal-a), var(--metal-b));
  box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
}

.contact-main {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

/* .contact-block delante: la regla general ul[role="list"] { padding: 0 }
   pesa mas que una sola clase y borraba el espacio junto al separador */
.contact-block .contact-info {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  margin: 0;
  padding: var(--sp-5) 0 0;
  border-top: 1px solid var(--line-strong);
}

.contact-info li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--tap);
  font-size: var(--fs-md);
  color: var(--ink-2);
}

.contact-info a {
  color: var(--ink-2);
}

/* Barrido de luz (opt-in) y grano fino */
.fx-sweep > * {
  position: relative;
  z-index: 1;
}

.fx-sweep::before,
.fx-sweep::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* La luz es fija y se desliza la capa con translate (sin repintar). La capa
   mide el doble del bloque y su centro arranca en el borde izquierdo; el
   bloque recorta lo que sale. 15% de la capa = 30% del bloque (sin animacion). */
.fx-sweep::before {
  right: auto;
  left: -100%;
  width: 200%;
  opacity: var(--sweep-o);
  background: radial-gradient(27.5% 130% at 50% 40%, var(--sweep-light), transparent 62%);
  translate: 15% 0;
}

.fx-sweep::after {
  opacity: var(--grain-o);
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

@media (prefers-reduced-motion: no-preference) {
  .fx-sweep::before {
    animation: sweep-x var(--dur-sweep) var(--ease-inout) infinite alternate;
    will-change: translate;
  }
}

/* -5% a 55% de la capa = -10% a 110% del ancho del bloque */
@keyframes sweep-x {
  from {
    translate: -5% 0;
  }

  to {
    translate: 55% 0;
  }
}

/* ---------- Ampliacion del home ---------- */
/* Celular chico: tarjetas flotantes compactas para no tapar la cara */
@media (max-width: 519px) {
  .hero-stat {
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r-md);
  }

  .hero-stat-1 {
    top: 2%;
    right: calc(var(--sp-2) * -1);
  }

  .hero-stat-2 {
    bottom: 6%;
    right: calc(var(--sp-2) * -1);
  }

  .hero-stat-num {
    font-size: var(--fs-stat-sm);
  }

  .hero-stat-big {
    font-size: var(--fs-md);
  }

  .hero-stat-line {
    height: var(--sp-4);
    margin-top: var(--sp-1);
  }

  .hero-orb-wrap {
    left: calc(var(--orb-size) * -0.15);
  }
}

@media (min-width: 520px) {
  .intro-label {
    left: var(--sp-5);
    bottom: var(--sp-5);
  }
}

@media (min-width: 860px) {
  .home > section,
  .home-rest > section {
    margin-block: var(--section-gap);
  }

  /* Mas aire entre el video y la seccion siguiente */
  .home-rest > section:first-child {
    margin-top: var(--rest-gap);
  }

  .hero {
    grid-template-columns: 1.1fr 0.9fr;
    gap: var(--sp-10);
  }

  .hero-media {
    order: 0;
  }

  .stage-halo {
    inset: 10% -16% -8%;
  }

  .hero-stat-1 {
    right: calc(var(--sp-6) * -1);
  }

  .hero-stat-2 {
    right: calc(var(--sp-8) * -1);
  }

  .contact-block {
    grid-template-columns: 1.2fr 1fr;
  }

  /* Separador vertical a todo el alto de la tarjeta, datos centrados */
  .contact-block .contact-info {
    align-self: stretch;
    justify-content: center;
    padding: 0 0 0 var(--sp-8);
    border-top: 0;
    border-left: 1px solid var(--line-strong);
  }
}

/* ---------- Home por bloques (pantallas horizontales de 860 px o mas) ----------
   Bloque 1: header + hero. Bloque 2: video centrado. Despues, scroll libre.
   El paso entre bloques lo anima home-scroll.js (suave, --dur-block).
   home-scroll.js escribe --to-intro (hero -> video) y --to-rest (video -> resto), de 0 a 1. */
@media (min-width: 860px) and (orientation: landscape) {
  /* El hero ocupa la pantalla */
  .home > .hero {
    min-height: calc(100svh - var(--hero-offset));
  }

  /* El video cabe completo en la pantalla, debajo del header */
  .intro-btn {
    width: min(100%, calc((100svh - var(--intro-chrome)) * 16 / 9));
    margin-inline: auto;
  }

  /* Cambio entre bloques (solo con movimiento) */
  @media (prefers-reduced-motion: no-preference) {
    .home > .hero {
      transform-origin: 50% 100%;
      transform:
        translateY(calc(var(--to-intro, 0) * var(--hero-lift) * -1))
        scale(calc(1 - var(--to-intro, 0) * var(--hero-shrink)));
      opacity: calc(1 - var(--to-intro, 0) * var(--hero-fade));
    }

    .intro-btn {
      transform: scale(calc(var(--intro-from) + var(--to-intro, 0) * (1 - var(--intro-from)) - var(--to-rest, 0) * var(--hero-shrink)));
      opacity: calc(var(--intro-fade) + var(--to-intro, 0) * (1 - var(--intro-fade)) - var(--to-rest, 0) * var(--hero-fade) * 0.6);
    }
  }
}

/* ---------- Entrada del resto del home (home-scroll.js pone .reveal) ---------- */
@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    translate: 0 var(--reveal-y);
    transition:
      opacity var(--dur-reveal) var(--ease-out),
      translate var(--dur-reveal) var(--ease-out);
  }

  .reveal.is-shown {
    opacity: 1;
    translate: none;
  }

  /* Grupos (destacados y lineas): cada tarjeta entra un poco despues */
  .reveal-group > li {
    opacity: 0;
    translate: 0 var(--reveal-y);
    transition:
      opacity var(--dur-reveal) var(--ease-out),
      translate var(--dur-reveal) var(--ease-out);
    transition-delay: calc(var(--i, 0) * var(--stagger) * 2);
  }

  .reveal-group.is-shown > li {
    opacity: 1;
    translate: none;
  }
}

/* ==========================================================================
   CORRECCIONES (2-oct-2026)
   ========================================================================== */

/* Entrada del hero. Las piezas esperan ocultas hasta que home.js pone
   .hero-go en .home: cuando el primer cuadro ya se pinto y la foto esta lista
   (con un limite), asi la animacion nunca corre a escondidas. Se repite en
   cada visita, tambien al volver con Atras. Si el JS falla, hero-wait las
   muestra solas a los --hero-wait-max. Con reduced-motion base.css quita las
   animaciones y todo se ve de inmediato.
   Las piezas de vidrio (WhatsApp, redes, datos) se animan cada una por su
   cuenta con opacity y scale: animar la opacidad de un contenedor rompe el
   desenfoque del vidrio y hace pesado cada cuadro. */
@media (prefers-reduced-motion: no-preference) {
  .home:not(.hero-go) :is(.hero-copy > *, .stage, .hero-media .glass, .home-shapes) {
    animation: hero-wait var(--hero-wait-max);
  }

  .home.hero-go .hero-copy > * {
    animation: hero-in var(--dur-hero-in) var(--ease-out) both;
    animation-delay: calc(var(--hero-in-base) + var(--n, 0) * var(--hero-in-gap));
  }

  .hero-copy > :nth-child(2) { --n: 1; }
  .hero-copy > :nth-child(3) { --n: 2; }
  .hero-copy > :nth-child(4) { --n: 3; }
  .hero-copy > :nth-child(5) { --n: 4; }

  .home.hero-go .stage {
    animation: hero-in var(--dur-hero-in) var(--ease-out) var(--hero-in-media) both;
  }

  .home.hero-go .hero-media .glass {
    animation: hero-pop var(--dur-hero-in) var(--ease-spring) var(--hero-in-pop) both;
  }

  .home.hero-go .home-shapes {
    animation: hero-fade var(--dur-hero-in) var(--ease-out) var(--hero-in-shapes) both;
  }
}

@keyframes hero-wait {
  from,
  to {
    opacity: 0;
  }
}

@keyframes hero-in {
  from {
    opacity: 0;
    translate: 0 var(--hero-in-rise);
  }
}

@keyframes hero-pop {
  from {
    opacity: 0;
    scale: var(--hero-in-scale);
  }
}

@keyframes hero-fade {
  from {
    opacity: 0;
  }
}

/* Tarjetas de linea en pantallas tactiles: la tarjeta mas cercana al centro
   (home.js le pone .is-active) se destaca como con el raton en escritorio. */
@media (hover: none) {
  .fx-enlarge.has-active .line-card {
    opacity: var(--enlarge-dim);
    transform: scale(var(--enlarge-shrink));
    filter: saturate(0.8);
  }

  .fx-enlarge.has-active .line-card.is-active {
    z-index: var(--z-raised);
    opacity: 1;
    transform: scale(1);
    filter: none;
    box-shadow: var(--sh-2), inset 0 1px 0 var(--bevel);
  }
}

/* ==========================================================================
   FASE 5 - Servicios (vista simple) y preguntas frecuentes
   ========================================================================== */

.svc-page > .sheet + .sheet {
  margin-top: var(--sp-8);
}

/* Aviso de precios por pais (siempre visible) */
.svc-region {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-sm);
  background: var(--chip);
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  color: var(--ink-2);
}

/* Icono anclado a la primera linea: su centro coincide con el de esa linea */
.svc-region .icon {
  --icon-size: var(--icon-md);
  margin-top: calc((1em * var(--lh-body) - var(--icon-size)) / 2);
  color: var(--link);
}

.svc-region strong {
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

/* ---------- Navegador de secciones (enlaces de ancla, no filtra) ----------
   Aspecto de los filtros de /portafolio (.seg), comportamiento de enlace.
   Pegajoso bajo el header: sin overflow hidden en sus contenedores. */
html:has(.svc-nav) {
  scroll-behavior: smooth;
}

.svc-nav {
  position: sticky;
  top: var(--svc-nav-top);
  z-index: calc(var(--z-nav) - 1);
  display: flex;
  justify-content: center;
  margin-top: var(--sp-10);
}

/* Mismo espacio header -> cabecera que cabecera -> barra (var(--sp-10)) */
.svc-page > .page-head {
  margin-bottom: 0;
}

.svc-page > .svc-nav + .sheet {
  margin-top: var(--sp-6);
}

/* Pista: vidrio para que se lea encima de las tarjetas al quedar pegada */
.svc-nav-track {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 2px;
  max-width: 100%;
  padding: var(--sp-1);
  border-radius: var(--r-pill);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--sp-1);
  scrollbar-width: none;
}

.svc-nav-track::-webkit-scrollbar {
  display: none;
}

/* Pista de que hay mas a la derecha (la pone servicios.js) */
.svc-nav-track.has-more {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--fade-edge)), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - var(--fade-edge)), transparent);
}

.svc-nav-track a {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  min-height: var(--tap);
  padding: 0 var(--sp-4);
  border-radius: var(--r-pill);
  scroll-snap-align: center;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1;
  color: var(--ink-2);
  white-space: nowrap;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

/* La fila desliza y recortaria el contorno: el foco va por dentro */
.svc-nav-track a:focus-visible {
  outline-offset: calc(var(--sp-1) * -0.5);
}

.svc-nav-track a[aria-current="true"] {
  background: var(--p);
  box-shadow: var(--sh-ind);
  color: var(--on-p);
}

@media (hover: hover) {
  .svc-nav-track a:not([aria-current="true"]):hover {
    color: var(--ink);
  }
}

/* "Preguntas frecuentes" no es un servicio: linea fina antes */
.svc-nav-sep {
  flex-shrink: 0;
  width: 1px;
  height: var(--sp-5);
  margin-inline: var(--sp-1);
  background: var(--line-strong);
}

/* Las anclas no quedan debajo del header ni de la barra pegajosa
   (el html ya reserva el alto del header con scroll-padding-top) */
.svc-line {
  scroll-margin-top: calc(var(--tap) + var(--sp-2) + var(--sp-3));
}


.svc-apart {
  margin-top: var(--sp-2);
  font-size: var(--fs-md);
}

/* ---------- Bloque: miniatura de ejemplo + servicios con su precio ---------- */
.svc-list {
  display: grid;
  gap: var(--sp-4);
  margin: 0;
  padding: 0;
}

@media (min-width: 860px) {
  .svc-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.svc-item {
  display: grid;
  grid-template-columns: var(--svc-thumb) minmax(0, 1fr);
  align-items: start;
  gap: var(--sp-4);
  padding: var(--sp-3);
}

.svc-item.no-media {
  grid-template-columns: 1fr;
  padding-inline: var(--sp-5);
}

.svc-thumb {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  background: none;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.svc-thumb .ring {
  --ring-size: var(--ring-sm);
  transition: transform var(--dur-fast) var(--ease-out);
}

@media (hover: hover) {
  .svc-thumb:hover .ring {
    transform: scale(1.08);
  }
}

.svc-thumb:active .vthumb {
  transform: translateY(1px);
}

.svc-rows {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
}

.svc-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-1) var(--sp-4);
  padding-block: var(--sp-3);
  border-bottom: 1px solid var(--line);
}

.svc-row:first-child {
  padding-top: var(--sp-1);
}

.svc-row:last-child {
  border-bottom: 0;
}

.svc-name {
  flex: 1 1 12em;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
  color: var(--ink);
}

.svc-price {
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.svc-price.is-quote {
  font-weight: var(--fw-semibold);
  color: var(--ink-2);
}

@media (min-width: 520px) {
  .svc-name {
    font-size: var(--fs-base);
  }

  .svc-price {
    font-size: var(--fs-xl);
  }
}

/* Cierre: cotizacion y WhatsApp */
.svc-close {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  text-align: center;
}

.svc-close .hero-cta {
  justify-content: center;
}

/* ---------- Preguntas frecuentes (acordeon con <details>) ---------- */
.faq-group + .faq-group {
  margin-top: var(--sp-8);
}

.faq-group-title {
  margin-bottom: var(--sp-3);
  font-size: var(--fs-h3);
  font-weight: var(--fw-bold);
  color: var(--ink);
}

.faq .faq-list {
  margin: 0;
  padding: var(--sp-1) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--sh-1), inset 0 1px 0 var(--bevel);
}

.faq-list > li + li {
  border-top: 1px solid var(--line);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: var(--tap);
  padding-block: var(--sp-4);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  color: var(--ink);
  list-style: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary .icon {
  --icon-size: var(--icon-sm);
  color: var(--ink-2);
  transition: transform var(--dur-base) var(--ease-out);
}

.faq-item[open] summary .icon {
  transform: rotate(180deg);
}

@media (hover: hover) {
  .faq-item summary:hover {
    color: var(--link);
  }
}

/* La respuesta deja libre la columna del chevron */
.faq-a p {
  max-width: 72ch;
  padding: 0 var(--sp-8) var(--sp-5) 0;
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  color: var(--ink-2);
}

.faq-a a {
  font-weight: var(--fw-semibold);
  color: var(--link);
}

.faq-item[open] .faq-a {
  animation: faq-in var(--dur-base) var(--ease-out);
}

@keyframes faq-in {
  from {
    opacity: 0;
    transform: translateY(calc(var(--sp-1) * -1));
  }
}

/* Inicio: reserva la altura de las 5 preguntas cerradas para que no salte */
.faq[data-faq="home"]:not(.is-ready) {
  min-height: calc(5 * (var(--tap) + var(--sp-8)));
}

.faq-more {
  margin-top: var(--sp-4);
}

@media (min-width: 520px) {
  .faq .faq-list {
    padding-inline: var(--sp-6);
  }
}

/* Escritorio: titulo a la izquierda, acordeon a la derecha (aprovecha el ancho) */
@media (min-width: 860px) {
  .faq .faq-list {
    padding-inline: var(--sp-8);
  }

  .faq-item summary {
    font-size: var(--fs-lg);
  }

  .faq-a p {
    font-size: var(--fs-base);
  }

  .faq-home {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2.2fr);
    grid-template-rows: auto 1fr;
    column-gap: var(--sp-10);
  }

  .faq-home .section-head {
    grid-column: 1;
    grid-row: 1;
    margin-bottom: 0;
  }

  .faq-home .faq-more {
    grid-column: 1;
    grid-row: 2;
    align-self: start;
  }

  .faq-home .faq {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  .faq-group {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2.6fr);
    align-items: start;
    column-gap: var(--sp-10);
  }

  .faq-group-title {
    margin-bottom: 0;
    padding-top: var(--sp-5);
  }
}

@media (prefers-reduced-motion: reduce) {
  .faq-item summary .icon,
  .svc-thumb .ring,
  .svc-nav-track a {
    transition: none;
  }

  .faq-item[open] .faq-a {
    animation: none;
  }
}

/* ---------- /categorias: lista densa para buscadores (Fase 6) ---------- */
.cat-toc {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.cat-toc a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 var(--sp-4);
  border-radius: var(--r-pill);
  background: var(--chip);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--ink);
  text-decoration: none;
}

@media (hover: hover) {
  .cat-toc a:hover {
    background: var(--surface);
    box-shadow: var(--sh-1);
  }
}

.cat-group {
  scroll-margin-top: var(--sp-21);
}

.cat-group h2 {
  margin-bottom: var(--sp-4);
}

.cat-intro {
  max-width: var(--measure);
  margin-bottom: var(--sp-5);
  color: var(--ink-2);
}

/* .cat-group delante: gana a la regla general ul[role="list"] */
.cat-group .cat-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--cat-col)), 1fr));
  gap: var(--sp-3);
}

.cat-list li {
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: inset 0 1px 0 var(--bevel);
}

.cat-list h3 {
  margin-bottom: var(--sp-1);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-h3);
  line-height: var(--lh-snug);
}

.cat-list p {
  font-size: var(--fs-md);
  color: var(--ink-2);
}

.cat-more {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  margin-top: var(--sp-3);
  font-weight: var(--fw-semibold);
  color: var(--link);
  text-decoration: none;
}

.cat-more .icon {
  transition: transform var(--dur-fast) var(--ease-out);
}

@media (hover: hover) {
  .cat-more:hover .icon {
    transform: translateX(var(--sp-1));
  }
}

/* ---------- /contacto: brief que se envia por WhatsApp (Fase 6) ---------- */
.ct-page .contact-block {
  margin-top: var(--sp-10);
}

.brief-head {
  margin-bottom: var(--sp-6);
}

.brief-head h2 {
  margin-bottom: var(--sp-2);
}

.req {
  color: var(--blue-ink);
}

.brief-grid {
  display: grid;
  gap: var(--sp-5);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.field > label,
.field legend {
  padding: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

.field input[type="text"],
.field input[type="date"],
.field select,
.field textarea {
  width: 100%;
  min-height: var(--tap);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--field-line);
  border-radius: var(--r-sm);
  background: var(--field-bg);
  font-size: var(--fs-base);   /* 16px: iPhone no hace zoom al enfocar */
  color: var(--ink);
  transition:
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.field textarea {
  resize: vertical;
  line-height: var(--lh-body);
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: none;
  border-color: var(--focus);
  box-shadow: var(--field-ring);
}

/* Validacion amable: borde y aviso en el azul de acento, sin rojo */
.field [aria-invalid="true"] {
  border-color: var(--a);
}

.field-hint {
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

/* Error: una linea corta en texto, sin cuadro; solo aparece al enviar */
.field-err {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--blue-ink);
}

/* Aviso informativo (fecha cercana): nota con fondo suave e icono */
.field-info {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-xs);
  background: var(--field-note);
  font-weight: var(--fw-medium);
  color: var(--ink);
}

.field-info[hidden] {
  display: none;
}

.field-info .icon {
  flex: none;
  color: var(--blue-ink);
}

/* Enlace "Aun no tengo idea": boton con aspecto de enlace */
.link-btn {
  align-self: flex-start;
  min-height: var(--tap);
  padding: 0;
  border: 0;
  background: none;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--link);
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.link-btn:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* Desplegable "Cuentame un poco mas" */
.brief-more {
  margin-top: var(--sp-6);
}

.brief-more summary {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: var(--tap);
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--field-line);
  border-radius: var(--r-md);
  background: var(--field-bg);
  box-shadow: inset 0 1px 0 var(--bevel);
  list-style: none;
  cursor: pointer;
  transition:
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.brief-more summary::-webkit-details-marker {
  display: none;
}

.brief-more summary:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

@media (hover: hover) {
  .brief-more summary:hover {
    border-color: var(--a);
    box-shadow: var(--sh-1);
  }
}

.brief-more-main {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  flex: 1;
  min-width: 0;
}

.brief-more-title {
  font-weight: var(--fw-bold);
  color: var(--ink);
}

.brief-more-sub {
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

.brief-count {
  flex: none;
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--chip);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--ink-2);
  white-space: nowrap;
}

.brief-count.is-done {
  background: var(--a);
  color: var(--on-a);
}

.brief-more-chev {
  flex: none;
  color: var(--ink-2);
  transition: transform var(--dur-base) var(--ease-out);
}

.brief-more[open] .brief-more-chev {
  transform: rotate(180deg);
}

.brief-more-body {
  padding-top: var(--sp-5);
}

.brief-files {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: var(--fs-md);
  color: var(--ink-2);
}

.brief-files .icon {
  flex: none;
  color: var(--blue-ink);
}

/* Celular: el contador baja debajo del titulo para no apretar el texto */
.brief-more summary {
  flex-wrap: wrap;
}

.brief-more-main {
  flex-basis: calc(100% - var(--icon-size) - var(--sp-3));
}

.brief-count {
  order: 3;
}

@media (min-width: 520px) {
  .brief-more summary {
    flex-wrap: nowrap;
  }

  .brief-more-main {
    flex-basis: auto;
  }

  .brief-count {
    order: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .brief-more-chev,
  .brief-more summary {
    transition: none;
  }
}

/* Selector con chevron propio */
.select {
  position: relative;
}

.select select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--sp-10);
  cursor: pointer;
}

.select .icon {
  position: absolute;
  top: 50%;
  right: var(--sp-4);
  transform: translateY(-50%);
  color: var(--ink-2);
  pointer-events: none;
}

/* Plazo: opciones tipo pastilla */
.plazo .opts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.opt {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: 0 var(--sp-4);
  border: 1px solid var(--field-line);
  border-radius: var(--r-pill);
  background: var(--field-bg);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--ink);
  cursor: pointer;
}

.opt input {
  width: var(--sp-4);
  height: var(--sp-4);
  margin: 0;
  accent-color: var(--a);
}

.opt:has(input:checked) {
  border-color: var(--a);
  box-shadow: inset 0 0 0 1px var(--a);
}

.opt:has(input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.plazo-fecha {
  max-width: var(--cat-col);
  margin-top: var(--sp-2);
}

.plazo-fecha[hidden] {
  display: none;
}

.brief-foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-top: var(--sp-8);
}

@media (min-width: 860px) {
  .brief-grid {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--sp-6);
  }

  .field-wide {
    grid-column: 1 / -1;
  }
}

.btn:disabled {
  opacity: var(--disabled-o);
  cursor: not-allowed;
  box-shadow: none;
}

/* ---------- /dev: Paginas web, KoreStock, cinta y FAQ ---------- */
/* Mismo espaciado entre laminas que en el inicio (.home > section). */
.dev-page > * + * {
  margin-top: var(--sp-16);
}

/* La cinta va pegada al encabezado: menos aire arriba y abajo que entre
   laminas, en todos los anchos */
.dev-page > .skills,
.dev-page > .skills + * {
  margin-top: var(--sp-8);
}

/* Celular: imagen arriba y texto abajo. Desde 860px: lado a lado. */
.dev-case {
  display: grid;
  gap: var(--sp-6);
}

.dev-shot {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: linear-gradient(135deg, var(--ph-a), var(--ph-b));
  box-shadow: var(--well);
}

.dev-shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.dev-shot.has-img img {
  opacity: 1;
}

.dev-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  min-width: 0;
}

.dev-body .chip-tag {
  color: var(--blue-ink);
}

.dev-tagline {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

.dev-desc {
  max-width: var(--measure);
  color: var(--ink-2);
}

/* Etiquetas en 2 lineas: funciones tecnicas y, debajo, tecnologias
   (mas pequenas y en gris, separadas por punto medio) */
.dev-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  max-width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dev-tags .chip-tag {
  font-size: var(--fs-xs);
  color: var(--ink-2);
}

.dev-tags-tech {
  gap: var(--sp-1) 0;
}

.dev-tags-tech li {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--ink-3);
}

.dev-tags-tech li + li::before {
  content: "·";
  padding-inline: var(--sp-2);
}

/* Celular: botones a ancho completo y apilados */
.dev-actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  width: 100%;
  margin-top: var(--sp-2);
}

.dev-actions .btn[hidden] {
  display: none;
}

/* FAQ de /dev: mismo acordeon de /servicios, escrito en el HTML */
.dev-page .faq {
  margin-top: var(--sp-5);
}

@media (min-width: 520px) {
  .dev-actions {
    flex-direction: row;
    width: auto;
  }
}

@media (min-width: 860px) {
  .dev-page > * + * {
    margin-top: var(--section-gap);
  }

  .dev-case {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: var(--sp-10);
  }
}

/* ==========================================================================
   AGREGADO 5-OCT-2026: notas bajo cada grupo y galeria en /servicios
   ========================================================================== */
.svc-note {
  margin-top: var(--sp-5);
  text-align: center;
}

/* Tarjeta con galeria: la imagen arriba, a todo el ancho; los precios abajo */
.svc-item.has-gallery {
  grid-template-columns: minmax(0, 1fr);
}

.svc-gal {
  position: relative;
  padding-top: calc(var(--stack-step) * 2); /* espacio para las tarjetas de atras */
}

.svc-gal-stage {
  position: relative;
  aspect-ratio: var(--gal-ar-h);
}

.svc-gal[data-orient="v"] .svc-gal-stage {
  aspect-ratio: var(--gal-ar-v);
}

.svc-gal-slide {
  position: absolute;
  inset: 0;
}

/* Sin .fx-stack solo se ve la imagen actual */
.svc-gal-slide:not([data-pos="0"]) {
  visibility: hidden;
}

.svc-gal-open {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  background: linear-gradient(135deg, var(--video-a), var(--video-b));
  box-shadow: var(--sh-1);
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
}

.svc-gal-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Captura de celular sobre la de escritorio, libre de la flecha derecha */
.svc-gal-mob {
  position: absolute;
  right: calc(var(--tap) + var(--sp-4));
  bottom: var(--sp-3);
  width: auto;
  height: var(--gal-mob-h);
  border-radius: var(--r-xs);
  box-shadow: var(--sh-2);
}

.svc-gal-btn {
  --ring-size: var(--tap);
  position: absolute;
  top: calc(50% + var(--stack-step));
  z-index: 4;
  transform: translateY(-50%);
  transition: transform var(--dur-fast) var(--ease-out);
}

.svc-gal-btn.is-prev {
  left: var(--sp-2);
}

.svc-gal-btn.is-next {
  right: var(--sp-2);
}

@media (hover: hover) {
  .svc-gal-btn:hover {
    transform: translateY(-50%) scale(1.08);
  }
}

.svc-gal-btn:active {
  transform: translateY(-50%) scale(0.96);
}

/* Efecto opt-in: tarjetas apiladas, las de atras asoman por arriba */
.fx-stack .svc-gal-slide {
  transform-origin: 50% 0;
  transition:
    transform var(--dur-slow) var(--ease-out),
    opacity var(--dur-slow) var(--ease-out);
}

.fx-stack .svc-gal-slide[data-pos="0"] {
  z-index: 3;
}

.fx-stack .svc-gal-slide[data-pos="1"] {
  z-index: 2;
  visibility: visible;
  opacity: var(--stack-o-1);
  transform: translateY(calc(var(--stack-step) * -1)) scale(var(--stack-scale-1));
}

.fx-stack .svc-gal-slide[data-pos="2"] {
  z-index: 1;
  visibility: visible;
  opacity: var(--stack-o-2);
  transform: translateY(calc(var(--stack-step) * -2)) scale(var(--stack-scale-2));
}

/* La que sale se desvanece antes de ocultarse */
.fx-stack .svc-gal-slide[data-pos="hide"] {
  z-index: 0;
  opacity: 0;
  transform: translateY(calc(var(--stack-step) * -2)) scale(var(--stack-scale-2));
  transition:
    transform var(--dur-slow) var(--ease-out),
    opacity var(--dur-slow) var(--ease-out),
    visibility 0s linear var(--dur-slow);
}

@media (prefers-reduced-motion: reduce) {
  .fx-stack .svc-gal-slide[data-pos],
  .svc-gal-btn {
    transition: none;
  }
}

/* ---------- Video de presentacion: borde con el degradado conico (5-oct) ----------
   En lugar de la linea, el anillo de .fx-ring recorre el borde por dentro
   (el boton recorta lo que sale) y queda encima de la miniatura. */
.intro-btn.fx-ring {
  border: 0;
}

/* El anillo gira dentro de .fx-ring-edge, no en el ::before del boton */
.intro-btn.fx-ring::before {
  content: none;
}

/* ---------- Aviso "Correo copiado" (mail.js) ---------- */
.mail-toast {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + var(--sp-6));
  z-index: var(--z-modal);
  max-width: calc(100% - 2 * var(--gutter));
  padding: var(--sp-3) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--glass-solid);
  box-shadow: var(--sh-2);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--ink);
  text-align: center;
  opacity: 0;
  transform: translate(-50%, var(--sp-3));
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
  pointer-events: none;
}

.mail-toast.on {
  opacity: 1;
  transform: translate(-50%, 0);
}
