/* ==========================================================================
   Mirador del eclipse
   Sistema visual: fondo blanco, azul como único color de acción, esquinas
   muy redondeadas, tipografía Montserrat.

   Regla estructural de toda la app: la pantalla NUNCA scrollea. Cada
   pantalla es una columna de altura fija (cabecera / contenido / acciones)
   y solo el bloque de contenido puede desbordar. Los botones viven en el
   bloque de acciones, que está siempre presente y siempre visible.
   ========================================================================== */

:root {
  --bg: #ffffff;
  --surface: #f4f6fb;
  --surface-2: #e9edf7;
  --border: #e2e7f2;

  --ink: #10143a;
  --ink-dim: #5a6076;
  --ink-faint: #8d94a8;

  --blue: #2b59ff;
  --blue-dark: #1e3fc4;
  --blue-soft: #e8edff;
  --blue-ink: #16215c;

  --danger: #e0455a;
  --success: #12a45f;

  --radius-pill: 999px;
  --radius-lg: 24px;
  --radius-md: 16px;
  --radius-sm: 12px;

  --pad: 1.25rem;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  /* En horizontal la muesca y el indicador de inicio pasan a los
     laterales, así que hay que reservarlos igual que arriba y abajo. */
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);

  /* Ancho del carril de controles en horizontal. */
  --rail-w: 188px;

  font-family: "Montserrat", system-ui, sans-serif;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  height: 100%;
  /* La página en sí no se mueve nunca. Los rebotes de scroll a nivel de
     documento rompen la sensación de app nativa. */
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  position: relative;
  height: 100vh;
  height: 100dvh;
}

/* --------------------------------------------------------------------------
   Estructura de pantalla
   -------------------------------------------------------------------------- */

.screen {
  display: none;
  position: absolute;
  inset: 0;
  flex-direction: column;
  background: var(--bg);
}

.screen--active {
  display: flex;
}

/* Único bloque con scroll, y solo cuando el contenido no cabe. */
.screen-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 1.25rem var(--pad) 0.5rem;
}

/* Los botones nunca se esconden detrás del scroll: viven aquí, fuera de
   la zona scrollable, con una sombra suave que los despega del contenido
   cuando este pasa por debajo. */
.screen-actions {
  flex: 0 0 auto;
  padding: 0.9rem var(--pad) calc(0.9rem + var(--safe-bottom));
  background: var(--bg);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.screen-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: calc(0.75rem + var(--safe-top)) var(--pad) 0.75rem;
  border-bottom: 1px solid var(--border);
}

.screen-head-title {
  flex: 1;
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  text-align: center;
}

.screen-head-spacer {
  width: 42px;
  flex: 0 0 auto;
}

.btn-row {
  display: flex;
  gap: 0.6rem;
}

.btn-row .btn {
  flex: 1;
}

/* --------------------------------------------------------------------------
   Tipografía
   -------------------------------------------------------------------------- */

.eyebrow {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--blue);
  margin: 0 0 0.6rem;
}

h1, h2, h3 {
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 0.6rem;
}

h1 { font-size: 2.4rem; line-height: 1.05; }
h2 { font-size: 1.5rem; line-height: 1.15; }
h3 { font-size: 1.02rem; }

.subtitle {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 1rem;
}

.lede {
  font-size: 0.93rem;
  line-height: 1.6;
  color: var(--ink-dim);
  margin: 0 0 0.9rem;
}

.lede strong { color: var(--ink); font-weight: 700; }

.lede a { color: var(--blue); font-weight: 600; }

.status-text {
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--ink-dim);
  margin: 0;
  text-align: center;
}

.status-text[data-error="true"] { color: var(--danger); }

.status-text:empty { display: none; }

/* --------------------------------------------------------------------------
   Botones
   -------------------------------------------------------------------------- */

.btn {
  font-family: inherit;
  font-size: 0.98rem;
  font-weight: 700;
  border-radius: var(--radius-pill);
  border: 1.5px solid transparent;
  padding: 0.95rem 1.4rem;
  cursor: pointer;
  transition: transform 0.12s ease, background 0.15s ease;
  /* Mínimo táctil cómodo con una mano sujetando el móvil en alto. */
  min-height: 52px;
}

.btn:active { transform: scale(0.975); }

.btn--primary {
  background: var(--blue);
  color: #ffffff;
  box-shadow: 0 8px 20px rgba(43, 89, 255, 0.28);
}

.btn--primary:active { background: var(--blue-dark); }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--border);
}

.btn--ghost:active { background: var(--surface); }

.btn--block {
  display: block;
  width: 100%;
}

.btn:disabled {
  opacity: 0.45;
  pointer-events: none;
  box-shadow: none;
}

.btn-icon {
  width: 42px;
  height: 42px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border: none;
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--radius-pill);
  cursor: pointer;
  padding: 0;
}

.btn-icon svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.btn-icon--solid {
  background: rgba(16, 20, 58, 0.55);
  color: #ffffff;
  backdrop-filter: blur(8px);
}

/* --------------------------------------------------------------------------
   Menú
   -------------------------------------------------------------------------- */

.menu-trigger {
  position: fixed;
  top: calc(0.75rem + var(--safe-top));
  right: 0.9rem;
  z-index: 60;
}

/* En la cámara el fondo es vídeo, así que el botón necesita contraste
   propio en vez de apoyarse en el blanco de la app. */
.screen--camera ~ .menu-trigger,
body.is-camera .menu-trigger {
  background: rgba(16, 20, 58, 0.55);
  color: #ffffff;
  backdrop-filter: blur(8px);
}

.menu-panel {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.28s ease;
}

.menu-panel--open { transform: translateX(0); }

.menu-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(0.9rem + var(--safe-top)) var(--pad) 0.9rem;
  border-bottom: 1px solid var(--border);
}

.menu-head h2 { margin: 0; font-size: 1.2rem; }

.menu-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 1.1rem var(--pad) calc(2rem + var(--safe-bottom));
}

.menu-section { margin-bottom: 1.8rem; }

.menu-section--safety {
  background: var(--blue-soft);
  border-radius: var(--radius-lg);
  padding: 1.1rem;
}

.menu-section--safety h3 { color: var(--blue-ink); }

.signature,
.signature-inline {
  display: block;
  text-align: center;
  font-size: 0.78rem;
  color: var(--ink-faint);
  text-decoration: none;
}

.signature-inline span { color: var(--blue); font-weight: 600; }

.signature { display: none; }

/* --------------------------------------------------------------------------
   Pantalla 1: intro
   -------------------------------------------------------------------------- */

/* El hero es la cabecera completa, no solo la imagen: antetítulo, título,
   subtítulo y firma van todos sobre la foto, en blanco. La imagen se
   oscurece por debajo para que el texto se lea sin depender de qué haya
   en esa zona concreta de la fotografía. */
.intro-hero {
  flex: 0 0 auto;
  position: relative;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  overflow: hidden;
  background: #05070f;
}

.intro-hero-art {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0.62;
}

/* Velo oscuro que se intensifica hacia abajo, donde vive el texto. */
.intro-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(5, 7, 15, 0.25) 0%, rgba(5, 7, 15, 0.5) 45%, rgba(5, 7, 15, 0.88) 100%);
}

.intro-hero-text {
  position: relative;
  z-index: 1;
  padding: calc(3.2rem + var(--safe-top)) var(--pad) 1.4rem;
}

.intro-hero-text .eyebrow { color: #b9c8ff; margin-bottom: 0.5rem; }
.intro-hero-text h1 { color: #ffffff; margin-bottom: 0.7rem; }

.intro-hero-sub {
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.92);
  margin: 0 0 0.9rem;
}

.intro-hero-credit {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.78rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.6);
}

.intro-hero-credit a {
  color: inherit;
  text-decoration: none;
}

.intro-hero-credit a span { color: #b9c8ff; font-weight: 700; }

/* El contador solo ocupa sitio cuando hay una cifra real que enseñar. */
.visit-counter {
  font-size: 0.72rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.75);
  background: rgba(255, 255, 255, 0.14);
  border-radius: var(--radius-pill);
  padding: 0.15rem 0.55rem;
}

.visit-counter:empty { display: none; }

/* El reloj es el bloque protagonista de la portada: fondo azul sólido,
   no el tinte suave del resto de tarjetas. */
.countdown-box {
  background: var(--blue);
  border-radius: var(--radius-lg);
  padding: 1rem 0.9rem 0.95rem;
  margin-bottom: 1rem;
  text-align: center;
  box-shadow: 0 10px 26px rgba(43, 89, 255, 0.26);
}

.countdown-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.8);
  margin: 0 0 0.6rem;
}

.countdown-numbers {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 0.35rem;
  color: #ffffff;
}

.cd-cell {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
}

.cd-val {
  font-size: 2.15rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  /* Cifras de ancho fijo: sin esto el bloque entero se ensancha y encoge
     cada segundo al cambiar de dígito. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

.cd-unit {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.75);
}

/* Este texto vive SIEMPRE sobre el azul de la caja, así que va en blanco.
   Ojo al mantenerlo: había una segunda regla más abajo que lo dejaba en
   gris (el color de cuando la caja era clara), y como ganaba por orden,
   el mensaje de "el eclipse es total ahora mismo" salía gris sobre azul,
   ilegible justo en el momento más importante de la app. */
.countdown-sub {
  font-size: 0.85rem;
  line-height: 1.5;
  font-weight: 600;
  color: #ffffff;
  margin: 0.5rem 0 0;
}

.countdown-sub:empty { display: none; }

/* Reclamo para compartir: cierra la portada explicando qué se lleva el
   usuario si abre la cámara. */
.share-promo {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: var(--blue-soft);
  border-radius: var(--radius-lg);
  padding: 0.9rem 1rem;
  margin: 0.2rem 0 0.5rem;
}

.share-promo-icon {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-pill);
  background: var(--blue);
  display: grid;
  place-items: center;
}

.share-promo-icon svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke: #ffffff;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.share-promo p {
  margin: 0;
  font-size: 0.88rem;
  font-weight: 700;
  line-height: 1.45;
  color: var(--blue-ink);
}

/* La invitación va en azul de acción, pero en la misma línea: en un
   renglón aparte empujaba el bloque fuera de la pantalla y obligaba a
   hacer scroll para leer el remate del mensaje. */
.share-promo-cta { color: var(--blue); }

/* --------------------------------------------------------------------------
   Pantalla 2: datos
   -------------------------------------------------------------------------- */

.data-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
  margin: 1rem 0;
}

.data-grid > div {
  background: var(--surface);
  border-radius: var(--radius-md);
  padding: 0.8rem 0.9rem;
}

.data-grid dt {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.25rem;
}

.data-grid dd {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--ink);
  letter-spacing: -0.01em;
}

.map-wrap {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface);
  touch-action: none;
}

.map-canvas { display: block; width: 100%; height: auto; }

.map-caption {
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--ink-faint);
  margin: 0.5rem 0 0;
}

/* --------------------------------------------------------------------------
   Pantalla 3: cámara
   -------------------------------------------------------------------------- */

.screen--camera { background: #000000; }

#camera-feed,
#ar-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

#camera-feed { object-fit: cover; }

#ar-canvas { pointer-events: none; }

.ar-gate {
  position: absolute;
  inset: 0;
  z-index: 30;
  background: var(--bg);
  display: flex;
  align-items: center;
  padding: var(--pad);
}

.ar-gate-card { width: 100%; }

/* Calibración: tapa la cámara hasta que termina, porque hasta entonces
   cualquier dato superpuesto estaría mal escalado. */
.calib-gate {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: none;
  align-items: flex-end;
  background: linear-gradient(to bottom, rgba(16, 20, 58, 0.15), rgba(16, 20, 58, 0.75));
}

.calib-gate--visible { display: flex; }

.calib-card {
  width: 100%;
  background: var(--bg);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 1.4rem var(--pad) calc(1.2rem + var(--safe-bottom));
  text-align: center;
}

.calib-phone { margin: 0 auto 0.8rem; width: 130px; }

.calib-phone svg { width: 100%; height: auto; }

.calib-phone-body {
  fill: none;
  stroke: var(--ink);
  stroke-width: 3;
  transform-origin: 60px 40px;
  animation: calib-sway 2.4s ease-in-out infinite;
}

.calib-phone-arc,
.calib-phone-tip {
  fill: none;
  stroke: var(--blue);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.calib-phone-arc { stroke-dasharray: 4 7; }

@keyframes calib-sway {
  0%, 100% { transform: rotate(-13deg) translateX(-14px); }
  50%      { transform: rotate(13deg) translateX(14px); }
}

@media (prefers-reduced-motion: reduce) {
  .calib-phone-body { animation: none; }
}

.calib-progress {
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  overflow: hidden;
  margin: 1.1rem 0 0.6rem;
}

.calib-progress-fill {
  height: 100%;
  width: 0%;
  border-radius: var(--radius-pill);
  background: var(--blue);
  transition: width 0.25s ease;
}

.calib-hint {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-dim);
  margin: 0 0 1rem;
  min-height: 1.2em;
}

.calib-hint--warn { color: var(--danger); }
.calib-hint--good { color: var(--success); }

/* HUD */

.ar-hud {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: none;
  flex-direction: column;
  pointer-events: none;
}

.ar-hud--visible { display: flex; }

.ar-hud button,
.ar-hud input { pointer-events: auto; }

.hud-top {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: calc(0.75rem + var(--safe-top)) 0.9rem 0;
}

.hud-readout {
  display: flex;
  gap: 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: #ffffff;
  background: rgba(16, 20, 58, 0.55);
  backdrop-filter: blur(8px);
  padding: 0.4rem 0.7rem;
  border-radius: var(--radius-pill);
}

.sun-warning-badge,
.sun-ok-badge {
  display: none;
  font-size: 0.72rem;
  font-weight: 700;
  padding: 0.4rem 0.7rem;
  border-radius: var(--radius-pill);
  color: #ffffff;
}

.sun-warning-badge { background: var(--danger); }
.sun-ok-badge { background: var(--success); }

.sun-warning-badge--active,
.sun-ok-badge--active { display: block; }

.hud-instructions {
  flex: 0 0 auto;
  margin: 0.7rem 0.9rem 0;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 700;
  color: #ffffff;
  background: rgba(16, 20, 58, 0.6);
  backdrop-filter: blur(8px);
  border-radius: var(--radius-md);
  padding: 0.65rem 0.85rem;
}

.hud-instructions--pinned {
  background: var(--blue);
}

.hud-compass-alert {
  display: none;
  margin: 0.6rem 0.9rem 0;
  background: var(--danger);
  color: #ffffff;
  border-radius: var(--radius-md);
  padding: 0.8rem;
  text-align: center;
}

.hud-compass-alert--visible { display: block; }

/* Diagnóstico de sensores en vivo, solo visible si se activa desde el
   panel de pruebas. Fondo oscuro fijo porque va encima del vídeo de la
   cámara, no del blanco de la app, y letra pequeña porque es un dato de
   depuración, no algo pensado para el uso normal. */
.sensor-diag-hud {
  position: absolute;
  top: calc(3.6rem + var(--safe-top, 0px));
  left: calc(0.7rem + var(--safe-left, 0px));
  z-index: 25;
  margin: 0;
  max-width: 62vw;
  font-family: "SF Mono", "Menlo", "Consolas", monospace;
  font-size: 0.62rem;
  line-height: 1.5;
  white-space: pre-wrap;
  background: rgba(8, 10, 28, 0.72);
  color: #ffffff;
  border-radius: var(--radius-md);
  padding: 0.55rem 0.65rem;
  pointer-events: none;
}

/* Variante discreta: para el aviso de interferencia magnética, que
   informa pero no impide seguir usando el visor. Ámbar en vez de rojo,
   una sola línea y sin botón, para no comerse el encuadre. */
.hud-compass-alert--soft {
  background: rgba(255, 176, 32, 0.94);
  color: #3a2600;
  padding: 0.5rem 0.8rem;
  text-align: left;
}

.hud-compass-alert--soft p { margin: 0; font-size: 0.78rem; }

.hud-compass-alert--soft .btn--ghost { display: none; }

.hud-compass-alert p { margin: 0 0 0.6rem; font-size: 0.85rem; font-weight: 600; }

.hud-compass-alert .btn--ghost {
  background: #ffffff;
  border-color: #ffffff;
  color: var(--danger);
  min-height: 44px;
  padding: 0.6rem 1.1rem;
}

.hud-bottom {
  margin-top: auto;
  flex: 0 0 auto;
  padding: 0.9rem 0.9rem calc(0.9rem + var(--safe-bottom));
  background: linear-gradient(to top, rgba(16, 20, 58, 0.85), rgba(16, 20, 58, 0));
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.hud-time-panel {
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  border-radius: var(--radius-lg);
  padding: 0.8rem 1rem 0.6rem;
}

.hud-time-title {
  display: block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 0.35rem;
}

.hud-time-labels {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-weight: 800;
  color: var(--ink);
  margin-bottom: 0.2rem;
}

#hud-slider-time { font-size: 1.25rem; letter-spacing: -0.02em; }

#hud-coverage-label { font-size: 0.82rem; color: var(--blue); font-weight: 700; }

/* El slider y sus dos extremos viven en una rejilla con áreas nombradas.
   Así la misma marca sirve para las dos orientaciones: en vertical los
   extremos se reparten debajo (inicio a la izquierda, fin a la derecha) y
   en horizontal se apilan alrededor del slider girado (fin arriba,
   inicio abajo), sin tocar el orden del HTML ni duplicar nodos. */
.slider-zone {
  display: grid;
  grid-template-areas:
    "rail rail"
    "start end";
  grid-template-columns: 1fr 1fr;
  align-items: center;
}

.slider-rail { grid-area: rail; min-width: 0; }

.hud-endpoint {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--ink-faint);
  margin-top: 0.1rem;
  white-space: nowrap;
}

.hud-endpoint--start { grid-area: start; text-align: left; }
.hud-endpoint--end { grid-area: end; text-align: right; }

/* Momento del máximo: el panel entero se marca para que el instante
   importante del eclipse se distinga de un vistazo. */
.time-panel--peak {
  box-shadow: 0 0 0 2.5px var(--blue), 0 10px 26px rgba(43, 89, 255, 0.32);
}

.coverage--peak {
  color: #ffffff !important;
  background: var(--blue);
  border-radius: var(--radius-pill);
  padding: 0.15rem 0.55rem;
}

/* Destello de captura */

.capture-flash {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: #ffffff;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.32s ease;
}

.capture-flash.flash-active { opacity: 0.85; }

/* Fila de captura. El interruptor de coordenadas ya no vive aquí: decidir
   si se publica dónde estabas es parte de compartir, no de encuadrar, y
   además liberaba el único sitio donde el botón de foto cabe entero en
   horizontal. */
.photo-row {
  display: flex;
  align-items: stretch;
  gap: 0.6rem;
}

.btn--photo { flex: 1 1 auto; }

/* Marcos de aviso sobre el vídeo */

.frame-warning,
.frame-ok {
  position: absolute;
  inset: 0;
  z-index: 15;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease;
  border: 4px solid transparent;
}

.frame-warning--active { opacity: 1; border-color: var(--danger); }
.frame-ok--active { opacity: 1; border-color: var(--success); }

/* Resultado de la foto */

.photo-result {
  position: absolute;
  inset: 0;
  z-index: 50;
  display: none;
  flex-direction: column;
  background: var(--bg);
}

.photo-result--visible { display: flex; }

.photo-result-inner {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: calc(1rem + var(--safe-top)) var(--pad) 0.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
}

#photo-result-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius-md);
}

.photo-hint {
  font-size: 0.78rem;
  color: var(--ink-faint);
  text-align: center;
  margin: 0;
}

/* --------------------------------------------------------------------------
   Sliders
   -------------------------------------------------------------------------- */

input[type="range"] {
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  /* Padding vertical invisible: amplía la zona táctil real sin cambiar el
     aspecto, importante sujetando el móvil en alto con una mano. */
  padding: 0.55rem 0;
  margin: 0;
}

input[type="range"]::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 26px;
  height: 26px;
  margin-top: -10px;
  border-radius: 50%;
  background: var(--blue);
  border: 3px solid #ffffff;
  box-shadow: 0 2px 8px rgba(16, 20, 58, 0.25);
}

input[type="range"]::-moz-range-track {
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
}

input[type="range"]::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--blue);
  border: 3px solid #ffffff;
}

/* --------------------------------------------------------------------------
   Aviso de escritorio
   -------------------------------------------------------------------------- */

.desktop-notice {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--pad);
}

.desktop-notice-card { max-width: 460px; }

/* --------------------------------------------------------------------------
   Simulador de ubicación (solo pruebas)
   -------------------------------------------------------------------------- */

.test-panel {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: none;
  align-items: flex-end;
  background: rgba(16, 20, 58, 0.55);
}

.test-panel--visible { display: flex; }

.test-panel-inner {
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--bg);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 1.1rem var(--pad) calc(1.1rem + var(--safe-bottom));
}

.test-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.3rem;
}

.test-head h2 { margin: 0; font-size: 1.15rem; }

.test-note {
  font-size: 0.8rem;
  color: var(--ink-dim);
  margin: 0 0 0.9rem;
}

.test-diag {
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.sensor-diag {
  font-family: "SF Mono", "Menlo", "Consolas", monospace;
  font-size: 0.72rem;
  line-height: 1.55;
  white-space: pre-wrap;
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--radius-md);
  padding: 0.7rem 0.8rem;
  margin: 0;
}

.test-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
}

.test-site {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--ink);
  background: var(--surface);
  border: none;
  border-radius: var(--radius-md);
  padding: 0.7rem 0.8rem;
  cursor: pointer;
  text-align: left;
}

.test-site:active { background: var(--surface-2); }

.test-site-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.test-site-tag {
  flex: 0 0 auto;
  font-size: 0.66rem;
  font-weight: 700;
  color: var(--ink-faint);
}

.test-site-tag--total {
  color: #ffffff;
  background: var(--blue);
  border-radius: var(--radius-pill);
  padding: 0.1rem 0.45rem;
}

.test-manual { display: flex; gap: 0.4rem; }

.test-manual input {
  flex: 1;
  min-width: 0;
  font-family: inherit;
  font-size: 0.9rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0.7rem 0.8rem;
  background: var(--bg);
  color: var(--ink);
}

.test-manual .btn { flex: 0 0 auto; padding: 0.7rem 1.1rem; min-height: 0; }

/* Aviso permanente mientras la ubicación es simulada. Va arriba del todo
   y en un color que no se confunde con nada de la app, precisamente para
   que no pase inadvertido. */
.test-badge {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 110;
  display: none;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: calc(0.35rem + var(--safe-top)) 0.6rem 0.35rem;
  background: #ffb020;
  color: #3a2600;
  font-size: 0.7rem;
  font-weight: 700;
}

.test-badge--visible { display: flex; }

.test-badge button {
  font: inherit;
  font-size: 0.66rem;
  text-decoration: underline;
  color: #3a2600;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* ==========================================================================
   Datos opcionales antes de compartir
   ==========================================================================

   Va por encima de todo lo demás (incluido el resultado de la foto, que
   es z-index 50 dentro de la pantalla de cámara). En vertical entra como
   hoja inferior, que es donde cae el pulgar; en horizontal se centra,
   porque una hoja de abajo con 390 px de alto no deja sitio ni al
   teclado. */

.share-opts {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: none;
  align-items: flex-end;
  justify-content: center;
  background: rgba(16, 20, 58, 0.6);
  backdrop-filter: blur(4px);
}

.share-opts--visible { display: flex; }

.share-opts-card {
  width: 100%;
  max-width: 520px;
  max-height: 92vh;
  max-height: 92dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 1.1rem var(--pad) calc(1rem + var(--safe-bottom));
}

.share-opts-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.share-opts-head h2 { margin: 0; font-size: 1.25rem; }

/* El aviso no es letra pequeña: una coordenada dice dónde estabas a una
   hora concreta, y la foto circula sin control. Se lee antes que las
   cajas, no después. */
.share-opts-note {
  flex: 0 0 auto;
  font-size: 0.85rem;
  line-height: 1.45;
  font-weight: 600;
  color: var(--ink-dim);
  margin: 0.5rem 0 0.9rem;
}

.share-opts-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.field { display: block; margin-bottom: 0.85rem; }

.field-label {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 0.35rem;
}

.field input {
  width: 100%;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0.8rem 0.9rem;
  /* 16 px reales evitan que iOS haga zoom al enfocar la caja. */
  min-height: 50px;
}

.field input:focus {
  outline: none;
  border-color: var(--blue);
  background: var(--bg);
}

/* Placeholder de ejemplo: gris muy claro para que se lea como pista y no
   como texto ya escrito. */
.field input::placeholder {
  color: #b6bccd;
  font-weight: 500;
}

.check-row {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  padding: 0.75rem 0.85rem;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  min-height: 52px;
}

/* Dos casillas seguidas (ubicación y galería) necesitan aire entre ellas;
   antes solo había una, así que no hacía falta esta separación. */
.check-row + .check-row { margin-top: 0.6rem; }

/* El input real se esconde sin sacarlo del árbol de accesibilidad: el
   lector de pantalla y el teclado siguen viéndolo. */
.check-row input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.check-box {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  margin-top: 1px;
  border-radius: 7px;
  border: 1.5px solid var(--ink-faint);
  background: var(--bg);
  display: grid;
  place-items: center;
}

.check-box svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: #ffffff;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
}

.check-row input:checked ~ .check-box {
  background: var(--blue);
  border-color: var(--blue);
}

.check-row input:checked ~ .check-box svg { opacity: 1; }

.check-row input:focus-visible ~ .check-box {
  box-shadow: 0 0 0 3px var(--blue-soft);
}

.check-text {
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
}

.check-sub {
  display: block;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--ink-faint);
  margin-top: 0.15rem;
}

.check-sub:empty { display: none; }

.share-opts-actions {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding-top: 0.9rem;
}

/* Pantallas bajas: el hero cede espacio antes que el contenido, porque el
   botón de acción no puede perder su sitio. */
@media (max-height: 700px) {
  .intro-hero-text { padding-top: calc(2.4rem + var(--safe-top)); padding-bottom: 1rem; }
  h1 { font-size: 1.95rem; }
  .intro-hero-sub { font-size: 0.94rem; margin-bottom: 0.7rem; }
  .cd-val { font-size: 1.8rem; }
}

/* ==========================================================================
   Pantalla de cámara en horizontal
   ==========================================================================

   En vertical la cámara ocupa la pantalla entera y los controles flotan
   encima, sobre el cielo, que es espacio muerto. Girado el móvil esa
   misma idea deja de funcionar: la franja útil (el horizonte con el Sol)
   se queda en el centro y los controles la tapan justo donde importa.

   Así que en horizontal se separan: la imagen se recorta a un rectángulo
   que termina antes del borde derecho, y todos los controles pasan a un
   carril propio a la derecha, con el slider girado a vertical. No se
   solapa nada y el pulgar de la mano derecha llega a todo sin cruzar por
   delante del objetivo. */

@media (orientation: landscape) {
  /* El vídeo, el canvas del overlay y los marcos de aviso comparten
     recorte: si uno solo se saliera, el horizonte dibujado dejaría de
     coincidir con la imagen.

     El recorte se hace con el ancho, no con `right`. La regla base
     declara width:100% además de inset:0, y un absoluto con left, right
     Y width está sobredeterminado: el navegador conserva el width y
     descarta el right, así que el vídeo seguiría midiendo la pantalla
     entera por detrás del carril. `width: auto` tampoco vale: en
     elementos reemplazados (vídeo, canvas) auto significa "tu tamaño
     intrínseco", no "lo que quede".

     Solo se recorta por la derecha. Por la izquierda sigue a sangre
     aunque haya muesca: dejar ahí una banda negra costaría el mismo
     trozo de imagen que la muesca tapa, pero encima parecería un fallo. */
  body.is-camera #camera-feed,
  body.is-camera #ar-canvas,
  body.is-camera .frame-warning,
  body.is-camera .frame-ok {
    right: var(--rail-w);
    width: calc(100% - var(--rail-w));
  }

  body.is-camera .menu-trigger {
    right: calc(var(--rail-w) + var(--safe-right) + 0.6rem);
  }

  /* El hueco de la derecha suma el carril más el botón de menú, que
     también vive arriba: sin ese margen el rumbo quedaría debajo. */
  .hud-top {
    padding: calc(0.6rem + var(--safe-top)) calc(var(--rail-w) + 3.6rem) 0
             calc(0.7rem + var(--safe-left));
    flex-wrap: wrap;
    gap: 0.4rem;
  }

  .hud-instructions,
  .hud-compass-alert {
    margin: 0.5rem calc(var(--rail-w) + 0.7rem) 0 calc(0.7rem + var(--safe-left));
    font-size: 0.82rem;
    padding: 0.5rem 0.75rem;
  }

  /* El carril. Ya no es una franja que se apoya en el fondo: es una
     columna sólida con su propio suelo, porque debajo no hay vídeo. */
  .hud-bottom {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: calc(var(--rail-w) + var(--safe-right));
    margin-top: 0;
    background: rgba(16, 20, 58, 0.94);
    backdrop-filter: blur(12px);
    padding: calc(0.6rem + var(--safe-top)) calc(0.6rem + var(--safe-right))
             calc(0.6rem + var(--safe-bottom)) 0.6rem;
    gap: 0.55rem;
    /* El carril sí captura el dedo: apoyar la mano encima no debe
       disparar el zoom de pellizco de la cámara que hay detrás. */
    pointer-events: auto;
  }

  .hud-time-panel {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0.6rem 0.65rem 0.5rem;
  }

  .hud-time-title { font-size: 0.6rem; margin-bottom: 0.2rem; }

  /* Hora y cobertura dejan de competir por una línea de 170 px: se
     apilan, con la hora como dato principal. */
  .hud-time-labels {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
    margin-bottom: 0.35rem;
  }

  #hud-slider-time { font-size: 1.15rem; }
  #hud-coverage-label { font-size: 0.76rem; }

  .slider-zone {
    flex: 1 1 auto;
    min-height: 0;
    grid-template-areas: "end" "rail" "start";
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr) auto;
    justify-items: center;
    gap: 0.3rem;
  }

  .hud-endpoint--start,
  .hud-endpoint--end { text-align: center; margin: 0; }

  /* Slider vertical por rotación en vez de writing-mode o
     -webkit-appearance: slider-vertical. Las dos vías nativas están en
     transición (Chrome retiró slider-vertical, Safari añadió
     writing-mode tarde) y cada navegador pinta el track de una forma;
     rotar conserva exactamente el mismo aspecto y la misma zona táctil
     ampliada que en vertical, y funciona en todo lo que exista hoy. */
  .slider-rail {
    position: relative;
    width: 44px;
    height: 100%;
    min-height: 80px;
  }

  .slider-rail #time-slider {
    position: absolute;
    top: 50%;
    left: 50%;
    /* Lo mide el JS: es la altura del carril, no un porcentaje, porque
       tras rotar el ancho del input pasa a ser su alto en pantalla. */
    width: var(--slider-len, 120px);
    transform-origin: 50% 50%;
    transform: translate(-50%, -50%) rotate(-90deg);
  }

  .btn--photo {
    font-size: 0.88rem;
    padding: 0.75rem 0.9rem;
    min-height: 48px;
  }

  /* La calibración deja de ser una hoja pegada abajo (en horizontal
     ocuparía la pantalla entera) y pasa a tarjeta centrada. */
  .calib-gate { align-items: center; justify-content: center; padding: 0.8rem; }

  .calib-card {
    max-width: 560px;
    max-height: 100%;
    overflow-y: auto;
    border-radius: var(--radius-lg);
    padding: 1rem 1.2rem;
  }

  .calib-phone { width: 92px; margin-bottom: 0.5rem; }
  .calib-card h2 { font-size: 1.2rem; }
  .calib-card .lede { font-size: 0.85rem; margin-bottom: 0.5rem; }
  .calib-progress { margin: 0.7rem 0 0.45rem; }

  .ar-gate { overflow-y: auto; padding: 1rem; }
  .ar-gate-card { max-width: 560px; margin: auto; }

  /* Resultado de la foto: la imagen es apaisada y ocupa el ancho, así
     que los botones se van al lateral en vez de comerse el alto. */
  .photo-result { flex-direction: row; }

  .photo-result-inner {
    padding: calc(0.7rem + var(--safe-top)) 0.7rem 0.7rem calc(0.7rem + var(--safe-left));
    justify-content: center;
  }

  .photo-result .screen-actions {
    flex: 0 0 auto;
    width: 220px;
    justify-content: center;
    border-top: none;
    border-left: 1px solid var(--border);
    padding: 0.9rem;
    padding-right: calc(0.9rem + var(--safe-right));
  }

  .photo-result .btn-row { flex-direction: column; }
  .photo-hint { font-size: 0.72rem; }

  /* La hoja de datos opcionales se centra y se aprieta: con el teclado
     abierto en horizontal quedan menos de 200 px de alto útil. */
  .share-opts { align-items: center; padding: 0.6rem; }

  .share-opts-card {
    border-radius: var(--radius-lg);
    max-height: 96dvh;
    padding: 0.9rem 1rem;
  }

  .share-opts-head h2 { font-size: 1.05rem; }
  .share-opts-note { font-size: 0.78rem; margin: 0.4rem 0 0.7rem; }
  .field { margin-bottom: 0.6rem; }
  .share-opts-actions { flex-direction: row-reverse; padding-top: 0.7rem; }
  .share-opts-actions .btn { flex: 1; min-height: 48px; padding: 0.7rem 1rem; }
}

/* Horizontal en un móvil de verdad: alto muy corto. Aquí es donde el
   carril se queda sin sitio, así que se recorta lo prescindible. */
@media (orientation: landscape) and (max-height: 430px) {
  :root { --rail-w: 168px; }

  .hud-time-title { display: none; }
  #hud-slider-time { font-size: 1.05rem; }
  .hud-endpoint { font-size: 0.64rem; }
  .hud-instructions { font-size: 0.76rem; }
  .photo-result .screen-actions { width: 190px; }
}
