/* ==========================================================================
   NANO — Componentes
   Piezas reutilizables: hero, botones, tarjetas, tabla, formulario, galería.
   Depende de: tokens.css, base.css, layout.css
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero de apertura (splash)
   Capas, de atrás hacia delante:
     0  canvas del campo vectorial
     1  marquesina de logotipos tenues
     2  viñeta radial que oscurece los bordes
     3  logotipo central
     4  franja de cierre que funde con el fondo de la página
   -------------------------------------------------------------------------- */

.hero-splash {
  position: relative;
  height: 100vh;
  min-height: 520px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--ink);
}

.hero-splash__canvas {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.hero-splash__band {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  overflow: hidden;
  /* Es decoración: no debe robarle el clic al lienzo que tiene debajo,
     o la onda expansiva del campo vectorial nunca llega a dispararse. */
  pointer-events: none;
  animation: nano-hero-fade 1.6s ease both;
}

.hero-splash__vignette {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(
    circle at 50% 52%,
    rgb(14 14 16 / 0.1) 0%,
    rgb(14 14 16 / 0.7) 68%,
    var(--ink) 100%
  );
}

.hero-splash__mark {
  position: relative;
  z-index: 3;
  width: clamp(150px, 40vw, 580px);
  height: auto;
  display: block;
  /* Ocupa el centro del hero: sin esto deja una zona muerta al clic. */
  pointer-events: none;
  animation: nano-hero-in 3s var(--ease-out) both;
}

/* Franja de cierre: funde el hero con el fondo de la página. Va por encima
   de todas las capas, incluido el logotipo. */
.hero-splash__fade {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 4;
  height: 90px;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--ink));
}

/* Flecha de bajada al titular. Va sobre la franja de cierre, centrada. */
.hero-splash__arrow {
  position: absolute;
  z-index: 5;
  inset-block-end: clamp(20px, 3vw, 34px);
  inset-inline-start: 50%;
  translate: -50% 0;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: solid var(--line-btn);
  border-width: 0px 0px 3px 3px;
  line-height: 1;
  color: var(--text);
  background: rgb(14 14 16 / 0.35);
  transform: rotate(-45deg) skew(10deg, 10deg);
  transition: border-color var(--t-fast);
}

.hero-splash__arrow:hover {
  border-color: var(--bone);
}

/* El vaivén anima `translate` (centrado incluido) para no tocar el `transform`
   que da forma al chevron. */
.hero-splash__arrow {
  animation: nano-arrow-nudge 2.4s var(--ease-out) infinite;
}

/* --------------------------------------------------------------------------
   Marquesina
   El contenido se duplica en el marcado para que el bucle no tenga corte.
   -------------------------------------------------------------------------- */

.marquee {
  overflow: hidden;
  background: var(--ink);
  padding-block: 20px;
  border-block-end: 1px solid var(--line-soft);
}

.marquee__track {
  display: flex;
  width: max-content;
  align-items: center;
  gap: var(--marquee-gap, 56px);
  animation: nano-marquee var(--marquee-speed, 38s) linear infinite;
  will-change: transform;
}

.marquee__item {
  display: flex;
  align-items: center;
  gap: var(--marquee-gap, 56px);
  white-space: nowrap;
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: clamp(18px, 2vw, 30px);
  letter-spacing: -0.02em;
  color: rgb(237 233 225 / 0.42);
}

.marquee__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* Variante de logotipos usada dentro del hero */
.marquee__logo {
  height: 200px;
  width: auto;
  display: block;
  opacity: 0.1;
}

/* --------------------------------------------------------------------------
   Hero editorial (bajo el splash)
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  /* clip y no hidden: hidden convierte al hero en contenedor de scroll, y el
     titular (.reveal-x, animation-timeline: view()) se ataría a ese scroll
     inmóvil en lugar del de la página, quedándose congelado. */
  overflow: clip;
  padding: 120px var(--pad-x) clamp(28px, 4vw, 48px);
  border-block-end: 1px solid var(--line-soft);
}

.hero__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to top,
    var(--ink) 4%,
    rgb(14 14 16 / 0.82) 34%,
    rgb(14 14 16 / 0.30) 76%,
    rgb(14 14 16 / 0.55) 100%
  );
}

.hero__inner {
  position: relative;
  display: grid;
  gap: clamp(28px, 4vw, 52px);
}

.hero__title {
  /* Destino de la flecha del hero: deja sitio al encabezado fijo. */
  scroll-margin-block-start: calc(var(--header-h) + 24px);
  font-family: var(--font-display);
  font-weight: var(--w-bold);
  font-size: var(--fs-hero);
  line-height: 0.86;
  text-wrap: balance;
  max-width: 20ch;
}

.hero__foot {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(20px, 3vw, 48px);
  align-items: end;
  padding-block-start: 26px;
  border-block-start: 1px solid var(--line-mid);
}

/* Indicador "disponibles para proyectos" */
.status {
  display: flex;
  align-items: center;
  gap: 14px;
  color: rgb(237 233 225 / 0.6);
}

.status__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent-ci);
  animation: nano-blink 2.6s infinite;
}

/* --------------------------------------------------------------------------
   Botones y pills
   -------------------------------------------------------------------------- */

.btn {
  display: inline-block;
  border-radius: 100px;
  white-space: nowrap;
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast), transform var(--t-fast);
}

/* Contorno sobre fondo oscuro */
.btn--outline {
  padding: 13px 20px;
  border: 1px solid var(--line-btn);
  background: none;
}

.btn--outline:hover {
  background: var(--bone);
  color: var(--ink);
  border-color: var(--bone);
}

/* Relleno claro — acción principal */
.btn--solid {
  padding: 11px 18px;
  background: var(--bone);
  color: var(--ink);
  border: none;
}

.btn--solid:hover {
  background: var(--accent);
  color: var(--ink);
  transform: translateY(-2px);
}

.btn--submit {
  padding: 16px 22px;
}

/* Pill de filtro / conmutador de vista. El estado activo lo marca
   aria-pressed, no una clase: así el DOM y la accesibilidad coinciden. */
.pill {
  padding: 11px 17px;
  border-radius: 100px;
  white-space: nowrap;
  border: 1px solid var(--line-pill);
  background: none;
  color: var(--text-muted);
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}

.pill:hover {
  border-color: var(--line-btn);
  color: var(--text);
}

/* Activa. Los filtros son botones (aria-pressed); el conmutador de vista
   son enlaces a otra página (aria-current). Mismo aspecto, semántica
   distinta según el elemento sea un control o una navegación. */
.pill[aria-pressed='true'],
.pill[aria-current='page'] {
  background: var(--bone);
  color: var(--ink);
  border-color: var(--bone);
}

.pill__count {
  opacity: 0.5;
}

/* Pill de tema en el formulario — se marca con el acento de identidad */
.pill--topic {
  padding: 10px 14px;
}

.pill--topic[aria-pressed='true'] {
  background: var(--accent);
  color: var(--ink);
  border-color: var(--accent);
}

/* Etiqueta estática (no interactiva) */
.tag {
  border: 1px solid var(--line-pill);
  border-radius: 100px;
  padding: 8px 13px;
  color: var(--text-muted);
}

/* Enlace con subrayado que se tiñe al pasar */
.link-underline {
  padding-block-end: 6px;
  border-block-end: 1px solid rgb(237 233 225 / 0.35);
}

.link-underline:hover {
  border-block-end-color: var(--accent);
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding-block-start: 26px;
  border-block-start: 1px solid var(--line-mid);
}

.toolbar__sep {
  width: 1px;
  height: 22px;
  margin-inline: 8px;
  background: rgb(237 233 225 / 0.18);
}

/* --------------------------------------------------------------------------
   Media
   -------------------------------------------------------------------------- */

.media {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--ratio, 7 / 5);
  background: var(--surface);
}

/* En escritorio la proporción manda hasta tocar el tope de altura. */
@media (min-width: 1001px) {
  .media {
    max-height: 430px;
  }

  /* En el carrusel manda la altura, no el ancho de la ventana: la tarjeta
     mide 400px de alto y el ancho sale de la proporción 7/5, así la imagen
     sigue siendo apaisada. Aquí el número de tarjetas a la vista lo decide
     ese ancho, no --carousel-visible. */
  .carousel .media {
    height: var(--carousel-height);
  }

  /* Selector con .carousel delante para ganar a la regla de ancho por
     ventana, que viene más abajo en el archivo. */
  .carousel .carousel__card {
    width: calc(var(--carousel-height) * 7 / 5);
  }
}

/* Envoltorio que se escala; la imagen queda quieta dentro del recorte */
.media__zoom {
  position: absolute;
  inset: 0;
  transition: transform 0.85s var(--ease-out), filter var(--t-slow);
}

.media__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.img-portrait {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
}

/* --------------------------------------------------------------------------
   Tarjeta de proyecto destacado (portada)
   -------------------------------------------------------------------------- */

/* La ficha queda a la altura de la imagen: .card__meta se superpone sobre
   ella y sale del flujo. */
.card {
  position: relative;
  display: block;
}

.card:hover .media__zoom {
  transform: scale(1.06);
  filter: saturate(1.25) contrast(1.06);
}

/* Barra de acento que crece al pasar el cursor.
   En el original esto dependía de estado en JS que nunca se activaba;
   aquí es CSS puro. */
.card__bar {
  position: absolute;
  inset-inline-start: 0;
  inset-block-end: 0;
  /* Por encima del velo de .card__meta para que el acento no se apague. */
  z-index: 2;
  height: 3px;
  width: 22%;
  background: var(--accent-color, var(--accent));
  transition: width 0.5s var(--ease-out);
}

.card:hover .card__bar {
  width: 100%;
}

/* Ficha sobre el pie de la imagen. El degradado (no un color plano) da
   contraste al texto sin tapar la foto, y deja sitio a la barra de acento. */
.card__meta {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 1;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: clamp(48px, 9vw, 72px) clamp(16px, 1.6vw, 22px) clamp(16px, 1.6vw, 20px);
  background: linear-gradient(
    to top,
    rgb(14 14 16 / 0.92) 0%,
    rgb(14 14 16 / 0.72) 40%,
    rgb(14 14 16 / 0) 100%
  );
  text-shadow: 0 1px 3px rgb(14 14 16 / 0.6);
}

/* Sobre una foto el texto atenuado se pierde; aquí sube un escalón. */
.card__meta .t-dim {
  color: var(--text-body);
}

/* Solo se oculta donde hay hover real: en táctil la ficha queda siempre
   visible. El teclado la revela con :focus-visible. */
@media (hover: hover) {
  .card__meta {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity var(--t-mid) var(--ease-out),
                transform var(--t-mid) var(--ease-out);
  }

  .card:hover .card__meta,
  .card:focus-visible .card__meta {
    opacity: 1;
    transform: none;
  }
}

.card__title {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: clamp(19px, 1.7vw, 25px);
  letter-spacing: -0.02em;
}

/* --------------------------------------------------------------------------
   Carrusel de casos (portada)
   Es un contenedor con scroll horizontal nativo: trackpad, gesto táctil y
   Mayús + rueda funcionan sin más. js/carousel.js le suma el avance
   automático, el arrastre con el ratón y el bucle infinito (la pista lleva el
   grupo de tarjetas dos veces y el scroll salta de una copia a la otra).

   El carrusel se sale del padding de la sección hasta los bordes de la
   ventana, pero la pista arranca alineada con el contenido: en reposo se ven
   las primeras tarjetas completas y la siguiente cortada por la ventana.
   -------------------------------------------------------------------------- */

.carousel {
  /* Tarjetas visibles entre el inicio del contenido y el borde de la ventana.
     La parte decimal es la tarjeta sangrada. */
  --carousel-visible: 3.35;
  /* Alto de tarjeta en escritorio; el ancho se deriva de él (ver más abajo). */
  --carousel-height: 400px;
  --carousel-gap: 2px;
  /* Duración de una vuelta completa del avance automático (la lee el JS). */
  --carousel-speed: 70s;

  container-type: inline-size;
  margin-inline: calc(-1 * var(--pad-x));
  padding-inline: var(--pad-x);
  overflow-x: auto;
  overflow-y: hidden;
  /* Que el gesto horizontal no arrastre la página ni dispare "atrás". */
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

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

/* Con el JS activo se puede arrastrar con el ratón. */
.carousel[data-carousel-ready] {
  cursor: grab;
}

.carousel[data-dragging] {
  cursor: grabbing;
}

/* Durante el arrastre la tarjeta no reacciona al cursor ni se selecciona texto. */
.carousel[data-dragging] .carousel__card {
  pointer-events: none;
  user-select: none;
}

.carousel__track {
  display: flex;
  width: max-content;
}

/* Cada grupo cierra con su propio hueco para que el empalme del bucle
   mantenga la misma separación que el resto. */
.carousel__group {
  display: flex;
  gap: var(--carousel-gap);
  padding-inline-end: var(--carousel-gap);
}

/* 100cqw es el ancho del contenido de la sección; + --pad-x lo lleva hasta
   el borde derecho de la ventana. */
.carousel__card {
  flex: 0 0 auto;
  width: calc(
    (100cqw + var(--pad-x) - (var(--carousel-visible) - 0.35) * var(--carousel-gap))
    / var(--carousel-visible)
  );
  -webkit-user-drag: none;
}

.carousel__card img {
  -webkit-user-drag: none;
}

@media (max-width: 1000px) {
  .carousel { --carousel-visible: 2.35; }
}

@media (max-width: 640px) {
  .carousel { --carousel-visible: 1.35; }
}

/* --------------------------------------------------------------------------
   Tarjeta de proyecto en retícula (portafolio)
   -------------------------------------------------------------------------- */

.work-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: clamp(18px, 2.5vw, 40px);
  padding: 0 var(--pad-x) clamp(72px, 10vw, 140px);
}

.work-card {
  display: grid;
  gap: 20px;
  animation: nano-rise 0.6s var(--ease-out) both;
}

.work-card:hover .media__zoom {
  transform: scale(1.05);
  filter: saturate(1.2);
}

.work-card__badge {
  position: absolute;
  inset-block-start: 14px;
  inset-inline-start: 14px;
  padding: 7px 11px;
  border-radius: 100px;
  background: rgb(14 14 16 / 0.78);
  backdrop-filter: blur(6px);
  color: var(--accent-color, var(--accent));
}

.work-card__body {
  display: grid;
  gap: 10px;
}

.work-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}

.work-card__title {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: clamp(21px, 2vw, 30px);
  letter-spacing: -0.025em;
}

.work-card__blurb {
  margin-block-start: 4px;
  max-width: 52ch;
}

/* --------------------------------------------------------------------------
   Índice de proyectos (vista tabla)
   -------------------------------------------------------------------------- */

.index-table {
  padding: 0 var(--pad-x) clamp(72px, 10vw, 140px);
}

/* Mismas columnas en cabecera y filas: se define una vez y se hereda */
.index-row {
  display: grid;
  grid-template-columns: 44px minmax(0, 2fr) minmax(0, 1.2fr) minmax(0, 1fr) 60px;
  gap: 16px;
}

.index-head {
  padding-block: 12px;
  border-block-end: 1px solid var(--line-strong);
  color: var(--text-ghost);
}

.index-link {
  align-items: baseline;
  padding-block: clamp(16px, 1.8vw, 26px);
  border-block-end: 1px solid var(--line);
  transition: padding-inline-start 0.45s var(--ease-out), background var(--t-mid);
}

.index-link:hover {
  padding-inline-start: 18px;
  background: var(--hover-row);
}

.index-link__title {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: var(--fs-row);
  line-height: 1.05;
  letter-spacing: -0.03em;
  transition: color var(--t-mid);
}

.index-link:hover .index-link__title {
  color: var(--accent-color, var(--accent));
}

.index-link__client {
  font-size: 14.5px;
  color: var(--text-muted);
}

/* Previsualización flotante que sigue al cursor.
   La posición la fija JS; aquí sólo su aspecto. */
.peek {
  position: fixed;
  /* Ancla en el origen del viewport: sin esto el elemento conservaría su
     posición estática (tras el footer) y el translate partiría de ahí. */
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: var(--z-peek);
  width: 300px;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t-fast);
}

.peek[data-visible='true'] {
  opacity: 1;
}

.peek__img {
  width: 100%;
  aspect-ratio: 7 / 5;
  background-color: var(--surface);
  background-size: cover;
  background-position: center;
  border: 1px solid var(--line-strong);
}

.peek__caption {
  padding: 9px 12px;
  background: var(--bone);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Servicios
   -------------------------------------------------------------------------- */

/* Fila de la lista de servicios en portada */
.service-row {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.4fr) auto;
  gap: clamp(16px, 3vw, 48px);
  align-items: start;
  padding-block: clamp(24px, 3vw, 42px);
  border-block-end: 1px solid var(--line-mid);
  transition: padding-inline-start 0.4s var(--ease-out), background 0.4s;
}

.service-row:hover {
  padding-inline-start: 22px;
  background: var(--hover-cell);
}

.service-row__head {
  display: flex;
  align-items: baseline;
  gap: 16px;
}

.service-row__title {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: var(--fs-h4);
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.dot {
  width: var(--dot-size, 10px);
  height: var(--dot-size, 10px);
  border-radius: 50%;
  background: var(--accent-color, var(--accent));
  flex: none;
}

.dot--sm { --dot-size: 9px; }
.dot--lg { --dot-size: 26px; }

/* Cabecera de la ficha de servicio (página interior) */
.service-code {
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--accent-color, var(--accent));
}

/* Entradilla de cada frente de servicio */
.service-lead {
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.6;
  max-width: 48ch;
}

/* Lista numerada de entregables */
.deliverable {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 14px;
  padding-block: 15px;
  border-block-end: 1px solid rgb(237 233 225 / 0.09);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-strong);
}

.deliverable__n {
  padding-block-start: 4px;
  color: var(--accent-color, var(--accent));
}

.list-head {
  padding-block-end: 12px;
  margin-block-end: 4px;
  border-block-end: 1px solid var(--line-mid);
  color: var(--text-faint);
}

/* Caja con borde — "cuándo tiene sentido", resultados */
.note {
  display: grid;
  gap: 12px;
  padding: 22px;
  border: 1px solid var(--line-box);
}

.note--lg {
  gap: 22px;
  padding: clamp(20px, 2.4vw, 30px);
}

.note__text {
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-strong);
}

/* --------------------------------------------------------------------------
   Ficha de caso
   -------------------------------------------------------------------------- */

.case-hero {
  width: 100%;
  height: clamp(280px, 58vh, 660px);
  background-color: var(--surface);
  background-size: cover;
  background-position: center;
}

/* Línea de metadatos sobre el título de caso ("Digital · 2023").
   Hereda el color del --accent-color fijado en .page. */
.case-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: clamp(24px, 3vw, 40px) 0 20px;
  color: var(--accent-color, var(--accent));
}

.case-title {
  font-family: var(--font-display);
  font-weight: var(--w-bold);
  font-size: var(--fs-case);
  line-height: 0.88;
  max-width: 20ch;
}

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 24px;
  margin-block-start: clamp(28px, 4vw, 52px);
  padding-block-start: 24px;
  border-block-start: 1px solid var(--line-mid);
}

.facts__value {
  font-size: 15.5px;
  line-height: 1.45;
  color: var(--text-strong);
}

/* Enlace al proyecto en vivo. Va bajo la ficha técnica, no dentro de ella:
   es una acción, no un dato. */
.case-live {
  margin-block-start: clamp(20px, 2.4vw, 28px);
}

.brief {
  font-size: var(--fs-brief);
  line-height: 1.45;
  letter-spacing: -0.015em;
  color: var(--text);
  text-wrap: pretty;
}

/* Movimientos: qué se hizo, numerado */
.move {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 16px;
  padding-block: 16px;
  border-block-start: 1px solid var(--line);
}

.move__n {
  padding-block-start: 5px;
  color: var(--accent-color, var(--accent));
}

.move__title {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: 19px;
  letter-spacing: -0.02em;
  margin-block-end: 7px;
}

.result {
  display: grid;
  gap: 8px;
  padding-block-start: 18px;
  border-block-start: 1px solid var(--line);
}

.result__value {
  font-family: var(--font-display);
  font-weight: var(--w-bold);
  font-size: var(--fs-result);
  line-height: 1;
  color: var(--accent-color, var(--accent));
}

.result__label {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-muted);
}

.quote {
  display: grid;
  gap: 12px;
  padding-inline-start: 20px;
  border-inline-start: 2px solid var(--accent-color, var(--accent));
}

.quote__text {
  font-family: var(--font-display);
  font-weight: var(--w-light);
  font-size: var(--fs-quote);
  line-height: 1.35;
  letter-spacing: -0.02em;
  text-wrap: pretty;
}

.quote__cite {
  font-style: normal;
  color: var(--text-dim);
}

/* Galería de piezas */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(14px, 2vw, 26px);
}

.gallery__figure {
  display: grid;
  gap: 12px;
}

.gallery__figure .media__zoom {
  position: static;
  width: 100%;
  height: 100%;
  transition: transform 0.9s var(--ease-out);
}

.gallery__figure:hover .media__zoom {
  transform: scale(1.06);
}

.gallery__caption {
  line-height: 1.7;
  color: var(--text-dim);
}

/* Navegación al caso siguiente */
.next-case {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding: var(--pad-y-sm) var(--pad-x);
}

.next-case__link {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: var(--fs-next);
  line-height: 1;
  letter-spacing: -0.035em;
}

/* --------------------------------------------------------------------------
   Estudio
   -------------------------------------------------------------------------- */

.principle {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 16px;
  padding-block: 18px;
  border-block-end: 1px solid var(--line);
}

.principle__n {
  padding-block-start: 5px;
  color: var(--accent);
}

.principle__title {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: 20px;
  letter-spacing: -0.02em;
  margin-block-end: 7px;
}

/* Celda de equipo / método dentro de .grid-hairline */
.cell {
  display: grid;
  gap: 12px;
  align-content: start;
  padding: clamp(20px, 2.4vw, 30px);
  transition: background var(--t-mid);
}

.cell:hover {
  background: var(--surface);
}

.cell--method { gap: 14px; }

.cell__name {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: 22px;
  letter-spacing: -0.025em;
}

.cell__bio {
  font-size: 14px;
  color: rgb(237 233 225 / 0.68);
}

.cell__out {
  padding-block-start: 12px;
  border-block-start: 1px solid var(--line);
  color: var(--text-ghost);
}

/* Celda de cliente */
.client {
  padding: 26px 20px;
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: 16px;
  letter-spacing: -0.01em;
  color: rgb(237 233 225 / 0.62);
  transition: color var(--t-mid), background var(--t-mid);
}

.client:hover {
  color: var(--text);
  background: var(--surface);
}

/* Estadísticas de portada */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 24px;
  padding-block-start: 26px;
  border-block-start: 1px solid var(--line-mid);
}

.stat__value {
  font-family: var(--font-display);
  font-weight: var(--w-bold);
  font-size: calc(var(--fs-stat) * 1.2);
  line-height: 1;
  color: var(--accent-color, var(--accent));
}

/* Cifras en contorno: relleno transparente y trazo del acento de cada dato. */
@supports (-webkit-text-stroke: 0.1px currentColor) {
  .stat__value {
    -webkit-text-stroke: 0.1px var(--accent-color, var(--accent));
    -webkit-text-fill-color: transparent;
  }
}

.stat__label {
  margin-block-start: 10px;
  line-height: 1.6;
  color: var(--text-dim);
}

/* Paso del bloque "Método" en portada */
.method-step__title { font-size: 21px; letter-spacing: -0.02em; }
.method-step__desc  { font-size: 14px; color: rgb(237 233 225 / 0.65); }

/* --------------------------------------------------------------------------
   Formulario de briefing
   -------------------------------------------------------------------------- */

.form-panel {
  border: 1px solid var(--line-box);
  padding: clamp(20px, 3vw, 36px);
}

.form {
  display: grid;
  gap: 22px;
}

.field {
  display: grid;
  gap: 9px;
}

.field--group { gap: 11px; }

.field__label {
  color: var(--text-dim);
}

/* Input de una línea */
.input {
  background: none;
  border: none;
  border-block-end: 1px solid var(--line-input);
  padding: 10px 0;
  font-size: 16px;
  outline: none;
  transition: border-color var(--t-fast);
}

.input:focus {
  border-block-end-color: var(--accent);
}

.textarea {
  background: none;
  border: 1px solid var(--line-pill);
  padding: 13px;
  font-size: 15.5px;
  line-height: 1.55;
  outline: none;
  resize: vertical;
  transition: border-color var(--t-fast);
}

.textarea:focus {
  border-color: var(--accent);
}

.range {
  width: 100%;
  accent-color: var(--accent);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Mensaje de validación. Reserva altura para que el envío no salte. */
.form__error {
  min-height: 14px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--accent);
}

.form__note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
}

/* Confirmación tras enviar */
.form-success {
  display: grid;
  gap: 18px;
  align-content: center;
  min-height: 380px;
}

.form-success__dot {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent-ci);
}

.form-success__title {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  font-size: 30px;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.btn--ghost {
  justify-self: start;
  padding: 12px 18px;
  background: none;
  border: 1px solid var(--line-btn);
}

.btn--ghost:hover {
  background: var(--bone);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Contacto
   -------------------------------------------------------------------------- */

.contact-line {
  display: grid;
  gap: 7px;
}

.contact-line__value {
  font-size: 16px;
}

.contact-lines {
  display: grid;
  gap: 18px;
  padding-block-start: 26px;
  border-block-start: 1px solid var(--line-mid);
}

/* --------------------------------------------------------------------------
   Ficha de caso en dos columnas
   Izquierda: textos y contenidos informativos, con el scroll de la página.
   Derecha: imágenes y multimedia, con scroll propio a la altura de la
   ventana menos el header fijo.
   -------------------------------------------------------------------------- */

.case-split {
  display: grid;
  grid-template-columns: 40vw minmax(0, 1fr);
  align-items: start;
}

/* La columna de texto trae su propio padding horizontal: las secciones que
   viven dentro lo anulan para no duplicarlo. */
.case-split__text {
  min-width: 0;
  padding-inline: var(--pad-x);
}

.case-split__text > .section,
.case-split__text > .next-case {
  padding-inline: 0;
}

/* La columna de media queda pegada bajo el header y hace su propio scroll. */
.case-media {
  position: sticky;
  inset-block-start: var(--header-h);
  height: calc(100svh - var(--header-h));
  overflow-y: auto;
  overscroll-behavior: contain;
  border-inline-start: 1px solid var(--line-soft);
  background: var(--paper);
  /* Sin estilos de scrollbar: cualquier declaración aquí fuerza la barra
     clásica permanente y desactiva la overlay del sistema. */
}

.case-media__list {
  display: grid;
  gap: 0;
}

.case-media__img {
  width: 100%;
  height: auto;
  display: block;
  background: var(--paper);
}

/* Series de piezas: comparten fila, misma proporción, sin recorte.
   --row-n fija cuántas piezas entran en la fila (tres por defecto). */
.case-media__row {
  display: grid;
  grid-template-columns: repeat(var(--row-n, 3), minmax(0, 1fr));
  gap: 0;
}

/* Video incrustado: conserva la proporción del reproductor sin alto fijo. */
.case-media__embed {
  position: relative;
  width: 100%;
  aspect-ratio: 1400 / 795;
  background: var(--paper);
}

.case-media__embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* Las piezas se pueden ampliar: el cursor lo anuncia. */
.case-media__img {
  cursor: zoom-in;
}

/* --------------------------------------------------------------------------
   Visor de piezas (lightbox)
   <dialog> modal: Esc, foco y fondo inerte los resuelve el navegador.
   -------------------------------------------------------------------------- */
.lightbox {
  /* Se anulan los valores propios del user agent para ocupar la ventana. */
  max-width: none;
  max-height: none;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  /* Si la pieza no cabe de alto, el visor mismo hace scroll. */
  overflow: auto;
  overscroll-behavior: contain;
  z-index: var(--z-lightbox);
}

.lightbox[open] {
  display: flex;
  flex-direction: column;
  padding-block: 4svh;
}

.lightbox::backdrop {
  background: rgb(14 14 16 / 0.92);
}

/* Tamaño original, limitado sólo por el ancho: una pieza vertical conserva
   su escala y se recorre con scroll. El margen auto centra sin recortar lo
   que sobresale, cosa que place-items:center sí haría. */
.lightbox__img {
  display: block;
  width: auto;
  height: auto;
  max-width: 92vw;
  /* flex:none impide que el eje principal la comprima para que quepa, que es
     justo lo contrario de lo que queremos en piezas verticales. Los márgenes
     auto centran cuando sobra sitio y valen 0 cuando falta, así nada queda
     recortado fuera del alcance del scroll. */
  flex: none;
  margin: auto;
  background: var(--paper);
  cursor: zoom-out;
}

.lightbox__close {
  position: fixed;
  inset-block-start: 18px;
  inset-inline-end: 18px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  color: var(--text);
  background: #2A2A2F;
  border: 0;
  border-radius: 100px;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}

/* La X son dos rectángulos de esquinas redondeadas, girados ±45°, apilados
   en la misma celda del grid. */
.lightbox__close::before,
.lightbox__close::after {
  content: "";
  grid-area: 1 / 1;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: rotate(45deg);
}

.lightbox__close::after {
  transform: rotate(-45deg);
}

.lightbox__close:hover {
  background: var(--bone);
  color: var(--ink);
}

/* Con el visor abierto la página de fondo no debe desplazarse. */
.has-lightbox,
.has-lightbox body {
  overflow: hidden;
}

/* Sin ancho suficiente para dos columnas, la media vuelve al flujo normal
   y el scroll propio desaparece. */
@media (max-width: 1000px) {
  .case-split {
    grid-template-columns: minmax(0, 1fr);
  }

  .case-media {
    position: static;
    height: auto;
    overflow: visible;
    border-inline-start: 0;
    border-block-start: 1px solid var(--line-soft);
  }
}
