/* Checks — hoja de estilos de la aplicación.
   Todo se expresa con los tokens de tokens.css: si la marca cambia, cambia ahí
   y no aquí. Sin dependencias externas (salvo la fuente Inter, que degrada a
   la del sistema si no hay red). */

/* ============================================================ base */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-inter);
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--text-primary);
  background: var(--color-paper);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: var(--color-forest-ink); }
button, input, select, textarea { font: inherit; color: inherit; }

h1, h2, h3, h4 { margin: 0; color: var(--text-display); letter-spacing: -0.02em; }

.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; }

.shell { max-width: var(--page-max-width); margin: 0 auto; padding: 0 var(--spacing-24); }

/* ============================================================ tipografía */

.display {
  font-family: var(--font-wise-sans);
  font-weight: var(--font-weight-black);
  color: var(--color-forest-ink);
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: -1.5px;
  margin: 0;
}
.display--hero { font-size: clamp(38px, 5.6vw, 61px); }
.display--md   { font-size: clamp(30px, 4vw, 45px); letter-spacing: -1px; line-height: 1; }

.section-title {
  font-size: clamp(26px, 3.2vw, var(--text-subheading));
  font-weight: var(--font-weight-bold);
  color: var(--color-forest-ink);
  letter-spacing: var(--tracking-subheading);
  margin: 0 0 var(--spacing-8);
}
.section-lead { font-size: var(--text-body); color: var(--text-muted); margin: 0 0 var(--spacing-40); }

.lead { font-size: var(--text-body); line-height: 1.5; color: var(--text-primary); }
.muted { color: var(--text-muted); }
.subtle { color: var(--text-subtle); }
.micro { font-size: var(--text-micro); }
.caption { font-size: var(--text-caption); }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }

/* ============================================================ botones */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--spacing-8);
  border: 1px solid transparent;
  border-radius: var(--radius-buttons);
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-body-sm);
  line-height: 1;
  padding: 14px 24px;
  cursor: pointer;
  background: none;
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease;
  white-space: nowrap;
}
.btn:focus-visible { outline: 2px solid var(--color-forest-ink); outline-offset: 2px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

.btn--primary { background: var(--color-checks-green); color: #fff; }
.btn--primary:not([disabled]):hover { background: var(--color-checks-green-dark); }

.btn--ink { background: var(--color-forest-ink); color: var(--color-paper); }
.btn--ink:not([disabled]):hover { background: #0d2300; }

.btn--secondary { background: transparent; color: var(--color-forest-ink); border-color: var(--color-forest-ink); }
.btn--secondary:not([disabled]):hover { background: var(--color-linen-mist); }

.btn--quiet { background: var(--color-fog); color: var(--color-forest-ink); }
.btn--quiet:not([disabled]):hover { background: var(--color-linen-mist); }

.btn--danger { background: transparent; color: var(--color-alarm-red); border-color: var(--color-alarm-red); }
.btn--danger:not([disabled]):hover { background: #fdf0f0; }

.btn--text { background: none; color: var(--color-forest-ink); text-decoration: underline; padding-left: 4px; padding-right: 4px; }
.btn--text:not([disabled]):hover { color: var(--color-checks-green-dark); }

.btn--lg { padding: 18px 32px; font-size: var(--text-body); }
.btn--sm { padding: 9px 16px; font-size: var(--text-caption); }

.btn-row { display: flex; gap: var(--spacing-12); flex-wrap: wrap; align-items: center; }

/* ============================================================ badges / pills */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: var(--radius-tags);
  padding: 6px 14px;
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  background: var(--color-linen-mist);
  color: var(--color-forest-ink);
}
.badge--fog { background: var(--color-fog); color: var(--color-forest-ink); }
.badge--ink { background: var(--color-forest-ink); color: var(--color-paper); }
.badge--lime { background: var(--color-lime-voltage); color: var(--color-forest-ink); }
.badge--green { background: var(--color-checks-green); color: #fff; }
.badge--danger { background: #fdecec; color: var(--color-alarm-red); }
.badge--warn { background: #fdf3e2; color: #8a5a00; }
.badge--soft { background: #e6f7ee; color: var(--color-checks-green-dark); font-weight: var(--font-weight-semibold); }
.badge--caps { font-size: 10px; letter-spacing: .07em; text-transform: uppercase; }

/* Estados de lote y persona. El color comunica antes que el texto. */
.state { font-weight: var(--font-weight-semibold); }
.state--queued, .state--preparing { background: var(--color-fog); color: var(--color-slate); }
.state--running { background: var(--color-lime-voltage); color: var(--color-forest-ink); }
.state--completed { background: var(--color-checks-green); color: #fff; }
.state--completed_with_errors { background: #fdf3e2; color: #8a5a00; }
.state--failed, .state--cancelled { background: #fdecec; color: var(--color-alarm-red); }
.state--interrupted { background: #eef1fb; color: var(--color-signal-blue); }

/* ============================================================ superficies */

.card {
  background: var(--color-paper);
  border: 1px solid var(--color-fog);
  border-radius: var(--radius-cards);
  padding: var(--card-padding);
}
.card--lg { border-radius: var(--radius-large-cards); padding: var(--spacing-40); border: none; box-shadow: var(--shadow-lg); }
.card--flat { background: var(--color-fog); border-color: transparent; }
.card--mist { background: var(--color-linen-mist); border-color: transparent; }

.panel {
  background: var(--color-paper);
  border-radius: var(--radius-large-cards);
  box-shadow: var(--shadow-lg);
  padding: var(--spacing-32);
}

.divider { height: 1px; background: var(--color-fog); border: 0; margin: var(--spacing-24) 0; }

.icon-pill {
  width: 44px; height: 44px; flex: none;
  border-radius: var(--radius-full);
  background: var(--color-checks-green); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-tile {
  width: 48px; height: 48px; flex: none;
  border-radius: var(--radius-cards);
  background: var(--color-linen-mist); color: var(--color-forest-ink);
  display: inline-flex; align-items: center; justify-content: center;
}

/* Marco para imágenes que aún no existen: el diseño las trae como placeholder,
   así que si el archivo falta se muestra este slot en vez de un icono roto. */
.img-slot {
  background: var(--color-linen-mist);
  border: 1px dashed var(--color-pebble);
  border-radius: var(--radius-cards);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); font-size: 13px; text-align: center; padding: 16px;
  min-height: 140px;
}

/* ============================================================ formularios */

.field { display: flex; flex-direction: column; gap: 6px; }
.field > label, .label {
  font-size: var(--text-caption);
  font-weight: var(--font-weight-semibold);
  color: var(--color-forest-ink);
}
.field .hint { font-size: var(--text-micro); color: var(--text-muted); }

.input, .select {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--color-pebble);
  border-radius: var(--radius-inputs);
  background: var(--color-paper);
  color: var(--text-primary);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input:focus, .select:focus {
  outline: none;
  border-color: var(--color-forest-ink);
  box-shadow: 0 0 0 3px rgba(159, 232, 112, .45);
}
/* Para editar un valor dentro de una tabla: el input de formulario es demasiado
   alto y hace crecer cada fila el doble. */
.input--sm {
  padding: 6px 10px;
  font-size: var(--text-caption);
  font-variant-numeric: tabular-nums;
}
.input::placeholder { color: var(--text-subtle); }
.input[aria-invalid="true"] { border-color: var(--color-alarm-red); }

.select { appearance: none; padding-right: 38px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23163300' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 14px center;
}

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-16); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--spacing-20); }
.stack { display: flex; flex-direction: column; gap: var(--spacing-16); }
.stack--sm { gap: var(--spacing-8); }
.stack--lg { gap: var(--spacing-24); }
.row { display: flex; align-items: center; gap: var(--spacing-12); }
.row--between { justify-content: space-between; }
.row--wrap { flex-wrap: wrap; }
.spacer { flex: 1; }

/* Casilla como píldora seleccionable: es el patrón del sistema para
   competencias y cortes, donde hay que elegir varias de un golpe. */
.check {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  border: 1px solid var(--color-fog);
  border-radius: var(--radius-tags);
  background: var(--color-paper);
  cursor: pointer;
  font-size: var(--text-caption);
  font-weight: var(--font-weight-medium);
  user-select: none;
  transition: background-color .15s ease, border-color .15s ease;
}
.check:hover { background: var(--color-linen-mist); }
.check input { accent-color: var(--color-forest-ink); width: 16px; height: 16px; margin: 0; }
/* Una casilla suelta junto a un botón, no una opción de una rejilla: sin marco,
   para que no compita con el botón que tiene al lado. */
.check--inline {
  border-color: transparent;
  background: transparent;
  padding: 10px 4px;
}
.check--inline:hover { background: transparent; text-decoration: underline; }
.check[data-on="1"] { background: var(--color-linen-mist); border-color: var(--color-forest-ink); }

.check--block { border-radius: var(--radius-cards); width: 100%; }

.check-grid { display: flex; flex-wrap: wrap; gap: var(--spacing-8); }

/* Zona de carga */
.dropzone {
  border: 2px dashed var(--color-pebble);
  border-radius: var(--radius-large-cards);
  padding: var(--spacing-48) var(--spacing-24);
  text-align: center;
  background: var(--color-paper);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
.dropzone:hover, .dropzone[data-drag="1"] {
  border-color: var(--color-checks-green);
  background: var(--color-linen-mist);
}

/* ============================================================ tablas */

.table-wrap { overflow-x: auto; border: 1px solid var(--color-fog); border-radius: var(--radius-cards); }
table.tbl { width: 100%; border-collapse: collapse; font-size: var(--text-caption); }
.tbl th, .tbl td { padding: 11px 14px; text-align: left; border-bottom: 1px solid var(--color-fog); vertical-align: top; }
.tbl th {
  background: var(--color-fog); color: var(--color-forest-ink);
  font-weight: var(--font-weight-semibold); white-space: nowrap;
  position: sticky; top: 0; z-index: 1;
}
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl tbody tr:hover { background: var(--color-linen-mist); }
.tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ============================================================ progreso */

.bar {
  height: 8px; border-radius: var(--radius-full);
  background: var(--color-fog); overflow: hidden;
}
.bar > span {
  display: block; height: 100%; width: 0;
  background: var(--color-checks-green);
  border-radius: inherit;
  transition: width .4s ease;
}
.bar--lime > span { background: var(--color-lime-voltage); }
.bar--thin { height: 5px; }
/* La pasada final en curso (confirmar vacíos, verificación, rescate por RUC),
   bajo la barra general que ya está en el 100 % de las consultas. */
.etapa { margin-top: 12px; }
.etapa__fila { margin-bottom: 6px; }

.metrics { display: flex; flex-wrap: wrap; gap: var(--spacing-24); }
.metric { min-width: 92px; }
.metric .n {
  font-family: var(--font-wise-sans); font-weight: var(--font-weight-black);
  font-size: 28px; line-height: 1.1; color: var(--color-forest-ink);
  letter-spacing: -0.5px; font-variant-numeric: tabular-nums;
}
.metric .k { font-size: var(--text-micro); color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }

.spin {
  width: 16px; height: 16px; flex: none;
  border: 2px solid var(--color-fog);
  border-top-color: var(--color-checks-green);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spin { animation-duration: 2s; }
  .bar > span { transition: none; }
}

/* ============================================================ navegación */

.nav {
  position: sticky; top: 0; z-index: 20;
  background: var(--color-paper);
  border-bottom: 1px solid var(--color-fog);
}
.nav .shell { display: flex; align-items: center; gap: var(--spacing-24); height: 72px; }
.nav__logo { height: 38px; width: auto; }
.nav__links { display: flex; gap: var(--spacing-28); margin-left: var(--spacing-24); }
.nav__links a {
  font-size: var(--text-body-sm); font-weight: var(--font-weight-medium);
  color: var(--color-forest-ink); text-decoration: none;
}
.nav__links a:hover { color: var(--color-checks-green-dark); }

/* Barra de la aplicación (tras iniciar sesión).
   Verde degradado de Alto Checks: oscuro a la izquierda, claro a la derecha. */
.appbar {
  background: linear-gradient(90deg, #0b6b34 0%, #199f5f 55%, #34c47e 100%);
  color: var(--color-paper);
  position: sticky; top: 0; z-index: 20;
}
.appbar .shell { display: flex; align-items: center; gap: var(--spacing-16); height: 64px; }
.appbar__logo { height: 30px; width: auto; filter: brightness(0) invert(1); }
.appbar__tabs { display: flex; gap: 4px; margin-left: var(--spacing-12); flex-wrap: wrap; }
.tab {
  border: 0; background: none; cursor: pointer;
  color: rgba(255,255,255,.86);
  padding: 9px 20px; border-radius: var(--radius-full);
  font-size: var(--text-caption); font-weight: var(--font-weight-semibold);
}
.tab:hover { color: #fff; background: rgba(255,255,255,.14); }
.tab[aria-current="page"] { background: #fff; color: #0b6b34; }

.appbar__right { display: flex; align-items: center; gap: var(--spacing-12); margin-left: auto; }

/* Estado del motor: cuántos carriles hay y si están trabajando. */
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.24);
  border-radius: var(--radius-full);
  padding: 7px 16px; font-size: var(--text-micro); color: #fff;
  white-space: nowrap;
}
.chip b { font-size: var(--text-caption); font-weight: var(--font-weight-bold); }
.chip .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-lime-voltage); flex: none; }
.chip .dot--idle { background: rgba(255,255,255,.6); }
.chip .dot--live { animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .35; } }

.chip--user { gap: 10px; padding-left: 6px; }
.chip--user .av {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: rgba(255,255,255,.25); color: #fff;
  display: grid; place-items: center; font-weight: var(--font-weight-bold); font-size: 12px;
}
.chip--user .nom { line-height: 1.15; text-align: left; }
.chip--user .nom b { display: block; font-size: var(--text-micro); }
.chip--user .nom span { font-size: 9px; letter-spacing: .09em; text-transform: uppercase; opacity: .8; }

.appbar .btn--ghost { background: rgba(255,255,255,.16); color: #fff; border-color: rgba(255,255,255,.24); }
.appbar .btn--ghost:hover { background: rgba(255,255,255,.28); }

/* ============================================================ landing */

.sec { padding: 80px 0; }
.sec--paper { background: var(--color-paper); }
.sec--fog { background: var(--color-fog); }
.sec--mist { background: var(--color-linen-mist); }
.sec--hero { padding: 88px 0 64px; }

.hero { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: var(--spacing-48); align-items: center; }
.hero p { max-width: 46ch; font-size: 20px; line-height: 1.5; margin: 0 0 var(--spacing-32); }
.hero__art {
  border-radius: var(--radius-2xl); overflow: hidden;
  min-height: 320px;
  background: linear-gradient(150deg, var(--color-forest-ink), var(--color-spruce) 62%, var(--color-checks-green));
  display: flex; align-items: center; justify-content: center;
  color: var(--color-lime-voltage); padding: var(--spacing-32);
}
.hero__art img { border-radius: var(--radius-2xl); }

.benefit {
  background: var(--color-paper); border-radius: var(--radius-large-cards);
  padding: var(--card-padding);
  display: flex; flex-direction: column; gap: var(--spacing-20);
  box-shadow: var(--shadow-subtle);
}
.benefit__img { width: 100%; height: 140px; object-fit: cover; border-radius: var(--radius-cards); background: var(--color-linen-mist); }
.benefit h3 { font-size: 22px; font-weight: var(--font-weight-bold); line-height: 1.15; letter-spacing: -0.2px; margin: 0; }
.benefit p { margin: 0; color: var(--text-muted); line-height: 1.5; }

.filter-card {
  background: var(--color-paper); border: 1px solid var(--color-fog);
  border-radius: var(--radius-cards); padding: var(--card-padding);
  display: flex; flex-direction: column; gap: var(--spacing-16);
}
.filter-card h3 { font-size: var(--text-body); font-weight: var(--font-weight-bold); line-height: 1.25; margin: 0; }
.filter-card a {
  margin-top: auto; font-size: 15px; font-weight: var(--font-weight-semibold);
  color: var(--color-forest-ink); text-decoration: underline;
  display: inline-flex; align-items: center; gap: 6px;
}

.contact { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-48); align-items: center; }
.contact p { max-width: 44ch; margin: 0; font-size: var(--text-body); line-height: 1.5; }

.foot { background: var(--color-forest-ink); color: var(--color-paper); padding: 64px 0 40px; }
.foot__top {
  display: flex; justify-content: space-between; gap: var(--spacing-32); flex-wrap: wrap;
  padding-bottom: var(--spacing-32); border-bottom: 1px solid rgba(255,255,255,.12);
}
.foot__logo { height: 38px; width: auto; filter: brightness(0) invert(1); margin-bottom: var(--spacing-16); }
.foot p { color: var(--color-fog); font-size: 15px; line-height: 1.6; margin: 0; }
.foot a { color: var(--color-fog); text-decoration: none; }
.foot__phone {
  font-family: var(--font-wise-sans); font-weight: var(--font-weight-black);
  font-size: 25px; color: var(--color-checks-green); text-decoration: none; letter-spacing: -0.5px;
}
.foot__legal { color: var(--color-pebble); font-size: 13px; margin-top: var(--spacing-24); }

/* ============================================================ app */

/* El área de trabajo va sobre un gris muy claro para que las tarjetas blancas
   se despeguen; la landing en cambio es blanca. */
body.app { background: #f5f7f6; }

.page { padding: var(--spacing-40) 0 var(--spacing-64); min-height: 60vh; }
.page__head { margin-bottom: var(--spacing-24); }
.page__head h1 { font-size: 30px; color: var(--color-forest-ink); letter-spacing: -0.6px; }

/* Encabezado de resultado: antetítulo verde + titular grande y muy pesado. */
.eyebrow {
  font-size: var(--text-micro); font-weight: var(--font-weight-bold);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-checks-green); margin: 0 0 var(--spacing-8);
}
.headline {
  font-size: clamp(34px, 5vw, 52px);
  font-weight: var(--font-weight-black);
  letter-spacing: -1.8px; line-height: 1;
  color: var(--color-obsidian); margin: 0;
}
.headline + .sub { margin: 10px 0 0; color: var(--text-muted); font-size: var(--text-body-sm); }

/* Tarjeta blanca del área de trabajo. Más redondeada y más suave que .card. */
.sheet {
  background: var(--color-paper);
  border-radius: 20px;
  box-shadow: rgba(14, 15, 12, .06) 0 2px 10px, rgba(14, 15, 12, .04) 0 12px 32px;
  padding: var(--spacing-32);
  margin-bottom: var(--spacing-24);
}
.sheet__head { margin-bottom: var(--spacing-20); }
.sheet__head h2 { font-size: var(--text-body); font-weight: var(--font-weight-bold); color: var(--color-obsidian); }
.sheet__head p { margin: 4px 0 0; font-size: var(--text-caption); color: var(--text-muted); }

/* Progreso general: porcentaje enorme a la izquierda, conteo a la derecha. */
.overall { display: flex; align-items: baseline; gap: var(--spacing-16); margin-bottom: var(--spacing-16); }
.overall .k { font-size: var(--text-caption); color: var(--text-muted); }
.overall .v {
  font-size: 40px; font-weight: var(--font-weight-black);
  letter-spacing: -1.5px; color: var(--color-obsidian); line-height: 1;
}
.overall .r { margin-left: auto; font-size: var(--text-caption); color: var(--text-muted); }

/* Fila de cifras separadas por filetes verticales. */
.stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: var(--spacing-24); margin-top: var(--spacing-24);
  padding-top: var(--spacing-20); border-top: 1px solid var(--color-fog);
}
.stats > div + div { border-left: 1px solid var(--color-fog); padding-left: var(--spacing-24); }
.stats .k {
  font-size: 10px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-subtle); margin-bottom: 6px;
}
.stats .v { font-size: var(--text-body-sm); font-weight: var(--font-weight-bold); color: var(--color-obsidian); }

.legend { display: flex; gap: var(--spacing-16); font-size: var(--text-micro); color: var(--text-muted); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

/* ---- fila de persona, plegable ---- */

.prow {
  border-top: 1px solid var(--color-fog);
  padding: var(--spacing-16) var(--spacing-8);
  display: grid; align-items: center; gap: var(--spacing-20);
  grid-template-columns: minmax(180px, 1.4fr) minmax(200px, 2.2fr) 76px 108px 32px;
  cursor: pointer;
  transition: background-color .15s ease;
}
.prow:hover { background: #fafcfb; }
.prow[data-open="1"] { background: #f2faf5; }
.prow__name {
  font-weight: var(--font-weight-bold); color: var(--color-obsidian);
  font-size: var(--text-caption); letter-spacing: .01em;
}
.prow__row { font-size: var(--text-micro); color: var(--text-subtle); margin-top: 2px; }
.prow__nums { display: flex; justify-content: space-between; font-size: var(--text-micro); color: var(--text-muted); margin-bottom: 5px; }
.prow__causas { text-align: center; }
.prow__causas b { display: block; font-size: var(--text-body-sm); font-weight: var(--font-weight-bold); color: var(--color-obsidian); }
.prow__causas span { font-size: 10px; color: var(--text-subtle); }
.prow__chev { color: var(--text-subtle); display: grid; place-items: center; transition: transform .2s ease; }
.prow[data-open="1"] .prow__chev { transform: rotate(-90deg); }

.pbody { padding: var(--spacing-8) var(--spacing-8) var(--spacing-24); }

/* ---- ficha de causa ---- */

.causa {
  border: 1px solid var(--color-fog); border-radius: 14px;
  padding: var(--spacing-20) var(--spacing-24); margin-bottom: var(--spacing-16);
  background: var(--color-paper);
}
.causa__top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.causa__rol { font-size: var(--text-body-sm); font-weight: var(--font-weight-bold); color: var(--color-obsidian); }
.causa__caratula { margin: 6px 0 var(--spacing-20); color: var(--text-primary); font-size: var(--text-caption); }

.causa__meta { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--spacing-20); margin-bottom: var(--spacing-20); }
.causa__meta .k {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-subtle); margin-bottom: 4px;
}
.causa__meta .v { font-size: var(--text-caption); color: var(--color-obsidian); }

.causa h4 {
  font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-muted); margin: 0 0 8px; font-weight: var(--font-weight-semibold);
}

/* Tabla compacta dentro de la ficha: sin bordes exteriores, filete bajo el
   encabezado. La fila de la persona buscada se destaca en verde. */
table.mini { width: 100%; border-collapse: collapse; font-size: var(--text-caption); }
.mini th {
  text-align: left; padding: 8px 12px; font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-subtle);
  font-weight: var(--font-weight-semibold); border-bottom: 1px solid var(--color-fog);
}
.mini td { padding: 9px 12px; border-bottom: 1px solid #f3f5f3; color: var(--text-primary); }
.mini tr:last-child td { border-bottom: none; }
.mini tr.is-person td {
  background: #eefaf3; color: var(--color-checks-green-dark);
  font-weight: var(--font-weight-bold);
}

.disclosure { margin-top: var(--spacing-20); }
.disclosure > summary {
  cursor: pointer; list-style: none;
  font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-muted); font-weight: var(--font-weight-semibold);
  display: flex; align-items: center; gap: 6px;
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before { content: '▸'; transition: transform .15s ease; }
.disclosure[open] > summary::before { transform: rotate(90deg); }
.disclosure__body { margin-top: 10px; max-height: 360px; overflow: auto; }

/* Pie del área de trabajo */
.workfoot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--spacing-16); flex-wrap: wrap;
  font-size: var(--text-micro); color: var(--text-subtle);
  padding: var(--spacing-8) var(--spacing-8) var(--spacing-40);
}
.applegal {
  border-top: 1px solid var(--color-fog); margin-top: var(--spacing-24);
  padding: var(--spacing-24) 0;
  display: flex; justify-content: space-between; gap: var(--spacing-16); flex-wrap: wrap;
  font-size: var(--text-micro); color: var(--text-subtle);
}
.applegal b { color: var(--color-checks-green); font-weight: var(--font-weight-bold); }

/* Login */
.gate { min-height: 100vh; display: grid; place-items: center; background: var(--color-fog); padding: var(--spacing-24); }
.gate__box { width: 100%; max-width: 420px; }
.gate__logo { height: 44px; width: auto; margin: 0 auto var(--spacing-24); }

/* Asistente de pasos */
.steps { display: flex; gap: var(--spacing-8); flex-wrap: wrap; margin-bottom: var(--spacing-32); }
.step {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: var(--radius-full);
  background: var(--color-fog); color: var(--text-muted);
  font-size: var(--text-caption); font-weight: var(--font-weight-semibold);
}
.step[data-on="1"] { background: var(--color-forest-ink); color: var(--color-paper); }
.step[data-done="1"] { background: var(--color-linen-mist); color: var(--color-forest-ink); }
.step .n {
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; font-size: 11px;
  background: rgba(0,0,0,.12);
}
.step[data-on="1"] .n { background: var(--color-lime-voltage); color: var(--color-forest-ink); }

/* Fila de persona en el seguimiento */
.person {
  display: grid; grid-template-columns: 1fr auto; gap: 6px var(--spacing-16);
  padding: var(--spacing-16) 0; border-bottom: 1px solid var(--color-fog);
}
.person:last-child { border-bottom: none; }
.person__name { font-weight: var(--font-weight-semibold); color: var(--color-forest-ink); }
.person__meta { font-size: var(--text-micro); color: var(--text-muted); }
.person__bar { grid-column: 1 / -1; }

/* Aviso */
.notice {
  border-radius: var(--radius-cards); padding: var(--spacing-16) var(--spacing-20);
  border-left: 4px solid var(--color-forest-ink); background: var(--color-fog);
  font-size: var(--text-caption);
}
.notice--warn { background: #fdf3e2; border-left-color: #c98a00; color: #6d4a00; }
.notice--error { background: #fdecec; border-left-color: var(--color-alarm-red); color: #8d1f24; }
.notice--ok { background: var(--color-linen-mist); border-left-color: var(--color-checks-green); }

/* Estado vacío */
.empty { text-align: center; padding: var(--spacing-64) var(--spacing-24); color: var(--text-muted); }
.empty .icon-tile { margin: 0 auto var(--spacing-16); }

/* Modal */
.overlay {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(14, 15, 12, .55);
  display: grid; place-items: center; padding: var(--spacing-24);
  overflow-y: auto;
}
.modal { width: 100%; max-width: 720px; background: var(--color-paper); border-radius: var(--radius-large-cards); padding: var(--spacing-32); }
.modal--wide { max-width: 1040px; }
.modal__head { display: flex; align-items: flex-start; gap: var(--spacing-16); margin-bottom: var(--spacing-20); }
.modal__head h2 { font-size: 24px; color: var(--color-forest-ink); }
.modal__body { max-height: min(64vh, 620px); overflow: auto; }

/* Avisos flotantes */
.toasts { position: fixed; right: var(--spacing-24); bottom: var(--spacing-24); z-index: 80; display: flex; flex-direction: column; gap: var(--spacing-8); max-width: 380px; }
.toast {
  background: var(--color-forest-ink); color: var(--color-paper);
  border-radius: var(--radius-cards); padding: 14px 18px;
  font-size: var(--text-caption); box-shadow: var(--shadow-xl);
  animation: rise .18s ease-out;
}
.toast--error { background: var(--color-alarm-red); }
.toast--ok { background: var(--color-checks-green); }
@keyframes rise { from { transform: translateY(8px); opacity: 0; } }

/* Clave temporal: se muestra UNA vez, así que tiene que saltar a la vista. */
.secret {
  font-family: var(--font-mono); font-size: 20px; letter-spacing: 1px;
  background: var(--color-forest-ink); color: var(--color-lime-voltage);
  padding: 14px 18px; border-radius: var(--radius-cards);
  display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-16);
  word-break: break-all;
}

/* ============================================================ responsive */

@media (max-width: 900px) {
  .hero, .contact { grid-template-columns: 1fr; }
  .grid-3 { grid-template-columns: 1fr 1fr; }
  .sec { padding: 56px 0; }
  .hero__art { min-height: 220px; order: -1; }
}

@media (max-width: 900px) {
  .stats { grid-template-columns: 1fr 1fr; }
  .stats > div + div { border-left: none; padding-left: 0; }
  .causa__meta { grid-template-columns: 1fr 1fr; }
  .prow { grid-template-columns: 1fr 84px 32px; }
  .prow__progress { grid-column: 1 / -1; order: 3; }
}

@media (max-width: 640px) {
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .nav__links { display: none; }
  .sheet { padding: var(--spacing-20); border-radius: 16px; }
  .stats { grid-template-columns: 1fr; gap: var(--spacing-12); }
  .causa__meta { grid-template-columns: 1fr; gap: var(--spacing-12); }
  .causa { padding: var(--spacing-16); }
  .chip--user .nom { display: none; }
  .disclosure__body, .mini { font-size: var(--text-micro); }
  .disclosure__body { overflow-x: auto; }
  .nav .shell, .appbar .shell { gap: var(--spacing-12); }
  .appbar { position: sticky; top: 0; z-index: 20; }
  .appbar .shell { height: auto; padding-top: 12px; padding-bottom: 12px; flex-wrap: wrap; }
  .appbar__user .who { display: none; }
  .panel, .card--lg { padding: var(--spacing-20); border-radius: var(--radius-2xl); }
  .metrics { gap: var(--spacing-16); }
  .metric .n { font-size: 22px; }
  .toasts { left: var(--spacing-16); right: var(--spacing-16); max-width: none; }
}

@media print {
  .nav, .appbar, .toasts, .btn { display: none !important; }
}

/* Gráficos del estado de la OJV. Se generan como SVG inline desde app.js: sin
   librerías ni CDN, igual que los iconos. Sólo hace falta que escalen. */
.graf { width: 100%; height: auto; display: block; overflow: visible; }

/* --- Cumplimiento (Ley 21.719) ---------------------------------------------
   Cabecera centrada con un sello, y seis afirmaciones en la misma retícula de
   tres que ya usa la sección de búsquedas. Se apoya en .icon-pill (el círculo
   verde de la marca): en esta sección lee como visto bueno, que es justo lo que
   tiene que transmitir. */
.cumple__head { text-align: center; max-width: 62ch; margin: 0 auto var(--spacing-40); }
.cumple__head .badge { margin-bottom: var(--spacing-16); }
.cumple__head .section-lead { margin-bottom: 0; }
.cumple__sello {
  width: 64px; height: 64px; margin: 0 auto var(--spacing-20);
  border-radius: var(--radius-full);
  background: var(--color-checks-green); color: #fff;
  display: flex; align-items: center; justify-content: center;
  /* El halo lo separa del fondo fog sin necesidad de una imagen. */
  box-shadow: 0 0 0 10px rgba(34, 181, 115, 0.14);
}
.icon-pill--sm { width: 36px; height: 36px; }
.cumple-card {
  background: var(--color-paper); border: 1px solid var(--color-fog);
  border-radius: var(--radius-cards); padding: var(--spacing-20);
  display: flex; align-items: center; gap: var(--spacing-16);
}
.cumple-card h3 {
  font-size: var(--text-body); font-weight: var(--font-weight-semibold);
  line-height: 1.25; margin: 0; color: var(--color-forest-ink);
}

/* --- Desglose de certeza en la fila de la persona --------------------------
   Un total suelto ("12 causas") no dice si son suyas o si son homónimos. El
   desglose va DEBAJO del número, en líneas cortas, sin robarle protagonismo. */
.certeza { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.certeza span { font-size: 10px; line-height: 1.3; white-space: nowrap; }
.certeza__ok {
  color: var(--color-checks-green-dark);
  font-weight: var(--font-weight-semibold);
}
.certeza__duda { color: #8a5a00; }

/* La línea donde deja de ser firme lo que se está leyendo. Mismo ámbar que
   .badge--warn y .notice--warn, para que signifique lo mismo en toda la app. */
.certeza-corte {
  display: flex; align-items: center; gap: var(--spacing-8);
  margin: var(--spacing-24) 0 var(--spacing-16);
  padding: var(--spacing-8) var(--spacing-16);
  background: #fdf3e2; color: #8a5a00;
  border-radius: var(--radius-cards);
  font-size: var(--text-caption); font-weight: var(--font-weight-semibold);
}

/* Una causa "confirmada" que sólo calzó por NOMBRE. Va dentro de la tarjeta y
   no como un badge suelto porque hay que leer la frase entera: el matiz es que
   coincidan los cuatro componentes del nombre no identifica a nadie de forma
   única, y sin la explicación el sello verde de al lado dice lo contrario. */
.aviso-nombre {
  display: flex; align-items: flex-start; gap: var(--spacing-8);
  margin: var(--spacing-8) 0 0;
  padding: var(--spacing-8) var(--spacing-12);
  background: #fdf3e2; color: #6d4a00;
  border-left: 3px solid #c98a00;
  border-radius: var(--radius-cards);
  font-size: var(--text-caption); line-height: 1.45;
}
.aviso-nombre svg { flex: 0 0 auto; margin-top: 1px; }

/* La contraparte del anterior: la persona NO es contra quien va la causa.
   Comparte la forma para que se lean como el mismo tipo de nota, y cambia el
   color porque dicen cosas opuestas — el ámbar avisa de un riesgo, éste da una
   tranquilidad. Dos avisos del mismo color se leerían como dos problemas. */
.aviso-calidad {
  display: flex; align-items: flex-start; gap: var(--spacing-8);
  margin: var(--spacing-8) 0 0;
  padding: var(--spacing-8) var(--spacing-12);
  background: #e6f7ee; color: var(--color-checks-green-dark);
  border-left: 3px solid var(--color-checks-green);
  border-radius: var(--radius-cards);
  font-size: var(--text-caption); line-height: 1.45;
}
.aviso-calidad svg { flex: 0 0 auto; margin-top: 1px; }

/* Separador entre "sube un archivo" y "busca a una persona". Son dos caminos
   alternativos al mismo sitio, no un paso después de otro, y sin esta línea se
   leían como una secuencia. */
.separador-o {
  display: flex; align-items: center; gap: var(--spacing-16);
  margin: var(--spacing-8) 0; color: var(--text-muted);
  font-size: var(--text-caption);
}
.separador-o::before, .separador-o::after {
  content: ""; flex: 1; height: 1px; background: var(--color-border, #e3e6e4);
}

/* Riesgo de homónimos: cinco segmentos, no una barra continua.
   El nivel es uno de cinco valores discretos, así que interpolar el color
   —como sí hace el mapa de calor de salud— insinuaría una precisión que la
   estimación no tiene. Cinco reglas, cinco colores. */
.homon { display: flex; gap: 3px; align-items: center; }
.homon > span {
  width: 20px; height: 8px; border-radius: 2px;
  background: var(--color-fog);
}
.homon[data-nivel="1"] > span:nth-child(-n+1),
.homon[data-nivel="2"] > span:nth-child(-n+2) { background: var(--color-checks-green); }
.homon[data-nivel="3"] > span:nth-child(-n+3) { background: var(--color-warn-amber); }
.homon[data-nivel="4"] > span:nth-child(-n+4) { background: #e8742d; }
.homon[data-nivel="5"] > span:nth-child(-n+5) { background: var(--color-alarm-red); }

.riesgo { margin: var(--spacing-12) 0 0; }
.riesgo__fila { display: flex; align-items: center; gap: var(--spacing-12); }
.riesgo__glosa { font-size: var(--text-caption); font-weight: var(--font-weight-semibold); }
.riesgo__embudo {
  margin: 6px 0 0; font-size: var(--text-micro); color: var(--text-muted);
  line-height: 1.5;
}

/* Lista de personas añadidas a mano. Cada fila lleva sus barras de riesgo:
   verlas al ir sumando gente es lo que permite notar a tiempo que alguien tiene
   homónimos, en vez de descubrirlo al final en el informe. */
.lista-personas { margin-top: var(--spacing-16); }
.lista-personas__fila {
  display: flex; align-items: center; gap: var(--spacing-12);
  padding: var(--spacing-8) 0;
  border-bottom: 1px solid var(--color-fog);
}
.lista-personas__fila:last-child { border-bottom: 0; }
.lista-personas__nombre { flex: 1; font-weight: var(--font-weight-medium); }

/* Selector de velocidad.

   La duración es lo único que se compara aquí, así que la duración ES el
   gráfico: tres barras proporcionales al tiempo, y se lee de un vistazo que uno
   es el triple de largo que otro sin leer un número.

   Antes eran tres tarjetas repitiendo seis campos cada una —precio, tiempo,
   carriles, minutos de preparación, insignia y motivo—: dieciocho datos para
   tomar una decisión entre tres opciones, y nada que dominara. Los datos de
   apoyo bajaron a una sola línea, la del modo elegido.

   Sigue siendo un radiogroup nativo por dentro: se navega con las flechas y un
   lector de pantalla lo anuncia como lo que es. */
.modos {
  display: grid;
  gap: 2px;
  padding: 6px;
  border: 1px solid var(--color-fog);
  border-radius: var(--radius-cards);
  background: var(--color-paper);
}

.modo {
  display: grid;
  /* punto · nombre · barra · tiempo · precio */
  grid-template-columns: 16px 58px 1fr auto auto;
  align-items: center;
  gap: var(--spacing-16);
  padding: 14px var(--spacing-16);
  border-radius: var(--radius-cards);
  cursor: pointer;
  user-select: none;
  transition: background-color .15s ease;
}
.modo:hover { background: var(--color-linen-mist); }
.modo[data-on="1"] { background: var(--color-linen-mist); }

/* El radio de verdad: invisible pero presente, para no inventar un control. */
.modo input {
  position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
  pointer-events: none;
}
.modo:has(input:focus-visible) {
  outline: 2px solid var(--color-forest-ink);
  outline-offset: 1px;
}

.modo__punto {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid var(--color-pebble);
  background: var(--color-paper);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.modo[data-on="1"] .modo__punto {
  border-color: var(--color-forest-ink);
  /* El relleno con un box-shadow interior deja el anillo limpio y evita un
     elemento extra sólo para el punto de dentro. */
  box-shadow: inset 0 0 0 3px var(--color-checks-green);
}

.modo__nombre {
  font-weight: var(--font-weight-semibold);
  color: var(--color-forest-ink);
}

/* La barra ES la comparación: su largo es la duración del lote, así que el modo
   más lento la tiene llena y el más rápido corta. Encima del relleno va cuánto
   se gana, centrado en su punto medio — el ahorro se lee sobre el trozo que lo
   produce, no en una columna aparte. El hueco de arriba se reserva en las tres
   filas aunque sólo una o dos lleven insignia: si no, los rieles bailan. */
.modo__barra { position: relative; padding-top: 20px; }
.modo__riel {
  display: block;
  height: 10px;
  border-radius: var(--radius-full);
  background: var(--color-fog);
  overflow: hidden;
}
/* La referencia va en AZUL y no en gris. Es la barra más larga de la pantalla, y
   en gris se leía como algo apagado o inservible cuando en realidad es la tarifa
   base y el modo por defecto. El azul de señal la deja como lo que es —el punto
   de partida contra el que se comparan los verdes— sin competir con ellos. */
.modo__riel > i {
  display: block; height: 100%;
  border-radius: inherit;
  background: var(--color-signal-blue);
  /* Ni al 100 % ni apagada: la de Lite es la barra MÁS LARGA de la pantalla, y a
     plena intensidad le grita por encima a los verdes, que son los que llevan la
     buena noticia. Aquí se lee azul sin robar el foco. */
  opacity: .72;
  transition: width .35s ease, background-color .15s ease, opacity .15s ease;
}
/* El color va por VELOCIDAD, no por selección. Marcar con verde lo elegido
   pintaba de verde la barra MÁS LARGA cuando se elegía el modo lento, que es el
   mensaje contrario: el verde lleno se lee como "esto está bien". Ahora el verde
   crece según cuánto tiempo ahorra, y lo elegido se distingue por el punto y el
   fondo de la fila, que es para lo que están. */
.modo[data-vel="1"] .modo__riel > i {
  background: var(--color-checks-green);
  opacity: .85;
}
.modo[data-vel="2"] .modo__riel > i {
  background: var(--color-checks-green-dark);
  opacity: 1;
}

.modo__x {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: var(--text-micro);
  font-weight: var(--font-weight-semibold);
  color: var(--color-checks-green-dark);
  background: #e6f7ee;
  border-radius: var(--radius-tags);
  padding: 2px 8px;
  line-height: 1.4;
}

.modo__tiempo {
  font-weight: var(--font-weight-semibold);
  color: var(--color-obsidian);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Mientras la estimación viaja. No es un dato: no debe pesar como uno. */
.modo__calculando {
  font-weight: var(--font-weight-regular);
  color: var(--text-muted);
}

/* Precio POR PERSONA, con la unidad debajo en pequeño: sin ella «US$1,50» se
   lee como el total del lote, que es justo la confusión que había. */
.modo__precio {
  min-width: 96px;
  text-align: right;
  color: var(--color-obsidian);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.modo__precio small {
  display: block;
  font-size: var(--text-micro);
  font-weight: var(--font-weight-regular);
  color: var(--text-muted);
}

/* Un modo que en ESTE lote no gana tiempo. Se muestra apagado y no se esconde:
   esconderlo dejaría la sospecha de que la app se guarda la opción buena, y la
   barra —más larga que la de Lite— ya explica sola por qué no conviene. */
.modo[data-veto="1"] { cursor: not-allowed; opacity: .5; }
.modo[data-veto="1"]:hover { background: transparent; }
.modo[data-veto="1"] .modo__riel > i {
  background: var(--color-warn-amber);
  opacity: 1;
}

.modos__detalle {
  margin: var(--spacing-12) 0 0;
  font-size: var(--text-caption);
  color: var(--text-muted);
}
.modos__nota {
  margin: var(--spacing-8) 0 0;
  font-size: var(--text-micro);
  color: var(--text-muted);
  line-height: 1.5;
}

/* En pantalla angosta la barra se va a su propia línea: comprimirla a 40 px la
   dejaría sin poder comunicar la proporción, que es todo su trabajo. */
@media (max-width: 640px) {
  .modo {
    grid-template-columns: 16px 1fr auto;
    gap: var(--spacing-8) var(--spacing-12);
    padding: 12px var(--spacing-12);
  }
  /* Los CINCO hijos van colocados a mano. Reubicar sólo algunos deja a los
     demás en auto-colocación y se montan unos sobre otros — el nombre acababa
     encima de la barra. */
  .modo__punto  { grid-area: 1 / 1; }
  .modo__nombre { grid-area: 1 / 2; }
  .modo__precio { grid-area: 1 / 3; min-width: 0; }
  .modo__barra  { grid-area: 2 / 2; }
  .modo__tiempo { grid-area: 2 / 3; font-size: var(--text-caption); align-self: end; }
  /* En angosto la insignia comparte línea con el nombre del modo, así que se
     pega al riel en vez de flotar 20 px por encima. */
  .modo__barra { padding-top: 16px; }
  .modo__x { font-size: 10px; padding: 1px 6px; }
}

/* Barra de carga del servidor, en la cabecera.

   Sustituye al chip «N carriles · Motor en marcha», que decía cuántos carriles
   EXISTEN —un número fijo— y por tanto no cambiaba nunca ni respondía nada. Lo
   que hace falta saber antes de lanzar es si la máquina está ocupada, porque de
   eso depende que la búsqueda vaya lenta.

   Vive sobre la cabecera oscura, así que la pista es blanca translúcida y no
   `--color-fog`, que ahí desaparecería. */
.carga {
  position: relative;
  display: inline-flex; align-items: center; gap: 9px;
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.24);
  border-radius: var(--radius-full);
  padding: 6px 14px 6px 11px;
  white-space: nowrap;
  cursor: default;
  color: #fff;
}
.carga:focus-visible { outline: 2px solid var(--color-lime-voltage); outline-offset: 2px; }

/* Dos líneas, igual que el chip de usuario de al lado: sin el rótulo, una barra
   con un porcentaje junto al avatar se lee como saldo o créditos gastados. */
.carga__cuerpo { display: flex; flex-direction: column; gap: 3px; }
.carga__linea { display: flex; align-items: center; gap: 9px; }
.carga__rotulo {
  font-size: 9px; letter-spacing: .09em; text-transform: uppercase;
  opacity: .8; line-height: 1;
}
/* El icono de medidor da el sentido antes de leer nada. Baja de opacidad para
   que no compita con la barra, que es el dato. */
.carga > svg { flex: none; opacity: .85; }

.carga__pista {
  width: 64px; height: 6px;
  border-radius: var(--radius-full);
  background: rgba(255,255,255,.22);
  overflow: hidden;
}
.carga__pista > i {
  display: block; height: 100%; width: 0;
  border-radius: inherit;
  /* El ancho se anima largo y suave: la carga sube a saltos —un barrido que
     arranca la dispara— y una transición corta se ve como un parpadeo. */
  transition: width 1.2s cubic-bezier(.4, 0, .2, 1), background-color .6s ease;
  background: var(--color-lime-voltage);
}
.carga__pct {
  font-size: var(--text-caption);
  font-weight: var(--font-weight-bold);
  color: #fff;
  font-variant-numeric: tabular-nums;
  /* Ancho fijo: sin esto la barra se desplaza un pixel cada vez que el número
     pasa de 9 a 10 o de 99 a 100, y eso se ve como un temblor constante. */
  min-width: 34px; text-align: right;
}

/* Verde mientras hay holgura, ámbar cuando trabaja, rojo cuando está exigido.
   Los cortes viven en el servidor (`carga.py`), que es quien sabe a partir de
   dónde las consultas se alargan; aquí sólo se pinta lo que decidió. */
.carga[data-nivel="cargado"] .carga__pista > i { background: var(--color-warn-amber); }
.carga[data-nivel="saturado"] .carga__pista > i { background: #ff6b5a; }
/* Sólo el rojo late. Una animación permanente en el estado normal se vuelve
   ruido de fondo y deja de significar nada justo cuando hay que notarla. */
.carga[data-nivel="saturado"] .carga__pista > i { animation: carga-late 1.8s ease-in-out infinite; }
@keyframes carga-late { 50% { opacity: .55; } }

/* El globo. Nativo `title` tarda un segundo y se pinta como el sistema; éste
   aparece al instante y va con el resto. */
.carga__globo {
  position: absolute; top: calc(100% + 10px); right: 0;
  width: 232px;
  padding: 10px 12px;
  background: var(--color-forest-ink);
  color: var(--color-paper);
  border-radius: var(--radius-cards);
  box-shadow: var(--shadow-lg);
  font-size: var(--text-micro); line-height: 1.5;
  opacity: 0; visibility: hidden;
  transform: translateY(-4px);
  transition: opacity .15s ease, transform .15s ease, visibility .15s;
  z-index: 40;
  white-space: normal;
}
.carga__globo strong { display: block; margin-bottom: 3px; color: var(--color-lime-voltage); }
.carga:hover .carga__globo,
.carga:focus-visible .carga__globo {
  opacity: 1; visibility: visible; transform: translateY(0);
}

/* En pantalla angosta la cabecera va justa: se deja el porcentaje, que es el
   dato, y se recorta la pista. */
@media (max-width: 640px) {
  .carga { padding: 6px 10px; gap: 7px; }
  .carga__pista { width: 30px; }
  .carga__rotulo { display: none; }
  .carga__globo { width: 200px; }
}

/* Quien pide menos animación no quiere una barra latiendo en la cabecera. */
@media (prefers-reduced-motion: reduce) {
  .carga__pista > i { transition: none; animation: none; }
}

/* ============================================================== SubCheck ===
   Buscador de empresas y semáforo de riesgo de contratistas. */

.sub-buscador { position: relative; }

/* La lista flota sobre el panel en vez de empujarlo: si empujara, cada tecla
   movería el resto de la pantalla y el ojo perdería el sitio. */
.sub-lista {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 4px);
  max-height: 330px; overflow-y: auto;
  background: var(--surface-paper);
  border: 1px solid var(--color-fog); border-radius: var(--radius-cards);
  box-shadow: var(--shadow-lg);
}
.sub-lista[hidden] { display: none; }

.sub-conteo, .sub-vacio {
  padding: 10px 14px; font-size: var(--text-micro); color: var(--text-muted);
}
.sub-conteo { border-bottom: 1px solid var(--color-fog); background: var(--surface-fog); }

.sub-op { padding: 10px 14px; cursor: pointer; border-bottom: 1px solid var(--color-fog); }
.sub-op:last-child { border-bottom: 0; }
.sub-op:hover, .sub-op[aria-selected="true"] { background: var(--surface-linen-mist); }
.sub-op__nom {
  font-size: var(--text-body-sm); font-weight: var(--font-weight-medium);
  color: var(--text-primary); display: flex; align-items: center; gap: 8px;
}
/* Las señas van en una línea aparte y en gris: son para desempatar entre
   homónimas, no para leerlas todas. Hacen falta porque hay 104 empresas
   llamadas «SERVICIOS INTEGRALES SPA» y entre ellas el RUT no ayuda a elegir. */
.sub-op__meta {
  display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 3px;
  font-size: var(--text-micro); color: var(--text-muted);
}

/* --- el semáforo --- */
.semaforo {
  display: flex; align-items: center; gap: 16px; margin-top: 16px;
  padding: 20px 24px; border-radius: var(--radius-large-cards);
  border: 1px solid var(--color-fog); background: var(--surface-paper);
  border-left: 6px solid var(--color-pebble);
}
.semaforo__luz {
  flex: none; width: 22px; height: 22px; border-radius: var(--radius-full);
  background: var(--color-pebble);
}
.semaforo__texto { display: flex; flex-direction: column; gap: 3px; }
.semaforo__texto b { font-size: var(--text-body-sm); color: var(--text-primary); }
.semaforo__texto span { font-size: var(--text-caption); color: var(--text-muted); }

.semaforo[data-luz="verde"] { border-left-color: var(--color-checks-green); }
.semaforo[data-luz="verde"] .semaforo__luz { background: var(--color-checks-green); }
.semaforo[data-luz="amarillo"] { border-left-color: var(--color-warn-amber); }
.semaforo[data-luz="amarillo"] .semaforo__luz { background: var(--color-warn-amber); }
.semaforo[data-luz="rojo"] { border-left-color: var(--color-alarm-red); }
.semaforo[data-luz="rojo"] .semaforo__luz {
  background: var(--color-alarm-red);
  /* Sólo el rojo late, por la misma razón que en la barra de carga: una
     animación permanente en el estado normal se vuelve ruido de fondo y deja de
     significar nada justo cuando hay que notarla. */
  animation: semaforo-late 1.8s ease-in-out infinite;
}
.semaforo[data-luz="sin_datos"] { border-left-color: var(--color-signal-blue); }
.semaforo[data-luz="sin_datos"] .semaforo__luz { background: var(--color-signal-blue); }

@keyframes semaforo-late {
  0%, 100% { box-shadow: 0 0 0 0 rgba(203, 39, 47, .45); }
  60%      { box-shadow: 0 0 0 9px rgba(203, 39, 47, 0); }
}

/* Una insignia que además es un interruptor (las banderas del panel de
   administración). Hereda el aspecto de `.badge` y sólo añade que se pueda
   pulsar. */
.badge--boton {
  border: 0; cursor: pointer; font: inherit; font-size: var(--text-micro);
  font-weight: var(--font-weight-semibold);
}
.badge--boton:hover { filter: brightness(.95); }
.badge--boton:disabled { opacity: .5; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .semaforo[data-luz="rojo"] .semaforo__luz { animation: none; }
}

/* La cabecera con cuatro pestañas ya no cabe holgada en un portátil.
   `.appbar__tabs` tiene `flex-wrap`, así que al apretarse no desbordaba: se
   partía en dos filas y la barra crecía a 100 px de alto, con "Administración"
   sola en un segundo renglón.
   Antes de llegar a eso se recorta lo prescindible —el rótulo de la barra de
   carga y el rol bajo el nombre, que son glosas, no datos— y se aprietan las
   pestañas. El porcentaje, el nombre y las cuatro pestañas siguen enteros. */
@media (max-width: 1180px) {
  .appbar .shell { gap: var(--spacing-12); }
  .appbar__tabs { margin-left: 4px; gap: 2px; }
  .tab { padding: 9px 13px; }
  .carga__rotulo { display: none; }
  .chip--user .nom span { display: none; }
  .chip--user .nom b { font-size: var(--text-caption); }
}

/* En móvil la cabecera se reparte en DOS filas fijas —marca y controles
   arriba, pestañas abajo— en vez de dejar que el `flex-wrap` decida.

   Antes se acomodaba solo, y con tres pestañas salían dos filas; al aparecer
   SubCheck se fue a tres y la cabecera ocupaba 200 px, un cuarto de la pantalla
   de un teléfono. Dándole a las pestañas su propia fila el alto deja de
   depender de cuántas haya: con tres o con cuatro, dos filas.

   Con cinco (un administrador ve también la API) la fila ya no cabe en un
   teléfono angosto, y centrada y sin quiebre se salía por los DOS lados: la
   primera pestaña quedaba fuera de la pantalla y no había cómo llegar a ella.
   `safe center` la centra mientras cabe y, si no, la alinea al inicio y la
   fila se desliza de lado. */
@media (max-width: 640px) {
  .appbar__right { order: 2; }
  .appbar__tabs {
    order: 3; width: 100%; margin-left: 0;
    justify-content: center; gap: 2px; flex-wrap: nowrap;
    justify-content: safe center; overflow-x: auto;
  }
  .tab { padding: 7px 11px; font-size: var(--text-micro); flex: none; }
}

/* ================================================================== API ===
   La pestaña «API» (claves, webhook, uso y un ejemplo para empezar) y lo que
   se le sumó a la administración. */

/* La clave de API y el secreto del webhook son mucho más largos que una
   contraseña temporal: al tamaño de ésta ocuparían tres renglones. */
.secret--largo { font-size: 15px; letter-spacing: 0; }

/* Un ejemplo para copiar y pegar en una terminal. Oscuro como el bloque de la
   clave, para que se lea como código y no como texto de la página; el botón
   flota en la esquina para no robarle una línea. */
.codigo { position: relative; margin-top: var(--spacing-8); }
.codigo pre {
  margin: 0;
  padding: 16px 112px 16px 18px;
  background: var(--color-forest-ink); color: var(--color-paper);
  border-radius: var(--radius-cards);
  font-family: var(--font-mono); font-size: var(--text-micro); line-height: 1.6;
  white-space: pre; overflow-x: auto;
}
.codigo .btn {
  position: absolute; top: 8px; right: 8px;
  background: rgba(255,255,255,.15); color: #fff;
}
.codigo .btn:not([disabled]):hover { background: rgba(255,255,255,.28); }

/* Cinco pestañas en la cabecera (un administrador ve todas: SubCheck y API
   incluidas) no caben con el aire que tenían cuatro, ni siquiera a todo el
   ancho. La marca `appbar--apretada` la pone appbar() cuando hay más de
   cuatro: se aprietan siempre las pestañas, un poco más en portátil, y en
   uno chico el nombre del usuario cede su sitio al avatar, que ya lo
   identifica. En móvil manda el bloque de la cabecera de más arriba. */
@media (min-width: 641px) {
  .appbar--apretada .appbar__tabs { margin-left: 4px; gap: 2px; }
  .appbar--apretada .tab { padding: 9px 15px; }
}
@media (min-width: 641px) and (max-width: 1180px) {
  .appbar--apretada .tab { padding: 9px 12px; }
}
@media (min-width: 641px) and (max-width: 1100px) {
  .appbar--apretada .chip--user .nom { display: none; }
}
