/* ══════════════════════════════════════════════════════════════
   feedback.css — Formulario público de reseñas · DBLinkOn

   DIRECCIÓN

   El color del ISP ocupa la pantalla entera y la tarjeta flota encima.
   La versión anterior era tarjeta blanca sobre fondo casi blanco: no
   había escena, solo superficies al mismo valor. El contraste de
   luminosidad es lo que hace que algo se lea como un objeto.

   JERARQUÍA

   El titular de la pantalla es LA PREGUNTA, no el nombre del negocio.
   Quien abre esto acaba de escanear la calcomanía de su propio proveedor:
   ya sabe con quién habla. El nombre confirma; la pregunta es el trabajo.

   MOVIMIENTO

   Lo lleva motion.js con resortes. Aquí solo van las transiciones de
   color y las entradas que no dependen de gesto. Nunca los dos sistemas
   sobre la misma propiedad: eso produce el corte de velocidad al
   interrumpir un gesto.
   ══════════════════════════════════════════════════════════════ */

:root {
  /* Marca del tenant — feedback.js sobrescribe estas tres. */
  --primary:   #2563eb;
  --accent:    #d97706;
  --tertiary:  #ffffff;

  /* El dorado de las estrellas NO sale de la marca. Es una convención, y
     atarlo al terciario rompe la página cuando ese color es claro:
     intercom.st lo tiene en blanco, lo que daría estrellas invisibles. */
  --star:      #f5b544;

  /* Azul propio de DBLinkOn, tomado del logotipo. Vive aparte de
     --primary porque aquí manda la marca del ISP: DBLinkOn firma. */
  --dblinkon:  #1d8fff;

  --surface:     #ffffff;
  --text:        #14171c;
  --text-soft:   #4d5462;
  --muted:       #7b8494;
  --border:      #e7eaef;
  --border-firm: #ccd2db;
  --danger:      #c81e1e;
  --ok:          #067647;

  --radius:      14px;
  --radius-lg:   22px;
  --radius-xl:   30px;

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s8: 32px; --s10: 40px;

  --display: 'Syne', system-ui, sans-serif;
  --sans:    'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono:    'DM Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --ease: cubic-bezier(0.23, 1, 0.32, 1);
  --dur:  180ms;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  padding: max(var(--s6), env(safe-area-inset-top)) var(--s5)
           max(var(--s6), env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;              /* 16px evita el autozoom de iOS al enfocar */
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  background: #f7f8fa;          /* base bajo el campo, por si el color falla */
}

/* ── CAMPO ──────────────────────────────────────────────────

   Fondo CLARO con rejilla y luces de color, el mismo lenguaje que
   dblinkon.com. La versión anterior era un azul saturado y plano — el
   patrón que más delata diseño generado, y además aplastaba la marca del
   cliente contra un muro del mismo tono.

   Aquí el color aparece como LUZ sobre un lienzo claro, no como relleno.
   Es lo que le da aire y profundidad al mismo tiempo.
   ────────────────────────────────────────────────────────── */
.campo {
  position: fixed;
  inset: 0;
  z-index: -2;
  background: #f7f8fa;
}

/* Rejilla de 44 px, idéntica a la de la landing. Da estructura sin peso:
   se percibe como papel técnico, no como decoración. */
.campo::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(20,23,28,0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(20,23,28,0.035) 1px, transparent 1px);
  background-size: 44px 44px;
  /* Se desvanece hacia abajo para que la rejilla no compita con la
     tarjeta en la zona donde está el contenido. */
  mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,0.35) 55%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,0.35) 55%, transparent 100%);
}

/* Dos luces de la marca del ISP, muy diluidas. Respiran despacio y solo
   animan transform. Aportan el color sin convertirlo en muro. */
.campo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(58% 42% at 18% 8%,
      color-mix(in srgb, var(--primary) 26%, transparent) 0%, transparent 68%),
    radial-gradient(48% 38% at 88% 92%,
      color-mix(in srgb, var(--accent) 18%, transparent) 0%, transparent 68%);
  animation: respirar 24s ease-in-out infinite alternate;
  will-change: transform;
}

@keyframes respirar {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(2%, 1.5%, 0) scale(1.07); }
}

/* ── Utilidades ─────────────────────────────────────────────── */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.hidden { display: none !important; }

:where(button, input, textarea, select, a):focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
  border-radius: 8px;
}
.card :where(button, input, textarea, a):focus-visible {
  outline-color: var(--primary);
  outline-offset: 2px;
}

/* ── Estructura ─────────────────────────────────────────────── */
/* 460 px, no 420. El formulario se veía apretado: cuatro campos, un
   textarea y un botón en 420 px con márgenes es una columna estrecha. */
.container { width: 100%; max-width: 460px; }

.screen {
  display: none;
  flex-direction: column;
  gap: var(--s5);
}
.screen.active { display: flex; }

/* La entrada de pantalla se aplica SOLO al cambiar, no al cargar.

   Al arrancar corrían dos animaciones sobre lo mismo: esta y la
   coreografía escalonada de motion.js. Se veían dos movimientos
   encadenados. La escalonada es la buena, así que esta se reserva para
   las transiciones entre pantallas, que es donde aporta continuidad
   espacial. La clase la pone showScreen(). */
.screen.entrando {
  animation: entra 420ms cubic-bezier(0.32, 0.72, 0, 1) both;
}

@keyframes entra {
  from { opacity: 0; transform: translate3d(16px, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* ── Identidad del negocio ──────────────────────────────────
   Sobre el campo de color, en blanco. Compacta: confirma de quién es la
   página sin robarle protagonismo a la pregunta. */
.identidad {
  display: flex;
  align-items: center;
  gap: var(--s3);
  text-align: left;
  padding-bottom: var(--s5);
  border-bottom: 1px solid var(--border);
}

/* En las pantallas de cierre el contenido va centrado, así que la
   identidad también. */
.card-center .identidad { justify-content: center; width: 100%; }

.logo-wrap {
  width: 42px; height: 42px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  /* Sombra profunda: una pieza sobre color necesita más separación que
     sobre blanco, o se lee pegada al fondo. */
  box-shadow: 0 1px 2px rgba(20,23,28,0.08), 0 6px 16px -8px rgba(20,23,28,0.22);
  border: 1px solid var(--border);
}
.logo-img { max-width: 76%; max-height: 76%; object-fit: contain; }
.logo-img[hidden], .logo-mono[hidden] { display: none; }

.logo-mono {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--primary);
}

/* El nombre NO va en Syne: es una display de titular corto y una razón
   social de cinco palabras se le descontrola. Aquí manda la legibilidad. */
.biz-name {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--biz-size, 15px);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--text-soft);
  max-width: 26ch;
}

/* ── Tarjeta ────────────────────────────────────────────────
   Doble bisel: bandeja translúcida fuera, núcleo sólido dentro con radio
   concéntrico. Sobre color, la bandeja se lee como vidrio esmerilado. */
.card-shell {
  padding: 6px;
  border-radius: var(--radius-xl);
  background: rgba(255,255,255,0.55);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.9);
  box-shadow:
    0 1px 2px rgba(20,23,28,0.04),
    0 18px 40px -20px rgba(20,23,28,0.28),
    0 48px 80px -50px rgba(20,23,28,0.35);
}

.card {
  background: var(--surface);
  border-radius: calc(var(--radius-xl) - 6px);
  padding: var(--s8) var(--s6) var(--s6);
  display: flex;
  flex-direction: column;
  gap: var(--s6);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.9);
}
.card-center {
  text-align: center;
  align-items: center;
  padding: var(--s10) var(--s6);
  gap: var(--s4);
}

.card.is-loading { opacity: 0; }
.card.is-ready   { opacity: 1; }

/* ── La pregunta: titular de la pantalla ────────────────────
   Syne 800. Tracking negativo porque el texto es grande — un espaciado
   pensado para cuerpo pequeño se lee suelto al crecer. */
.pregunta {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(23px, 6.6vw, 28px);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.03em;
  text-wrap: balance;
  text-align: center;
  color: var(--text);
}

/* ── Motivo ─────────────────────────────────────────────────
   Control segmentado, secundario. No compite con la pregunta. */
.motivo {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
  margin: 0;
  padding: 3px;
  border: 0;
  border-radius: 13px;
  background: #f1f3f7;
  box-shadow: inset 0 1px 3px rgba(20,23,28,0.07);
}

.motivo-btn {
  min-height: 46px;
  padding: var(--s2) 2px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.motivo-btn.active {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 1px rgba(20,23,28,0.06), 0 3px 8px -4px rgba(20,23,28,0.18);
}

/* ── Sede en la pantalla de calificación ────────────────────
   Va antes de las estrellas porque la reseña es sobre una oficina
   concreta: elegirla es parte de calificar, no un dato posterior. */
.sede {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

/* ── Calificación: la acción principal ──────────────────────
   Sin panel de fondo ni números bajo cada estrella. Ambas cosas competían
   con lo único que hay que hacer en esta pantalla. */
.rating {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s2);
  padding-top: var(--s1);
}

.rating-box { display: flex; gap: 2px; }

.star-unit {
  width: 58px;
  padding: var(--s2) 0;
  border: 0;
  border-radius: 14px;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  /* Sin transición en transform: el resorte de motion.js maneja la
     pulsación, y dos sistemas sobre la misma propiedad producen el corte
     de velocidad al interrumpir. */
}

.star-unit svg {
  width: 44px; height: 44px;
  fill: #fff;
  stroke: color-mix(in srgb, var(--star) 62%, #d9dee6);
  stroke-width: 1.4;
  stroke-linejoin: round;
  transition: fill 240ms var(--ease), stroke 240ms var(--ease),
              filter 240ms var(--ease);
}

.star-unit.active svg {
  fill: var(--star);
  stroke: color-mix(in srgb, var(--star) 65%, #000);
  filter: drop-shadow(0 4px 10px color-mix(in srgb, var(--star) 50%, transparent));
}

.star-num { display: none; }   /* el número duplicaba lo que ya dice la forma */

/* Alto reservado para que nombrar la calificación no empuje el layout. */
.rating-echo {
  margin: 0;
  min-height: 22px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  text-align: center;
}
.rating-hint {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ── Campos ─────────────────────────────────────────────────── */
.card-title {
  margin: 0;
  font-family: var(--display);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.15;
  text-wrap: balance;
}
.card-sub {
  margin: 0;
  font-size: 15px;
  color: var(--text-soft);
  text-wrap: pretty;
  max-width: 32ch;
}

.field-group { display: flex; flex-direction: column; gap: var(--s6); }
.field-block { display: flex; flex-direction: column; gap: var(--s2); }

.field-label {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.13em;   /* tracking positivo: lo que pide el texto pequeño */
  text-transform: uppercase;
  color: var(--muted);
}
.field-label .req { color: var(--danger); }
.field-label .opt {
  text-transform: none; letter-spacing: 0;
  font-family: var(--sans); font-size: 12px; color: var(--border-firm);
}

input[type="text"], input[type="tel"], textarea {
  width: 100%;
  min-height: 52px;
  padding: var(--s4);
  border: 1px solid var(--border-firm);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
textarea { resize: vertical; min-height: 116px; line-height: 1.6; }
input::placeholder, textarea::placeholder { color: var(--border-firm); }

input:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent);
}

.field-error { margin: 0; font-size: 13px; color: var(--danger); font-weight: 600; }

.phone-wrap { display: flex; align-items: stretch; }
.phone-prefix {
  display: flex; align-items: center;
  padding: 0 var(--s3);
  border: 1px solid var(--border-firm); border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
  background: #f1f3f7;
  color: var(--text-soft);
  font-family: var(--mono); font-size: 14px;
  white-space: nowrap;
}
.phone-wrap input { border-radius: 0 var(--radius) var(--radius) 0; }

.reply-check {
  display: flex; align-items: flex-start; gap: var(--s3);
  padding: var(--s4);
  border-radius: var(--radius);
  background: #f1f3f7;
}
.reply-check input {
  width: 20px; height: 20px; margin: 2px 0 0;
  accent-color: var(--primary); flex-shrink: 0;
}
.reply-label { font-size: 14px; color: var(--text-soft); cursor: pointer; }

/* ── Sede ───────────────────────────────────────────────────── */
.custom-select { position: relative; }

.custom-select-trigger {
  width: 100%; min-height: 52px;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  padding: var(--s3) var(--s4);
  border: 1px solid var(--border-firm);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-family: var(--sans); font-size: 15px;
  text-align: left; cursor: pointer;
  transition: border-color var(--dur) var(--ease);
}
.custom-select-trigger:hover { border-color: var(--muted); }

.chev {
  width: 18px; height: 18px; flex-shrink: 0;
  fill: none; stroke: var(--muted); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform var(--dur) var(--ease);
}
.custom-select.open .chev { transform: rotate(180deg); }

.custom-select-dropdown {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  z-index: 20;
  /* Alto suficiente para seis sedes sin scroll, acotado a la pantalla:
     210 px cortaba la quinta opción por doce píxeles y obligaba a
     desplazar para ver una lista que cabía casi entera. */
  max-height: min(64vh, 340px); overflow-y: auto;
  padding: var(--s1);
  border: 1px solid var(--border-firm);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 16px 34px -12px rgba(20,23,28,0.3);
  display: none;
}
.custom-select.open .custom-select-dropdown { display: block; }

.custom-select-option {
  min-height: 44px;
  display: flex; align-items: center;
  padding: var(--s2) var(--s3);
  border-radius: 9px;
  font-size: 15px; cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.custom-select-option:hover,
.custom-select-option.selected { background: #f1f3f7; }
.custom-select-option.selected { font-weight: 600; }

/* ── Botones ────────────────────────────────────────────────── */
.btn {
  width: 100%;
  min-height: 54px;
  padding: var(--s3) var(--s5);
  border: 0;
  border-radius: var(--radius);
  background: var(--primary);
  color: #fff;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.24),
              0 8px 20px -10px color-mix(in srgb, var(--primary) 70%, transparent);
  transition: filter var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:hover  { filter: brightness(1.07); }
.btn:active { transform: scale(0.985); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; filter: none; }
.btn-accent { background: var(--accent); }

.btn-text {
  min-height: 44px;
  border: 0; background: transparent;
  color: var(--muted);
  font-family: var(--sans); font-size: 15px;
  cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.btn-text:hover { color: var(--text); }

/* ── Pantallas de cierre ─────────────────────────────────────

   Es el último momento que ve el cliente, y el único de toda la página
   donde un gesto de celebración se gana su sitio: ocurre una vez y es
   emotivo. En el resto de la interfaz sería ruido.
   ────────────────────────────────────────────────────────── */
.status-icon {
  width: 76px; height: 76px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  /* Halo que se expande una vez, como una onda. */
  animation: halo 700ms cubic-bezier(0.23, 1, 0.32, 1) both;
}

@keyframes halo {
  from { transform: scale(0.6); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}

.status-icon svg {
  width: 36px; height: 36px;
  fill: none; stroke: var(--ok); stroke-width: 2.6;
  stroke-linecap: round; stroke-linejoin: round;
  /* El visto se DIBUJA. Es el gesto de confirmación: la marca aparece
     trazándose, no encendiéndose de golpe. */
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
  animation: trazar 520ms cubic-bezier(0.32, 0.72, 0, 1) 260ms both;
}

@keyframes trazar { to { stroke-dashoffset: 0; } }

/* La estrella se RELLENA, no se traza: su forma no es un trazo.
   La regla general pone fill:none, y antes esta no lo revertía — el
   icono quedaba sin relleno y sin trazo, o sea invisible. */
.status-icon.star { background: color-mix(in srgb, var(--star) 20%, transparent); }
.status-icon.star svg {
  fill: var(--star);
  stroke: none;
  stroke-dasharray: none;
  animation: aparecer-estrella 620ms cubic-bezier(0.34, 1.56, 0.64, 1) 180ms both;
}

@keyframes aparecer-estrella {
  from { transform: scale(0.3) rotate(-25deg); opacity: 0; }
  to   { transform: scale(1) rotate(0deg); opacity: 1; }
}

/* ── Pie ────────────────────────────────────────────────────── */
.powered {
  margin: 0;
  display: flex; align-items: center; justify-content: center; gap: 8px;
}
.powered-label {
  font-family: var(--mono);
  font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
}
.powered-brand {
  display: inline-flex; align-items: center; gap: 6px;
  text-decoration: none;
  transition: opacity var(--dur) var(--ease);
}
.powered-brand:hover { opacity: 0.8; }
.powered-icon {
  width: 19px; height: 19px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px;
  color: var(--dblinkon);
  box-shadow: inset 0 0 0 1.4px var(--dblinkon);
}
.powered-icon svg { width: 11px; height: 11px; }
.powered-name {
  font-family: var(--display);
  font-size: 14px; font-weight: 800; letter-spacing: -0.03em;
  color: var(--text);
}
.powered-name .on { color: var(--dblinkon); }

/* ── Pantallas estrechas ────────────────────────────────────── */
@media (max-width: 370px) {
  body { padding: var(--s5) var(--s4); }
  .card { padding: var(--s5) var(--s4) var(--s4); }
  .star-unit { width: 50px; }
  .star-unit svg { width: 38px; height: 38px; }
}

/* ── Preferencias del sistema ───────────────────────────────
   Movimiento reducido: menos y más suave, no cero. Se conservan los
   cambios de color, que comunican estado; se detiene lo que puede marear. */
@media (prefers-reduced-motion: reduce) {
  .screen.entrando { animation: aparece 200ms ease both; }
  .status-icon { animation: none; }
  .status-icon svg { animation: none; stroke-dashoffset: 0; }
  .status-icon.star svg { animation: none; transform: none; opacity: 1; }
  .campo::before, .campo::after { animation: none; }
  .btn:active { transform: none; }
}
@keyframes aparece { from { opacity: 0; } to { opacity: 1; } }

/* Transparencia reducida: el vidrio se vuelve sólido. */
@media (prefers-reduced-transparency: reduce) {
  .card-shell {
    background: rgba(255,255,255,0.9);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  body::before { display: none; }
}

/* ── Eco de identidad en las pantallas de cierre ────────────
   El cliente no debe perder de vista con quién habló justo en el último
   momento. Es una copia decorativa: feedback.js la rellena con el mismo
   logo y nombre, y va oculta a lectores de pantalla porque la información
   ya se anunció al abrir. */
.identidad-eco { opacity: 0.7; padding-bottom: var(--s4); }
