/* ==========================================================================
   UVLIS — kit de componentes
   Lo comparten UVLIS y todos sus módulos (los módulos lo enlazan en
   /kit/css/kit.css, detrás de /kit/css/tokens.css).

   Regla: aquí no hay ni un color, tamaño de letra, radio, alto de control ni
   duración literal. Todo sale de tokens.css, que genera el módulo Diseño.
   Si hace falta un valor nuevo, se añade al sistema desde Diseño.
   ========================================================================== */

/* ── Tipografía (servida en local; rutas relativas para que valgan en /kit/) */
@font-face { font-family: "Poppins"; font-weight: 400; font-display: swap; src: url(../fonts/poppins-400.woff2) format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 500; font-display: swap; src: url(../fonts/poppins-500.woff2) format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 600; font-display: swap; src: url(../fonts/poppins-600.woff2) format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 700; font-display: swap; src: url(../fonts/poppins-700.woff2) format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 800; font-display: swap; src: url(../fonts/poppins-800.woff2) format("woff2"); }

/* ── Base ────────────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
/* Sin el zoom del doble toque en el móvil (la app instalada incluida): `manipulation` deja
   desplazar y pellizcar, pero no amplía al tocar dos veces ni retrasa el toque. Va en TODO
   elemento (con 0 de especificidad, así que un `touch-action` propio —asas de arrastrar,
   mapas— le gana): en `html` solo no basta, cada zona con scroll corta la herencia. */
*, html, body { touch-action: manipulation; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Un Servicio de UVLIS a pantalla completa en el móvil (kit/js/vivo-modulo.js pone
   html.uvlis-movil y las variables): lo que no tiene su barra —una bienvenida, un alta—
   queda por debajo de «Atrás» y por encima del dock. Cada servicio lo anula donde tiene
   su barra, que ya se coloca sola junto a «Atrás». */
html.uvlis-movil body { padding-top: var(--uvlis-despeje, 0px); padding-bottom: var(--uvlis-abajo, 0px); }

html, body { margin: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font: var(--t-cuerpo);
  letter-spacing: var(--t-cuerpo-ls);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background var(--slow), color var(--slow);
}

button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p { margin: 0; }

/* Un `display` de autor pisa el `display:none` de [hidden] (lección de Diagramas). */
[hidden] { display: none !important; }

:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* Iconos de trazo: 24×24, trazo 2, extremos redondos. */
svg.i {
  width: 18px; height: 18px; flex: none;
  fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

code, pre { font-family: var(--font-mono); }

/* ── Página ──────────────────────────────────────────────────────────── */
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  margin-bottom: 26px;
  min-height: 40px;
}
.page-head h1 { font: var(--t-titulo); letter-spacing: var(--t-titulo-ls); color: var(--ink); }
.page-head p { font: var(--t-subtitulo); letter-spacing: var(--t-subtitulo-ls); color: var(--ink-soft); margin-top: 4px; }

/* La piel de todo lo que es panel. */
.card {
  position: relative;
  background: var(--panel);
  border: 2px solid var(--panel-stroke);
  border-radius: var(--r-xl);
  padding: 24px;
}
.card h2 { font: var(--t-seccion); letter-spacing: var(--t-seccion-ls); }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.card-head p { font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-soft); }
.stack { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

/* ── Botones ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: var(--control-alto); padding: 0 20px;
  border: 1px solid transparent; border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink);
  font: var(--t-boton); letter-spacing: var(--t-boton-ls);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--fast), transform var(--fast), opacity var(--fast), filter var(--fast);
}
.btn:hover { background: var(--surface-hi); }
.btn:active { transform: scale(var(--press)); }
.btn[disabled] { opacity: 0.45; pointer-events: none; }
.btn svg.i { width: 16px; height: 16px; }
.btn-primary { background: var(--primary); color: var(--primary-ink); }
.btn-primary:hover { background: var(--primary); filter: brightness(1.15); }
.btn-danger { background: transparent; color: var(--pink); }
.btn-danger:hover { background: color-mix(in srgb, var(--pink) 12%, transparent); }
.btn-plain { background: transparent; }
.btn-plain:hover { background: var(--item-on); }
.btn-sm { height: var(--control-alto-sm); padding: 0 14px; font: var(--t-boton-sm); letter-spacing: var(--t-boton-sm-ls); }

.icon-btn {
  display: grid; place-items: center;
  width: 36px; height: 36px; flex: none;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-soft);
  cursor: pointer;
  transition: background var(--fast), color var(--fast), transform var(--fast);
}
.icon-btn:hover { background: var(--item-on); color: var(--ink); }
.icon-btn:active { transform: scale(var(--press-icono)); }

/* Botón redondo gris (el de contraer la barra lateral). */
.round-btn {
  display: grid; place-items: center;
  width: 40px; height: 40px; flex: none;
  border: 0; border-radius: 50%;
  background: var(--round); color: var(--round-ink);
  cursor: pointer;
  transition: transform var(--fast), filter var(--fast);
}
.round-btn:hover { filter: brightness(0.95); }
.round-btn:active { transform: scale(var(--press-icono)); }
.round-btn svg { width: 20px; height: 20px; stroke-width: 3.2; transition: transform var(--slow); }

/* ── Campos ──────────────────────────────────────────────────────────── */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 18px; }
.form-grid .ancho { grid-column: 1 / -1; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > span { font: var(--t-etiqueta); letter-spacing: var(--t-etiqueta-ls); color: var(--ink-soft); padding-left: 4px; }
.field > span em { font-style: normal; font-weight: 400; color: var(--ink-faint); }
.field input, .field select, .field textarea {
  width: 100%; height: var(--campo-alto);
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  font: var(--t-campo); letter-spacing: var(--t-campo-ls);
  transition: border-color var(--fast), background var(--fast), box-shadow var(--fast);
}
.field textarea { height: auto; min-height: 96px; padding: 11px 14px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-faint); font-weight: 400; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  background: var(--surface-hi);
  border-color: color-mix(in srgb, var(--blue) 55%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 14%, transparent);
}
.field input[disabled] { color: var(--ink-soft); background: transparent; }
.field .nota { font: var(--t-etiqueta); font-weight: 400; color: var(--ink-faint); padding-left: 4px; }
.field .seg { align-self: flex-start; }
.form-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 22px; }
/* En el teléfono los botones se reparten la fila (y, si no caben, bajan): nunca se salen de la caja. */
@media (max-width: 560px) { .form-foot .btn { flex: 1 1 auto; } }
.form-foot .izq { margin-right: auto; }
.error-msg {
  font: var(--t-texto); font-weight: 500;
  color: var(--pink);
  background: color-mix(in srgb, var(--pink) 10%, transparent);
  border-radius: var(--r-sm);
  padding: 8px 12px;
}

/* Control segmentado: una opción entre 2–4. */
.seg {
  display: inline-flex; gap: 2px;
  padding: 4px;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--line);
}
.seg button {
  height: var(--control-alto-sm); padding: 0 16px;
  border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--ink-soft);
  font: var(--t-boton-sm); letter-spacing: var(--t-boton-sm-ls);
  cursor: pointer;
  transition: background var(--fast), color var(--fast), box-shadow var(--fast);
}
.seg button:hover { color: var(--ink); }
.seg button b { font-weight: 600; margin-left: 6px; opacity: 0.55; }   /* contador opcional */
.seg button.on { background: var(--surface-hi); color: var(--ink-strong); box-shadow: var(--shadow-sm); }

/* ── Buscador: campo de búsqueda en píldora (con su lupa) ────────────── */
.buscador {
  flex: 1; min-width: 220px;
  display: flex; align-items: center; gap: 10px;
  height: var(--control-alto);
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-faint);
  transition: border-color var(--fast), background var(--fast), box-shadow var(--fast);
}
.buscador:focus-within {
  background: var(--surface-hi);
  border-color: color-mix(in srgb, var(--blue) 55%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 14%, transparent);
}
.buscador svg { width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.buscador input { flex: 1; min-width: 0; border: 0; background: none; outline: none; font: var(--t-campo); color: var(--ink); }
.buscador input::placeholder { color: var(--ink-faint); font-weight: 400; }
.herramientas { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.seg button[disabled] { opacity: 0.5; pointer-events: none; }

/* Interruptor: sí/no de una opción. Una casilla real (teclado y lector de
   pantalla) con piel de interruptor. `.opciones` los apila en filas con icono. */
.interruptor { position: relative; display: inline-flex; flex: none; cursor: pointer; }
.interruptor input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: inherit; }
.interruptor .pista-int {
  width: 44px; height: 26px; padding: 3px;
  border-radius: var(--r-pill);
  background: var(--round);
  transition: background var(--fast);
}
.interruptor .pista-int::after {
  content: ''; display: block;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--round-ink);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-lenta) var(--ease), background var(--fast);
}
.interruptor input:checked + .pista-int { background: var(--primary); }
.interruptor input:checked + .pista-int::after { transform: translateX(18px); background: var(--primary-ink); }
.interruptor input:focus-visible + .pista-int { box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 24%, transparent); }
.interruptor input:disabled { cursor: default; }
.interruptor input:disabled + .pista-int { opacity: 0.5; }

.opciones { display: flex; flex-direction: column; gap: 6px; }
.opcion {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  cursor: pointer;
}
.opcion .ico {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px;
  border-radius: var(--r-md);
  background: var(--surface-hi); color: var(--icon);
}
.opcion .ico svg { width: 20px; height: 20px; }
.opcion .txt { display: flex; flex-direction: column; min-width: 0; margin-right: auto; }
.opcion .txt strong { font: var(--t-campo); letter-spacing: var(--t-campo-ls); color: var(--ink-strong); }
.opcion .txt small { font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-soft); }

/* ── Avatar ──────────────────────────────────────────────────────────── */
.avatar {
  --s: 40px;
  position: relative;
  display: grid; place-items: center;
  width: var(--s); height: var(--s); flex: none;
  border-radius: 50%;
  overflow: hidden;
  background: var(--tono, var(--round));
  color: var(--tono-tinta, var(--ink-sobre-color));
  font-family: var(--font); font-size: calc(var(--s) * 0.38); font-weight: 600; letter-spacing: 0;
  box-shadow: var(--shadow-avatar);
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; -webkit-user-drag: none; }
.avatar.plano { box-shadow: none; }

/* ── Marca: un cliente, no una persona ───────────────────────────────── */
/* Una persona va en círculo (.avatar) y un cliente en cuadrado redondeado:
   se distinguen de un vistazo. Mismas variables (--s, --tono, --tono-tinta),
   así el mismo código de iniciales y de color vale para los dos. */
.marca {
  --s: 44px;
  display: grid; place-items: center;
  width: var(--s); height: var(--s); flex: none;
  border-radius: calc(var(--s) * 0.3);
  overflow: hidden;
  background: var(--tono, var(--round));
  color: var(--tono-tinta, var(--ink-sobre-color));
  font-family: var(--font); font-size: calc(var(--s) * 0.36); font-weight: 600;
  box-shadow: var(--shadow-sm);
}
/* Con logo, el fondo se aclara y la imagen se ve entera (contain), sin recortar. */
.marca.con-logo { background: var(--surface-hi); padding: calc(var(--s) * 0.12); }
.marca img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* ── Chips y puntos de estado ────────────────────────────────────────── */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 10px;
  border-radius: var(--r-pill);
  background: var(--surface);
  font: var(--t-chip); letter-spacing: var(--t-chip-ls);
  color: var(--ink-soft);
  white-space: nowrap;
}
.chip.dueno { background: var(--primary); color: var(--primary-ink); }
.punto { width: 8px; height: 8px; border-radius: 50%; background: var(--ink-faint); flex: none; }

/* ── Pastilla de elección: encender y apagar opciones sueltas ──────────
   Para elegir VARIAS de una lista corta (o ninguna). Cuando la elección es
   una sola entre pocas, el control segmentado; cuando es sí o no de una
   cosa, el interruptor. Es un botón de verdad, con `aria-pressed`. */
.eleccion { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.eleccion > span {
  font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint);
}
.pastilla {
  display: inline-flex; align-items: center; gap: 6px;
  height: var(--control-alto-sm); padding: 0 14px;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink-soft);
  font: var(--t-boton-sm); letter-spacing: var(--t-boton-sm-ls);
  cursor: pointer; white-space: nowrap;
  transition: background var(--fast), color var(--fast), border-color var(--fast), box-shadow var(--fast);
}
.pastilla:hover { background: var(--surface-hi); color: var(--ink); }
.pastilla:active { transform: scale(var(--press)); }
.pastilla:focus-visible { outline: none; box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 24%, transparent); }
.pastilla[aria-pressed="true"] {
  background: var(--surface-hi); border-color: transparent;
  color: var(--ink-strong); box-shadow: var(--shadow-sm);
}
/* La palomita solo se ve cuando está encendida: apagada ocuparía sitio y ruido. */
.pastilla .tic { width: 14px; height: 14px; margin-left: -4px; opacity: 0; transition: opacity var(--fast), margin var(--fast); }
.pastilla[aria-pressed="true"] .tic { opacity: 1; margin-left: 0; }
.pastilla small { font: var(--t-chip); color: var(--ink-faint); }
.punto.on { background: var(--mint); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mint) 22%, transparent); }

/* ── Progreso: avance de 0 a 100 % con --p ───────────────────────────── */
.progreso {
  position: relative;
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--surface);
  overflow: hidden;
}
.progreso > span {
  display: block;
  width: var(--p, 0%);
  height: 100%;
  border-radius: inherit;
  background: var(--mint);
  transition: width var(--slow);
}

/* ── Deslizante: un número dentro de un rango (la edad, un volumen) ────
   Un `input type=range` real (teclado y lector de pantalla) con piel propia, sobre un
   `.field`: el valor se lee a la derecha de la etiqueta (`<b>`) y los botones − / +
   (`data-paso`) afinan de uno en uno. El relleno sale de `--p` (de 0 a 1), que pone
   `enganchaDeslizante()` de piezas.js. `.sin-elegir`: nadie lo ha movido, aún no hay valor. */
.deslizante > span { display: flex; align-items: baseline; padding-right: 4px; }
/* Un puntal con la letra del valor: la fila mide lo mismo con valor que sin él (nada salta al elegir). */
.deslizante > span::before { content: '\200b'; font: var(--t-seccion); }
.deslizante > span b {
  margin-left: auto; padding-left: 10px;
  font: var(--t-seccion); letter-spacing: var(--t-seccion-ls); color: var(--ink-strong);
  font-variant-numeric: tabular-nums;
}
.deslizante.sin-elegir > span b { font: var(--t-etiqueta); font-weight: 400; letter-spacing: 0; color: var(--ink-faint); }
.deslizante-pista {
  --pomo: 24px; --riel: 6px;
  display: flex; align-items: center; gap: 2px;
  height: var(--campo-alto);
  padding: 0 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  transition: border-color var(--fast), background var(--fast), box-shadow var(--fast);
}
.deslizante-pista:focus-within {
  background: var(--surface-hi);
  border-color: color-mix(in srgb, var(--blue) 55%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 14%, transparent);
}
.deslizante-pista .icon-btn svg { width: 18px; height: 18px; }
.deslizante-pista input[type="range"],
.deslizante-pista input[type="range"]:focus {
  -webkit-appearance: none; appearance: none;
  flex: 1; min-width: 0;
  height: var(--pomo);
  margin: 0; padding: 0;
  border: 0; border-radius: var(--r-pill);
  background: transparent; box-shadow: none; outline: none;
  cursor: pointer;
  touch-action: pan-y;   /* arrastrar de lado mueve el pomo; hacia arriba o abajo, la página */
}
/* El riel: lleno hasta el centro del pomo (que no llega a los bordes: de ahí la cuenta). */
.deslizante-pista input[type="range"]::-webkit-slider-runnable-track {
  height: var(--riel); border-radius: var(--r-pill);
  background: linear-gradient(to right, var(--primary) calc(var(--pomo) / 2 + (100% - var(--pomo)) * var(--p, 0)), var(--round) 0);
}
.deslizante-pista input[type="range"]::-moz-range-track {
  height: var(--riel); border-radius: var(--r-pill);
  background: linear-gradient(to right, var(--primary) calc(var(--pomo) / 2 + (100% - var(--pomo)) * var(--p, 0)), var(--round) 0);
}
/* El pomo: un aro del color del relleno. */
.deslizante-pista input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  box-sizing: border-box;
  width: var(--pomo); height: var(--pomo);
  margin-top: calc((var(--riel) - var(--pomo)) / 2);
  border: 7px solid var(--primary); border-radius: 50%;
  background: var(--primary-ink);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--fast), transform var(--fast);
}
.deslizante-pista input[type="range"]::-moz-range-thumb {
  box-sizing: border-box;
  width: var(--pomo); height: var(--pomo);
  border: 7px solid var(--primary); border-radius: 50%;
  background: var(--primary-ink);
  box-shadow: var(--shadow-sm);
  transition: border-color var(--fast), transform var(--fast);
}
.deslizante-pista input[type="range"]:active::-webkit-slider-thumb { transform: scale(var(--press-icono)); }
.deslizante-pista input[type="range"]:active::-moz-range-thumb { transform: scale(var(--press-icono)); }
.deslizante.sin-elegir input[type="range"]::-webkit-slider-thumb { border-color: var(--round); background: var(--round-ink); }
.deslizante.sin-elegir input[type="range"]::-moz-range-thumb { border-color: var(--round); background: var(--round-ink); }

/* ── Insignia: un número que pide atención (sin leer, pendientes) ────── */
.insignia {
  display: inline-grid; place-items: center;
  min-width: 20px; height: 20px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--pink);
  color: var(--ink-sobre-color);
  font: var(--t-chip);
}

/* ── Icono de color: en vez de emojis (kit/js/iconos.js) ────────────────
   Minimalista, a dos tonos y solo con tokens: --tono es su acento y --tono-b el de
   contraste (los pone icono()). Capas: f relleno suave · t trazo · s relleno · fb/tb/sb
   lo mismo con el contraste · claro papel · p punteado. Tamaño: --s (24 px). */
.ic { --s: 24px; width: var(--s); height: var(--s); flex: none; display: inline-block; vertical-align: middle; overflow: visible; }
.ic .f { fill: color-mix(in srgb, var(--tono) 28%, transparent); }
.ic .fb { fill: color-mix(in srgb, var(--tono-b, var(--tono)) 28%, transparent); }
.ic .s { fill: var(--tono); }
.ic .sb { fill: var(--tono-b, var(--tono)); }
.ic .claro { fill: var(--papel); }
.ic .t, .ic .tb, .ic .tk { fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ic .t { stroke: var(--tono); }
.ic .tb { stroke: var(--tono-b, var(--tono)); }
.ic .tk { stroke: var(--ink-sobre-claro); stroke-width: 1.4; }
.ic .p { stroke-dasharray: 2.6 2.8; }
/* En su baldosa (filas, cabeceras): el acento muy suave detrás. */
.ic-caja { --s: 44px; display: grid; place-items: center; width: var(--s); height: var(--s); flex: none; border-radius: var(--r-md);
  background: color-mix(in srgb, var(--tono, var(--blue)) 16%, var(--surface-hi)); }
.ic-caja .ic { --s: 58%; }

/* ── Insignia de servicio: lo que alguien hace en un Servicio de Uvlis ──
   Compacta, junto al nombre (su icono del kit y el nombre del servicio); al tocarla
   se abre su detalle. Es un <details> (teclado y lector de pantalla sin JS).
   Descriptiva, nunca un valor ni un ranking. `.estatica`: el detalle siempre a la
   vista y en su sitio (para enseñar «así la ven»). --tono opcional (azul). */
.insignia-srv { position: relative; display: inline-block; vertical-align: middle; }
.insignia-srv > summary {
  list-style: none; display: inline-flex; align-items: center; gap: 4px;
  height: 24px; padding: 0 10px 0 6px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--tono, var(--blue)) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--tono, var(--blue)) 32%, transparent);
  color: var(--ink-strong); font: var(--t-chip); letter-spacing: var(--t-chip-ls);
  cursor: pointer; white-space: nowrap; user-select: none;
}
.insignia-srv > summary::-webkit-details-marker { display: none; }
.insignia-srv > summary .ic { --s: 16px; }
.insignia-srv > summary:focus-visible { outline: none; box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 24%, transparent); }
.insignia-srv-pop {
  position: absolute; z-index: 40; top: calc(100% + 6px); left: 0;
  display: flex; flex-direction: column; gap: 2px; min-width: 220px;
  padding: 12px 14px; border-radius: var(--r-md);
  background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-lg);
  animation: aparece var(--dur-rapida) var(--ease);
}
.insignia-srv-pop strong { font: var(--t-campo); letter-spacing: var(--t-campo-ls); font-weight: 700; color: var(--ink-strong); }
.insignia-srv-pop span { font: var(--t-pequeno); letter-spacing: var(--t-pequeno-ls); color: var(--ink-soft); }
.insignia-srv-pop .btn { margin-top: 8px; align-self: flex-start; }
.insignia-srv.estatica .insignia-srv-pop { position: static; margin-top: 6px; box-shadow: var(--shadow-sm); animation: none; }

/* ── Subir archivo: zona para soltar o pulsar ────────────────────────────
   Borde punteado que se ilumina al arrastrar encima (.encima). Mientras sube,
   .ocupada (con un Progreso dentro); al terminar, .lista (borde continuo). */
.soltar {
  display: grid; place-items: center;
  min-height: 150px;
  padding: 22px 20px;
  border: 1.5px dashed var(--ink-faint);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-align: center;
  cursor: pointer;
  outline: none;
  transition: border-color var(--fast), background var(--fast), box-shadow var(--fast);
}
.soltar:hover, .soltar:focus-visible { border-color: var(--ink-soft); background: var(--surface-hi); }
.soltar:focus-visible { box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 14%, transparent); }
.soltar.encima { border-color: var(--blue); background: color-mix(in srgb, var(--blue) 7%, var(--surface-hi)); }
.soltar.ocupada { cursor: default; border-style: solid; border-color: var(--line); }
.soltar.lista { cursor: default; border-style: solid; border-color: color-mix(in srgb, var(--mint) 55%, transparent); background: var(--surface-hi); }
.soltar-dentro { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100%; max-width: 440px; min-width: 0; }
.soltar-dentro strong { font: var(--t-cuerpo); font-weight: 600; color: var(--ink); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.soltar-dentro small { font: var(--t-texto); color: var(--ink-soft); }
.soltar-ico { width: 46px; height: 46px; display: grid; place-items: center; border-radius: var(--r-md); background: var(--surface-hi); color: var(--icon); margin-bottom: 4px; box-shadow: var(--shadow-sm); }
.soltar-ico svg { width: 22px; height: 22px; }
.soltar-ico.hecho { background: var(--mint); color: var(--ink-sobre-claro); }
.soltar .progreso { width: 100%; margin: 6px 0 2px; }

/* ── Estado vacío ────────────────────────────────────────────────────── */
.vacio {
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  gap: 10px;
  flex: 1;
  padding: 40px;
}
.vacio .tile-ico { width: 64px; height: 64px; border-radius: 22px; display: grid; place-items: center; background: var(--surface-hi); color: var(--icon); margin-bottom: 6px; }
.vacio .tile-ico svg { width: 28px; height: 28px; }
.vacio h2 { font: var(--t-destacado); letter-spacing: var(--t-destacado-ls); }
.vacio p { font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-soft); max-width: 420px; }
.vacio code { font: var(--t-pequeno); font-family: var(--font-mono); background: var(--surface); padding: 2px 7px; border-radius: 6px; }
.vacio .btn { margin-top: 10px; }

/* ── Candado: algo bloqueado que se abre con una contraseña ─────────────
   La Bóveda y Código («Código bloqueado»). Va sobre una tarjeta (`card candado`): por eso
   está DESPUÉS de .card, para ganarle el relleno y el título. El tiempo que le queda
   abierto, en un chip con cifras que no bailan: `.chip.reloj`. */
.candado { max-width: 420px; display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; padding: 34px 28px; }
.candado-ico {
  display: grid; place-items: center;
  width: 62px; height: 62px;
  border-radius: 22px;
  background: var(--surface-hi); color: var(--icon);
  box-shadow: var(--shadow-sm);
}
.candado-ico svg { width: 28px; height: 28px; }
.candado h2 { font: var(--t-destacado); letter-spacing: var(--t-destacado-ls); }
.candado p { font: var(--t-texto); color: var(--ink-soft); }
.candado .field { width: 100%; text-align: left; margin-top: 6px; }
.candado .error-msg { width: 100%; }
.candado .btn { width: 100%; margin-top: 4px; }
.chip.reloj { font-variant-numeric: tabular-nums; }

/* ── Terminal: lo que imprime un programa, línea a línea ────────────────
   La ficha de un Servicio de UVLIS (lo que sale con [id] en la terminal de UVLIS) y los
   «Registros» de Código. Cada línea puede llevar su <time> y `.error` si es de error. */
.terminal {
  max-height: 360px; overflow: auto;
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: var(--surface);
  font: var(--t-pequeno); font-family: var(--font-mono); color: var(--ink);
  white-space: pre-wrap; overflow-wrap: anywhere;
  scrollbar-width: thin;
}
.terminal time { color: var(--ink-faint); margin-right: 10px; }
.terminal .error { color: var(--pink); }
.terminal .lista-vacia { padding: 4px 0; font-family: var(--font); }

/* ── Cifra: un dato grande con su etiqueta ──────────────────────────────
   Para los números de un panorama (el del estudio y el de los Servicios de
   UVLIS). Si lleva a algún sitio, es un <button> o un <a> y se pulsa como una
   tarjeta. `.nose` cuando el dato no se sabe (un módulo que no contesta): nunca
   se enseña un cero que no lo es. `--tono` opcional tiñe el icono y el dato.
   En una rejilla `.cifras`, con `--cols` columnas fijas (el reparto automático
   dejaba una sola cifra huérfana en la última fila). */
.cifras {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
@media (min-width: 700px) { .cifras { grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); } }
.cifra {
  display: flex; flex-direction: column; gap: 6px;
  min-width: 0;
  padding: 16px 18px 14px;
  border: 2px solid var(--panel-stroke);
  border-radius: var(--r-xl);
  background: var(--panel);
  color: inherit; text-align: left; text-decoration: none;
}
button.cifra, a.cifra { cursor: pointer; transition: background var(--fast), transform var(--fast); }
button.cifra:hover, a.cifra:hover { background: var(--surface-hi); }
button.cifra:active, a.cifra:active { transform: scale(var(--press)); }
.cifra-cab {
  display: flex; align-items: center; gap: 8px;
  font: var(--t-pequeno); letter-spacing: var(--t-pequeno-ls); color: var(--ink-soft);
}
.cifra-ico {
  display: grid; place-items: center;
  width: 24px; height: 24px; flex: none;
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--tono, var(--icon));
}
.cifra-ico svg { width: 15px; height: 15px; }
.cifra-dato {
  font: var(--t-marca); letter-spacing: var(--t-marca-ls);
  color: var(--tono, var(--ink-strong));
  line-height: 1.05;
}
.cifra-dato.nose { color: var(--ink-faint); }
.cifra small { font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-faint); }

/* ── Columnas: una sola serie en el tiempo ───────────────────────────────
   Una columna por día o por mes, de la tinta principal (una serie, un color: el
   título dice qué es, sin leyenda). Crece desde abajo, con el extremo
   redondeado; entre columna y columna, 2 px de fondo. Cada columna lleva su
   `aria-label` («23 sep: 4 personas»): es la tabla para quien no ve la gráfica.
   Se rotulan solo algunas (`<b>`, el máximo y la última); el resto, al pasar. */
.columnas { display: flex; align-items: flex-end; gap: 2px; height: 96px; }
.columna {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 3px;
  height: 100%;
}
.columna b { font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-soft); white-space: nowrap; }
.columna-barra {
  width: 100%; max-width: 24px;
  height: max(3px, var(--h));
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  background: var(--primary);
  transition: height var(--slow), opacity var(--fast);
}
.columna.cero .columna-barra { background: var(--line); }
.columna small { font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint); white-space: nowrap; }
.columnas:hover .columna-barra { opacity: 0.55; }
.columnas .columna:hover .columna-barra { opacity: 1; }
.columnas-pie { display: flex; justify-content: space-between; gap: 8px; margin-top: 6px; }
.columnas-pie small { font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint); }
.columnas.densa { gap: 1px; }   /* muchas columnas (más de 45): menos aire para que la barra no se quede en un hilo */

/* ── Barras: comparar unas cuantas cosas entre sí ────────────────────────
   Una fila por cosa (un juego, un modo, un paso): su nombre, su barra y su
   número. Todas de la tinta principal: lo que distingue a cada una es su
   nombre, no un color (si la cosa tiene el suyo, va en un `.punto` junto al
   nombre). La barra nace recta a la izquierda y acaba redonda; `--p` es su
   largo en porcentaje del máximo, `.cero` cuando no hay nada. Cada fila
   lleva su `aria-label`. Si lleva a algún sitio, es un <button>. */
.barras { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.barra {
  display: grid; grid-template-columns: minmax(0, var(--nombre, 40%)) minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
  min-width: 0; padding: 0; border: 0; background: none; text-align: left;
}
button.barra { cursor: pointer; }
button.barra:active { transform: scale(var(--press)); }
.barra-nombre {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink);
}
.barra-nombre > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.barra-pista { height: 10px; min-width: 0; }
.barra-pista > span {
  display: block; height: 100%;
  width: max(3px, var(--p, 0%));
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--primary);
  transition: width var(--slow), opacity var(--fast);
}
.barra.cero .barra-pista > span { background: var(--line); }
.barra-valor {
  font: var(--t-pequeno); letter-spacing: var(--t-pequeno-ls); color: var(--ink-strong);
  font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}
.barra-valor small { font: inherit; font-weight: 400; color: var(--ink-faint); margin-left: 6px; }
.barras:hover .barra-pista > span { opacity: 0.55; }
.barras .barra:hover .barra-pista > span { opacity: 1; }
/* En el teléfono la barra va debajo, a todo lo ancho: al lado del nombre y del número se quedaba en nada. */
@media (max-width: 699px) {
  .barra { grid-template-columns: minmax(0, 1fr) auto; row-gap: 6px; }
  .barra-pista { grid-column: 1 / -1; grid-row: 2; }
}

/* ── Calor: cuánto, en una rejilla (día de la semana × hora) ─────────────
   Un solo color, más lleno cuanto más hay: `--v` (de 0% a 100%) mezcla la
   tinta principal con el fondo. Con su escala («Menos · Más») y el
   `aria-label` de cada celda, que es su dato para quien no la ve. */
.calor { display: grid; grid-template-columns: auto repeat(var(--cols, 24), minmax(0, 1fr)); gap: 2px; align-items: center; }
.calor-celda {
  aspect-ratio: 1; min-width: 0;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--primary) var(--v, 0%), var(--surface));
}
.calor-celda:hover { box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--ink-soft); }
.calor-lado, .calor-pie { font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint); white-space: nowrap; }
.calor-lado { padding-right: 8px; }
.calor-pie { grid-column: span var(--tramo, 6); padding-top: 4px; }
.calor-escala { display: flex; align-items: center; justify-content: flex-end; gap: 4px; margin-top: 10px; font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint); }
.calor-escala .calor-celda { width: 12px; flex: none; }
.calor-escala .calor-celda:hover { box-shadow: none; }

/* ── Tabla de datos: filas con varias columnas que se comparan ────────────────────
   Para lo que se lee fila a fila (personas, partidas, juego por juego).
   Cabecera pequeña y gris; los números, a la derecha y con cifras que no
   bailan (`.num`). Una cabecera que ordena es un <button> dentro del <th>
   (`aria-sort` en el <th> dice por cuál va). Una fila que abre algo lleva
   `data-abre` y `tabindex="0"`. En `.tabla-datos-caja` se desplaza de lado cuando
   no cabe, sin mover la página. */
.tabla-datos-caja { overflow-x: auto; max-width: 100%; }
.tabla-datos { width: 100%; border-collapse: collapse; }
.tabla-datos th {
  padding: 0 14px 10px 0;
  font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint);
  text-align: left; white-space: nowrap;
}
.tabla-datos th button {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; letter-spacing: inherit; color: inherit;
}
.tabla-datos th button:hover, .tabla-datos th[aria-sort] button { color: var(--ink-strong); }
.tabla-datos th button svg { width: 10px; height: 10px; opacity: 0; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; transition: transform var(--fast); }
.tabla-datos th[aria-sort] button svg { opacity: 1; }
.tabla-datos th[aria-sort="ascending"] button svg { transform: rotate(180deg); }
.tabla-datos td {
  padding: 10px 14px 10px 0;
  border-top: 1px solid var(--line);
  font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink);
  white-space: nowrap; vertical-align: middle;
}
.tabla-datos th:last-child, .tabla-datos td:last-child { padding-right: 0; }
.tabla-datos .num { text-align: right; font-variant-numeric: tabular-nums; }
.tabla-datos td strong { font-weight: 600; color: var(--ink-strong); }
.tabla-datos td small { font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint); }
.tabla-datos .apagada td { color: var(--ink-faint); }
.tabla-datos tr[data-abre] { cursor: pointer; }
.tabla-datos tr[data-abre]:hover td { background: var(--item-on); }
.tabla-datos tr[data-abre]:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.tabla-datos-quien { display: flex; align-items: center; gap: 10px; min-width: 0; }
.tabla-datos-quien > span:last-child { display: flex; flex-direction: column; min-width: 0; }
.tabla-datos-varios { display: flex; align-items: center; }
.tabla-datos-varios .avatar + .avatar { margin-left: -8px; }
.tabla-datos-pie { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-top: 14px; font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-faint); }

/* La pista de un dato: lo que dice una columna, una barra o una celda al pasar. Nunca es la única forma de leerlo. */
.pista-dato {
  position: fixed; z-index: 60;
  max-width: min(300px, calc(100vw - 16px));
  padding: 6px 12px;
  border-radius: var(--r-sm);
  background: var(--primary); color: var(--primary-ink);
  font: var(--t-pequeno); letter-spacing: var(--t-pequeno-ls);
  pointer-events: none;
  box-shadow: var(--shadow-sm);
  animation: aparece var(--dur-rapida) var(--ease);
}

/* ── Cuadro de mando: filtros arriba y, debajo, todo lo que esos filtros cortan ──
   Una sola fila de filtros (el periodo primero) que manda sobre TODAS las
   cifras, gráficas y tablas de debajo: los números siempre cuadran entre sí.
   Las tarjetas van en `.cuadro-rejilla`, de dos en dos (`.ancha`: la fila
   entera) y de una en una en el teléfono. Mientras se vuelve a pedir, lo de
   antes se queda atenuado (`.cargando`): sin saltos ni esqueletos. */
.cuadro { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.cuadro-filtros { display: flex; flex-direction: column; gap: 12px; }
.cuadro-fila { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.cuadro-fila > .sitio { flex: 1; }
.cuadro-fila .field { flex-direction: row; align-items: center; gap: 8px; }
.cuadro-fila .field input { width: auto; height: var(--control-alto-sm); }
.cuadro-cuerpo { display: flex; flex-direction: column; gap: 14px; min-width: 0; transition: opacity var(--fast); }
.cuadro.cargando .cuadro-cuerpo { opacity: 0.55; }
.cuadro-rejilla { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; }
@media (min-width: 900px) {
  .cuadro-rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cuadro-rejilla > .ancha { grid-column: 1 / -1; }
}
.cuadro .card { min-width: 0; }
/* En el teléfono nada se sale de ancho: un segmentado largo se desliza dentro de su píldora, y los juegos van en una tira que se desliza. */
.cuadro .seg { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.cuadro .seg::-webkit-scrollbar { display: none; }
.cuadro .seg button { flex: none; white-space: nowrap; }
.cuadro-fila > div, .cuadro .card-head > div, .cuadro .herramientas > div { min-width: 0; max-width: 100%; }
@media (max-width: 699px) {
  .cuadro-fila.eleccion { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -24px; padding: 2px 24px; }
  .cuadro-fila.eleccion::-webkit-scrollbar { display: none; }
  .cuadro-fila.eleccion > * { flex: none; }
}
.cuadro .card-head { align-items: flex-start; flex-wrap: wrap; }
.cuadro .card-head > div:first-child { min-width: 0; }
.cuadro .card-head p { margin-top: 2px; }
.cuadro .columnas { height: 132px; }
.cuadro-nota { font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-soft); margin-top: 12px; }
.cuadro-nota b { font-weight: 600; color: var(--ink-strong); }
.cuadro-pie { font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-faint); }
.cuadro-mini { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); align-items: end; gap: 14px; margin-bottom: 16px; }
.cuadro-mini > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cuadro-mini span { font: var(--t-chip); letter-spacing: var(--t-chip-ls); color: var(--ink-faint); }
.cuadro-mini b { font: var(--t-destacado); letter-spacing: var(--t-destacado-ls); color: var(--ink-strong); }
.cuadro-titulo { font: var(--t-etiqueta); letter-spacing: var(--t-etiqueta-ls); color: var(--ink-soft); margin: 18px 0 10px; }
.cuadro-titulo:first-child { margin-top: 0; }

/* ── Diálogo ─────────────────────────────────────────────────────────── */
.dialogo {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 28px;
  border: 2px solid var(--panel-stroke);
  border-radius: var(--r-xl);
  background: var(--panel);
  color: var(--ink);
  box-shadow: var(--shadow-lg);
  overflow: auto;
}
.dialogo[open] { animation: dialogo var(--dur-lenta) var(--ease); }
.dialogo::backdrop { background: var(--scrim); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); animation: aparece var(--dur-lenta) var(--ease); }
/* Dentro de UVLIS el módulo es un marco (iframe): su velo solo cubre ese recuadro. Se
   redondea como un panel de la plataforma para que no quede un rectángulo de esquinas
   vivas junto a la barra lateral. Se redondea el VELO, no el marco: así no se recorta
   nada del contenido del módulo. */
.embebido .dialogo::backdrop { border-radius: var(--r-xl); }
@media (max-width: 560px) { .dialogo { padding: 22px 20px; } }
.dialogo-head { display: flex; align-items: center; gap: 16px; margin-bottom: 22px; }
.dialogo-head h2 { font: var(--t-destacado); letter-spacing: var(--t-destacado-ls); }
.dialogo-head p { font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink-soft); }
.dialogo-head .icon-btn { margin-left: auto; align-self: flex-start; }
.dialogo .avatar { --s: 64px; }
/* El icono de la app (fondo blanco propio en los dos temas, como en el móvil). */
.app-icono { width: 56px; height: 56px; flex: none; border-radius: var(--r-md); border: 1px solid var(--line); }
/* Pasos numerados: instrucciones cortas dentro de un diálogo. */
.pasos { display: grid; gap: 8px; margin: 0; padding: 14px 16px 14px 34px; border-radius: var(--r-md); background: var(--surface); font: var(--t-texto); letter-spacing: var(--t-texto-ls); color: var(--ink); }

/* ── Aviso flotante ──────────────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; bottom: 28px; z-index: 100;
  transform: translateX(-50%);
  padding: 11px 20px;
  border-radius: var(--r-pill);
  background: var(--primary); color: var(--primary-ink);
  font: var(--t-boton); letter-spacing: var(--t-boton-ls);
  box-shadow: var(--shadow-lg);
  animation: sube var(--dur-lenta) var(--ease);
}

/* ── Cargando ────────────────────────────────────────────────────────── */
.girando {
  width: 22px; height: 22px;
  border: 2.5px solid var(--line); border-top-color: var(--ink-soft);
  border-radius: 50%;
  animation: gira 0.8s linear infinite;
}

/* ── Movimiento ──────────────────────────────────────────────────────── */
@keyframes entra   { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes aparece { from { opacity: 0; } to { opacity: 1; } }
@keyframes dialogo { from { opacity: 0; transform: translateY(10px) scale(0.97); } to { opacity: 1; transform: none; } }
@keyframes sube    { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes gira    { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ── Transiciones de vista (View Transitions) ─────────────────────────────
   Regla del dueño (11-oct-2026): todo cambio de pantalla se anima, no salta.
   Entre páginas del mismo origen lo hace esto solo; dentro de una página, `transicion()`
   de kit/js/transicion.js (que pone `vt` y `vt-atras` en <html> mientras dura).
   Por omisión es un FUNDIDO corto: lo que no cambia (cabecera, pestañas) se queda quieto y
   solo cambia lo nuevo. Quien quiera que una zona entre deslizándose le pone nombre
   (ver el panel: styles.css) y usa vt-sale / vt-entra.
   Los clics ATRAVIESAN la transición: nunca se pierde una pulsación mientras anima. */
@view-transition { navigation: auto; }
::view-transition { pointer-events: none; }
::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
  animation-duration: calc(var(--dur-rapida) * 1.3); animation-timing-function: var(--ease);
}
@keyframes vt-sale        { to   { opacity: 0; transform: translateY(-6px) scale(0.992); } }
@keyframes vt-entra       { from { opacity: 0; transform: translateY(12px) scale(0.992); } }
@keyframes vt-sale-atras  { to   { opacity: 0; transform: translateX(18px); } }
@keyframes vt-entra-atras { from { opacity: 0; transform: translateX(-18px); } }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

@media (max-width: 720px) {
  .form-grid { grid-template-columns: 1fr; }
  .page-head { flex-direction: column; align-items: flex-start; }
}
