/*
 * Full Garage — hand-written, no build step.
 *
 * There is no Node in this repository and none in the production image. The
 * class vocabulary in the templates is semantic and in Spanish — `ranura`,
 * `campo--interruptor`, `rejilla-fotos` — not utilities, so a Tailwind scan
 * would have nothing to emit. AGENTS.md claimed a Vite pipeline for months;
 * it never existed.
 *
 * NOT in a `dist/` directory, deliberately. When Vite does arrive with H4 (the
 * React island and the PWA), its `emptyOutDir` deletes whatever it finds there
 * — and the symptom would appear on an advisor's phone, not in CI.
 *
 * What drives every number below: the screen that matters is the intake
 * checklist, used on a phone, in a workshop, by someone wearing gloves, with
 * the car in front of them. Touch target sizes and font sizes here are not
 * taste.
 */

:root {
  /* ESCALAS. Antes sólo había color: quince variables y ninguna de espacio, de
     tipo, de radio ni de sombra. Sin ellas cada pantalla inventa sus números y
     el resultado se lee como «a medio hacer» aunque cada pieza esté bien. */
  --e-1: .25rem;  --e-2: .5rem;   --e-3: .75rem;
  --e-4: 1rem;    --e-6: 1.5rem;  --e-8: 2rem;

  --r-sm: 4px;  --r-md: 8px;  --r-lg: 12px;

  --sombra-1: 0 1px 2px rgba(18, 26, 33, .06), 0 1px 3px rgba(18, 26, 33, .04);
  --sombra-2: 0 2px 4px rgba(18, 26, 33, .06), 0 4px 12px rgba(18, 26, 33, .06);

  /* EL ALTO DE LA BARRA DE ARRIBA, que es pegajosa y va encima de todo. Lo que
     se pega debajo de ella lo descuenta de aquí. El árbol y la guía del manual
     se pegaban a 1rem del borde de la VENTANA y la barra les tapaba 52 px de
     cabeza; el dueño lo mandó en captura el 2026-09-11: «siempre deberían estar
     visibles desde tope y no cortarse al hacer scroll».

     MEDIDO, NO SUPUESTO, en un banco con las plantillas reales renderizadas:
     69 px (68,57 en una pantalla al 175 %, donde el filete de 1px se pinta con
     un solo píxel físico). Los comentarios de la hoja suponían «~3.4rem», 54
     px, y no: lo que manda es «Salir», que mide 44 px como todo botón de la
     aplicación. Por eso va escrito con sus piezas y no como un número suelto:
     el botón, el relleno de `.barra__fila` arriba y abajo, y el filete.

     Y VALE EN CUALQUIER ANCHO PORQUE LA BARRA YA NO CRECE. La fila no se
     envuelve, y el nombre del taller se partía en tantas líneas como pidiera:
     con «Taller de pruebas del banco» la barra medía 82,56 px a 375 de ancho y
     120,94 a 320, con una razón social de 65 letras 159 px, y saltar a un
     apartado dejaba el título ENTERO debajo de ella. Ahora `.barra__taller`
     corta en dos líneas, que caben en los 44 px del botón. Las piezas de esta
     cuenta las cruza con la hoja `test_la_ayuda_llega_a_su_apartado.py`. */
  --alto-barra: calc(44px + 2 * var(--e-3) + 1px);

  /* La familia. `system-ui` era lo único que había, y es la razón de que la
     aplicación no se pareciera a nada. Archivo es una grotesca industrial: alta
     legibilidad a tamaño pequeño y una Narrow para las cabeceras densas. */
  --letra: Archivo, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --letra-titulo: "Archivo Narrow", "Arial Narrow", var(--letra);
  --letra-dato: "IBM Plex Mono", ui-monospace, SFMono-Regular, Consolas, monospace;

  --fondo: #f7f8fa;
  --papel: #ffffff;
  --tinta: #1c2430;
  --tinta-suave: #4a5462;
  --borde: #c9d1da;
  --marca: #0a6470;
  --marca-oscura: #084f59;
  --alerta: #a32b22;
  --exito: #2c6e49;
  --aviso: #8a5b00;

  /* Los PISOS de cada estado. Un color de texto sin fondo obliga a inventar uno
     en cada pantalla, y ahí es donde aparecen los ocho verdes distintos. */
  --alerta-piso: #fbeae8;
  --exito-piso: #e6f2eb;
  --aviso-piso: #fbf0dc;
  --marca-piso: #e4f0f1;
  --papel-alt: #edf1f2;
  --borde-firme: #c3ced3;

  /* The vehicle silhouette. `_silueta.html` uses these five and nothing
   * defined them, so the diagram rendered with the browser's defaults. */
  --silueta-fondo: #eceff3;
  /* 5.35:1 on the background, 4.51:1 on the glass. The previous shade was
   * 4.11:1 — fine for graphics, and this colour also paints the FRENTE/ATRÁS
   * labels, which are text and need 4.5:1. */
  --silueta-linea: #5a626d;
  --silueta-vidrio: #d6dde6;
  --silueta-techo: #e2e7ee;
  --dano-fondo: #a32b22;
}

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

/* `hidden` ESCONDE, DIGA LO QUE DIGA UNA CLASE.
 *
 * La regla del navegador es `[hidden] { display: none }` SIN `!important`, así
 * que cualquier clase de esta hoja que ponga `display` la pisa y no avisa. Pasó
 * con el asistente: `.ia__panel` pone `display: flex`, la plantilla lo hace
 * nacer con `hidden` y el guion hace bien `panel.hidden = true` al cerrar -- y
 * aun así el panel salía ABIERTO en todas las pantallas y la × no lo cerraba.
 * El dueño lo mandó en captura el 2026-09-11: «la "x" no cierra la pantalla» y
 * «la ventana flotante debe iniciarse cerrada».
 *
 * Aquí, y no un `.ia__panel[hidden]` suelto: la trampa es de la cascada y no
 * del panel, y el próximo elemento con `hidden` y una clase con `display` caería
 * igual. Los que ya lo usaban --el aviso del tablero, el del vídeo y la firma del
 * ingreso-- no ponen `display`, así que para ellos no cambia nada.
 */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--fondo);
  color: var(--tinta);
  font: 15px/1.5 var(--letra);
  -webkit-font-smoothing: antialiased;
}

/* EL CONTENEDOR VA EN `main`, no en una clase.
 *
 * Aquí había un `.principal { max-width: 60rem }` que quería ser el contenedor
 * de la página -- y el único elemento con esa clase en todo el proyecto es el
 * `<nav>`. O sea: la navegación salía encajonada a 60rem y `<main>` se quedaba
 * SIN contenedor, pegado al borde izquierdo de la ventana y estirándose hasta
 * donde diera el monitor. Dos reglas con el mismo nombre, la de abajo ganando,
 * y nadie mirando.
 *
 * En `main` no hace falta acordarse de poner una clase en cada plantilla, que
 * es justo el descuido que produjo esto.
 */
main {
  /* Ancho generoso porque el tablero va en columnas y se desplaza. Las
     pantallas que se LEEN --formularios, el papel del art. 41-- traen su propia
     medida más estrecha, que es donde el ojo la necesita. */
  max-width: 1500px;
  margin: 0 auto;
  padding: var(--e-6) var(--e-4);
}
@media (max-width: 40rem) { main { padding: var(--e-4) var(--e-3); } }

h1, h2, h3 { line-height: 1.25; margin: 1.5rem 0 0.75rem; }
h1 { font-size: 1.6rem; }
h2 { font-size: 1.25rem; }

a { color: var(--marca); }

/* --- the one that is not cosmetic ------------------------------------- *
 * Used in four templates and never defined, so the intake screen printed
 * every photo position's name TWICE per slot — seven times on the page. Text
 * written only for screen readers was being shown to everyone.
 */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- el armazón de pantalla (2026-09-06) ---------------------------------
 *
 * Lo que hacía falta y no existía: una barra que diga dónde estás, una cabecera
 * de página con su acción principal, y el tablero como TABLERO y no como tabla.
 *
 * Nada de aquí baja al patio. La evaluación, las fotos de ingreso, el diagrama
 * de daños y la firma se quedan con sus tamaños: están escritos para manos con
 * guantes sosteniendo un teléfono, y ésa es la razón de que el técnico marque
 * los trece puntos en vez de apuntarlos en un papel.
 */

/* Pegajosa y ENCIMA de todo: tapa lo que se pegue arriba sin descontarla. Si
   cambia su alto, cambia `--alto-barra` en `:root`. */
.barra {
  background: var(--papel);
  border-bottom: 1px solid var(--borde);
  position: sticky; top: 0; z-index: 20;
}
.barra__fila { display: flex; align-items: center; gap: var(--e-4); padding: var(--e-3) var(--e-6); }
/* En el teléfono la fila deja a los lados lo mismo que `main`, y no es por
   alinear: con --e-6 a 320 de ancho al nombre del taller le quedaban 38 px y
   «Kleiber Garage», el piloto, salía cortado aun en dos líneas. Sólo el relleno
   de los lados: el de arriba y abajo es parte de `--alto-barra`. */
@media (max-width: 40rem) { .barra__fila { padding-inline: var(--e-3); } }

/* TODO SALTO A UN ANCLA SE PARA DEBAJO DE LA BARRA, y se dice aquí y no destino
   por destino. Iba con un `scroll-margin-top` en `.ay-area` y otro en
   `#seccion-*`, y el destino que no lo llevaba quedaba tapado: «↑ Al principio»,
   el salto de la guía del manual, lleva a `#ay-arriba` y dejaba el título de la
   página ENTERO detrás de la barra --38 px de 38-- en todos los anchos. En
   `html` vale para cualquier ancla, la de hoy y la que se añada.

   NO SE SUMA A UN `scroll-margin-top`: un destino que vuelva a descontar la
   barra por su cuenta deja su título 85 px más abajo. Las pantallas que vacían
   la barra --la del cliente, entrar, el PIN, el comprobante-- no tienen anclas. */
html { scroll-padding-top: calc(var(--alto-barra) + var(--e-4)); }

.marca-app {
  font-family: var(--letra-titulo);
  font-weight: 700; font-size: 1.2rem; letter-spacing: .02em;
  color: var(--marca); text-transform: uppercase; white-space: nowrap;
  text-decoration: none;
}
.marca-app span { color: var(--tinta); }
/* EL NOMBRE DEL TALLER CORTA EN DOS LÍNEAS, y es lo que hace verdad
   `--alto-barra` en cualquier ancho. Sin tope crecía hacia abajo --82,56 px de
   barra a 375 con 27 letras, 159 con 65, 390 con 200-- y los saltos a un
   apartado dejaban el título debajo. Dos líneas de .8rem son 38,4 px y caben en
   los 44 del botón «Salir».

   DOS LÍNEAS Y NO UNA CON PUNTOS SUSPENSIVOS, que era la salida corta: medido,
   en una sola línea «Kleiber Garage» --el piloto-- salía cortado a 320, 360 y
   375 de ancho; en dos cabe entero. `overflow-wrap` parte una razón social de
   una sola palabra larga, que desbordaba la página: 587 px de ancho en un
   teléfono de 375. El nombre entero va en el `title`. */
.barra__taller {
  font-size: .8rem; color: var(--tinta-suave); padding-left: var(--e-3); border-left: 1px solid var(--borde);
  min-width: 0; overflow: hidden; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}
.barra__derecha { margin-left: auto; display: flex; align-items: center; gap: var(--e-3); }

.avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--marca); color: #fff;
  display: grid; place-items: center; font-size: .78rem; font-weight: 600;
}

/* --- cabecera de página --- */
.cabecera-pagina {
  display: flex; align-items: flex-end; gap: var(--e-4);
  flex-wrap: wrap; margin-bottom: var(--e-6);
}
.cabecera-pagina h1 {
  font-family: var(--letra-titulo);
  font-size: 1.9rem; font-weight: 700; margin: 0; letter-spacing: -.01em;
}
.cabecera-pagina .subtitulo { margin: .15rem 0 0; color: var(--tinta-suave); font-size: .9rem; }
.cabecera-pagina__acciones { margin-left: auto; display: flex; gap: var(--e-2); align-items: center; }

/* --- las cifras de arriba --- */
.cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: var(--e-3); margin-bottom: var(--e-4); }
.cifra {
  background: var(--papel); border: 1px solid var(--borde);
  border-radius: var(--r-lg); padding: var(--e-3) var(--e-4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-3);
}
.cifra__nombre { font-size: .82rem; color: var(--tinta-suave); }
.cifra__valor { font-size: 1.5rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.cifra--urgente { border-color: var(--aviso); background: var(--aviso-piso); }
.cifra--urgente .cifra__valor, .cifra--urgente .cifra__nombre { color: var(--aviso); }

/* --- píldoras de filtro --- */
.pildoras { display: flex; gap: var(--e-2); flex-wrap: wrap; margin-bottom: var(--e-4); }
.pildora {
  font: inherit; font-size: .84rem; cursor: pointer;
  background: var(--papel); border: 1px solid var(--borde);
  border-radius: 999px; padding: .3rem .8rem; color: var(--tinta-suave);
  display: inline-flex; align-items: center; gap: .35rem; min-height: 32px;
}
.pildora:hover { border-color: var(--borde-firme); color: var(--tinta); }
.pildora--activa { background: var(--marca-piso); border-color: var(--marca); color: var(--marca); font-weight: 600; }

/* --- conmutador lista / tablero --- */
.conmutador { display: flex; background: var(--papel-alt); border: 1px solid var(--borde); border-radius: var(--r-md); padding: 2px; }
.conmutador a, .conmutador button {
  font: inherit; font-size: .84rem; font-weight: 500; text-decoration: none;
  border: none; background: none; color: var(--tinta-suave);
  padding: .35rem .7rem; border-radius: calc(var(--r-md) - 2px); cursor: pointer;
  display: flex; align-items: center; gap: .35rem;
}
.conmutador [aria-pressed="true"], .conmutador [aria-current="page"] {
  background: var(--papel); color: var(--tinta); font-weight: 600; box-shadow: var(--sombra-1);
}

/* --- el tablero --- */
.tablero { display: flex; gap: var(--e-3); overflow-x: auto; padding-bottom: var(--e-4); }
/* SEIS COLUMNAS A LA VEZ, que es el circuito completo de un taller de
   carrocería: recepción, evaluación, aprobado, desarme, en espera, listo.
   Con 17rem fijos sólo cabían cuatro y había que desplazar para ver si algo
   está terminado -- justo lo que el tablero existe para contestar de un
   vistazo.

   `flex: 1 0 12rem`: crecen para repartirse el ancho, y nunca bajan de 12rem.
   Con seis y el contenedor a 1500px salen a ~235px cada una; con más, el
   tablero se desplaza, que es lo correcto. */
.columna { flex: 1 0 12rem; min-width: 12rem; display: flex; flex-direction: column; gap: var(--e-2); }
/* TODAS LAS CABECERAS ACABAN A LA MISMA ALTURA, se llame como se llame el
   estado. Cada columna es un flex independiente, así que el alto de su cabecera
   lo decidía su propio texto: «Aprobado» ocupaba una línea y «En espera de
   repuesto» dos, y el subrayado de esa columna quedaba más abajo que el del
   resto. No se puede arreglar acortando el nombre --el dueño los renombra desde
   Configuración-- así que se fija el alto de dos líneas, se alinea al final, y
   el nombre se acota a dos líneas con el completo en el `title`. */
.columna__cabeza {
  display: flex; align-items: flex-end; gap: var(--e-2);
  /* Dos líneas EXACTAS, calculadas con los mismos números que las producen.
     Con un `3.1rem` a mano, subir el `line-height` o el `font-size` de aquí
     dejaría el alto corto y la desalineación volvería sin que nada avisara. */
  min-height: calc(2 * 1.25 * .82rem + .7rem + 2px);
  padding: .2rem .3rem .5rem;
  font-family: var(--letra-titulo);
  font-weight: 700; font-size: .82rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--tinta-suave); border-bottom: 2px solid var(--borde-firme);
}
.columna__nombre {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; line-height: 1.25;
}
.columna__cuenta {
  margin-left: auto; flex: 0 0 auto; font-family: var(--letra-dato);
  background: var(--papel-alt); color: var(--tinta-suave);
  border-radius: 999px; padding: 0 .45rem; font-size: .78rem;
}
.columna__cuerpo { display: flex; flex-direction: column; gap: var(--e-2); min-height: 4rem; }

.tarjeta-ot {
  background: var(--papel); border: 1px solid var(--borde);
  border-left: 3px solid var(--borde-firme);
  border-radius: var(--r-md); padding: var(--e-3);
  box-shadow: var(--sombra-1); text-decoration: none; color: inherit;
  display: flex; flex-direction: column; gap: .35rem;
}
.tarjeta-ot:hover { box-shadow: var(--sombra-2); border-color: var(--borde-firme); }
.tarjeta-ot--urgente { border-left-color: var(--alerta); }
.tarjeta-ot--espera { border-left-color: var(--aviso); }
.tarjeta-ot--ok { border-left-color: var(--exito); }
.tarjeta-ot__alto { display: flex; align-items: center; gap: var(--e-2); }
.tarjeta-ot__coche { font-weight: 600; font-size: .92rem; }
.tarjeta-ot__cliente { font-size: .84rem; color: var(--tinta-suave); }
.tarjeta-ot__pie { display: flex; align-items: center; gap: var(--e-2); margin-top: .2rem; }

/* Arrastrando una tarjeta. Las clases las pone SortableJS. */
.tarjeta-ot--fantasma { opacity: .35; }
.tarjeta-ot--arrastrando { box-shadow: var(--sombra-2); transform: rotate(1.5deg); }
.columna__cuerpo--recibiendo { background: var(--marca-piso); border-radius: var(--r-md); outline: 2px dashed var(--marca); outline-offset: 2px; }

/* --- la patente y el folio se leen como se dictan --- */
.patente {
  font-family: var(--letra-dato); font-weight: 600; font-size: .92rem;
  letter-spacing: .04em; background: var(--papel-alt);
  border: 1px solid var(--borde); border-radius: var(--r-sm); padding: .05rem .4rem;
}
.folio { font-family: var(--letra-dato); font-size: .78rem; color: var(--tinta-suave); }
.plata { font-family: var(--letra-dato); font-weight: 600; font-variant-numeric: tabular-nums; }

/* --- la marca de estado --- */
.marca-estado {
  font-size: .72rem; font-weight: 600; border-radius: var(--r-sm);
  padding: .1rem .4rem; letter-spacing: .02em; white-space: nowrap;
}
.marca-estado--urgente { background: var(--alerta-piso); color: var(--alerta); }
.marca-estado--espera { background: var(--aviso-piso); color: var(--aviso); }
.marca-estado--ok { background: var(--exito-piso); color: var(--exito); }

/* --- bloques con cabecera --- */
.bloque { background: var(--papel); border: 1px solid var(--borde); border-radius: var(--r-lg); box-shadow: var(--sombra-1); overflow: hidden; }
.bloque__cabeza {
  display: flex; align-items: center; gap: var(--e-2);
  padding: var(--e-3) var(--e-4); border-bottom: 1px solid var(--borde); background: var(--papel-alt);
}
.bloque__cabeza h2 {
  font-family: var(--letra-titulo); font-size: .88rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; margin: 0; color: var(--tinta-suave);
}
.bloque__cuerpo { padding: var(--e-4); }
/* El atajo de una sección, empujado al otro extremo de su cabecera. La
   cabecera ya es flex con `gap`, así que sin el `margin-left: auto` el enlace
   se pega al título y se lee como parte de él. */
.enlace-cabeza {
  margin-left: auto;
  font-size: .82rem;
  white-space: nowrap;
}
/* Dos bloques seguidos se tocaban y se leían como una caja partida por la
   mitad. El hueco lo pone el componente, no cada pantalla acordándose. */
.bloque + .bloque { margin-top: var(--e-4); }

/* Una OT cerrada, atenuada. Sale al buscar una patente --el historial son
   órdenes cerradas-- y sin esto se ve igual de viva que una en ejecución. */
.tarjeta-ot--apagada { opacity: .6; }
.tarjeta-ot--apagada:hover { opacity: 1; }

/* Una columna de un estado que el dueño APAGÓ y que aún tiene órdenes dentro.
   El tablero las sigue pintando a propósito --si no, desaparecerían de la única
   lista donde alguien las vería-- y son justo las que hay que vaciar. */
.columna--apagada .columna__cabeza { border-bottom-style: dashed; color: var(--aviso); }
.columna--apagada .columna__cuenta { background: var(--aviso-piso); color: var(--aviso); }

/* El folio, a la derecha y alineado entre tarjetas. */
.tarjeta-ot__alto .folio { margin-left: auto; }

/* --- navigation -------------------------------------------------------- */

.principal { display: flex; gap: 2px; padding: 0 var(--e-4); overflow-x: auto; }
.principal a, .principal form { display: flex; align-items: center; }
.principal a {
  gap: .45rem; font-size: .88rem; font-weight: 500;
  color: var(--tinta-suave); text-decoration: none;
  padding: .6rem .8rem; border-bottom: 2px solid transparent; white-space: nowrap;
}
.principal a:hover { color: var(--tinta); }
.principal a[aria-current="page"] { color: var(--marca); border-bottom-color: var(--marca); font-weight: 600; }
.principal svg { width: 17px; height: 17px; flex-shrink: 0; }
.principal form { margin-left: auto; }

/* --- forms ------------------------------------------------------------- *
 * 16px minimum on every control: below that, iOS Safari zooms on focus, and
 * with gloves on that is a failure, not a nuisance.
 */
.campo { margin: 0 0 1rem; }
.campo label { display: block; font-weight: 600; margin-bottom: 0.25rem; }

input, select, textarea {
  font: inherit;
  font-size: 16px;
  width: 100%;
  min-height: 48px;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--borde);
  border-radius: 6px;
  background: var(--papel);
  color: var(--tinta);
}
textarea { min-height: 7rem; resize: vertical; }

/* The most-pressed control on the intake screen: seven file inputs and seven
 * submits. The button inside a file input needs its own sizing in both
 * engines or it stays tiny. */
input[type="file"] { padding: 0.5rem; }
input[type="file"]::file-selector-button,
input[type="file"]::-webkit-file-upload-button {
  min-height: 44px;
  padding: 0 1rem;
  margin-right: 0.75rem;
  font: inherit;
  border: 1px solid var(--borde);
  border-radius: 6px;
  background: var(--fondo);
  cursor: pointer;
}

.campo--interruptor { display: flex; align-items: center; gap: 0.6rem; }
.campo--interruptor input[type="checkbox"] {
  width: 24px; height: 24px; min-height: 0; flex: 0 0 auto;
  /* Chrome le pone `margin: 3px 3px 3px 4px` por su cuenta y nadie lo quitaba,
     así que el hueco real hasta la etiqueta eran 12,6 px y no los 0,6rem del
     `gap`. Con el margen a cero manda el `gap`, que es donde se ajusta. */
  margin: 0;
}
/* The label is part of the target: a 24px box alone is not enough with gloves. */
.campo--interruptor label { margin: 0; min-height: 44px; display: flex; align-items: center; }

.campo--error input, .campo--error select, .campo--error textarea { border-color: var(--alerta); }
.requerido { color: var(--alerta); }
.ayuda, .nota { color: var(--tinta-suave); font-size: 0.9rem; }

/* El codigo del fallo. Se lee EN VOZ ALTA por telefono, asi que va en
   monoespaciada y con las letras separadas: en la de texto, un 1 y una l --o un
   0 y una O-- se dictan mal, y un codigo mal dictado no encuentra nada. */
.referencia { color: var(--tinta-suave); font-size: 0.9rem; margin-top: 1rem; }
.referencia code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: 0.08em;
  background: #f1f3f4;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  user-select: all;
}
.error { color: var(--alerta); font-weight: 600; }
.errores-resumen {
  border: 2px solid var(--alerta);
  background: #fdf2f1;
  padding: 0.75rem 1rem;
  border-radius: 6px;
  margin-bottom: 1rem;
}

.campo__con-boton { display: flex; gap: 0.5rem; align-items: stretch; }
.campo__con-boton select { flex: 1 1 auto; }

fieldset { border: 1px solid var(--borde); border-radius: 8px; padding: 1rem; margin: 0 0 1.5rem; }
legend { font-weight: 700; padding: 0 0.4rem; }

/* --- buttons ----------------------------------------------------------- */
.boton, button, .boton-mas {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;  /* el mostrador. El patio manda los suyos por su cuenta. */
  padding: 0 1.1rem;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  background: var(--papel);
  color: var(--tinta);
  text-decoration: none;
  cursor: pointer;
}
.boton--primario, button[type="submit"] {
  background: var(--marca);
  border-color: var(--marca-oscura);
  color: #fff;
}
.boton-mas { width: 48px; padding: 0; font-size: 1.4rem; }
.cancelar { display: inline-flex; align-items: center; min-height: 48px; padding: 0 0.75rem; }
.acciones { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-top: 1rem; }
.acciones-principales { margin: 0.5rem 0 1.5rem; }

/* La línea de abajo separa los filtros de lo que filtran. Sin ella la barra
   de búsqueda quedaba pegada a las cabeceras de las columnas y las dos filas
   de texto en mayúsculas se leían como una sola cosa amontonada. */
.busqueda { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: end; margin-bottom: var(--e-4); }
/* EL SEPARADOR, SÓLO CUANDO LA BÚSQUEDA VA SUELTA EN LA PÁGINA.
   `.busqueda` la usan cuatro plantillas, y en `ot/formulario.html` el
   formulario vive DENTRO de una tarjeta (`.bloque__cuerpo`). Puesto en
   `.busqueda` a secas, este borde partía esa tarjeta en dos con una raya de
   1 px justo encima del aviso de «este vehículo ya está registrado» -- que es
   exactamente lo que el comentario de `.bloque + .bloque` evita en el otro
   sentido. El hijo directo de `main` distingue las tres donde el separador se
   quiere de la que va anidada. */
main > .busqueda { padding-bottom: var(--e-3); border-bottom: 1px solid var(--borde); }
.busqueda label { font-weight: 600; }
/* EL `min-width` NO ES PARA TODOS LOS `input`, y ahí estaba el fallo.
   Alcanzaba también a `input[type=checkbox]`, así que la casilla de «Ver
   también las cerradas» medía 12rem de ancho --192 px de caja vacía-- y su
   texto quedaba al otro lado de la pantalla. `.campo--interruptor` le ponía
   24 px de `width` y perdía: `min-width` manda sobre `width`. */
.busqueda input:not([type="checkbox"]), .busqueda select { width: auto; min-width: 12rem; }

/* --- tables ------------------------------------------------------------ */
table { width: 100%; border-collapse: collapse; background: var(--papel); }
th, td { text-align: left; padding: 0.7rem 0.6rem; border-bottom: 1px solid var(--borde); }
th { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--tinta-suave); }
.fila--inactiva { opacity: 0.55; }
.tabla-ot td:first-child { font-variant-numeric: tabular-nums; font-weight: 700; }
.estado-pastilla {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--fondo);
  border: 1px solid var(--borde);
  font-size: 0.9rem;
}
.vacio { color: var(--tinta-suave); font-style: italic; }
.ficha__dato { margin: 0.35rem 0; }

/* --- catalogues and the "+" dialog ------------------------------------- *
 * `modal.js` creates this element; it appears in no template, so with no CSS
 * it rendered edge to edge with UA styling on a phone. It is the "+" button
 * the README advertises as a feature.
 */
.catalogos { display: grid; gap: 0.75rem; padding: 0; list-style: none; }
.modal-catalogo {
  width: min(34rem, 92vw);
  padding: 1.25rem;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--papel);
  color: var(--tinta);
}
.modal-catalogo::backdrop { background: rgb(0 0 0 / 45%); }

/* --- intake: photos ---------------------------------------------------- */
.rejilla-fotos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 1rem;
  padding: 0;
  list-style: none;
}
.ranura {
  border: 1px solid var(--borde);
  border-radius: 8px;
  padding: 0.75rem;
  background: var(--papel);
}
.ranura__nombre { display: block; font-weight: 600; margin-bottom: 0.5rem; }
.ranura__vacia { color: var(--tinta-suave); font-size: 0.9rem; }
.ranura--lista { border-color: var(--exito); }
.foto { max-width: 100%; height: auto; border-radius: 6px; display: block; }

/* --- intake: the damage diagram ---------------------------------------- *
 * `manipulation`, not `none`. `ingreso.js` binds only `pointerdown` — the mark
 * lands on the tap, there is no drag — so `none` would buy no reliability and
 * would create a dead zone the size of the diagram that the page cannot be
 * scrolled through with a thumb.
 */
.diagrama { margin: 1rem 0; }
.silueta {
  display: block;
  width: 100%;
  max-width: 20rem;
  height: auto;
  touch-action: manipulation;
}
.silueta--interactiva {
  cursor: crosshair;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.marca { fill: var(--dano-fondo); }
/* Same colour `ingreso.js` sets inline for a provisional mark. Two places, one
 * value: if they drift, a mark changes colour when the page reloads. */
.marca--nueva { fill: var(--marca); }
.lista-danos { padding-left: 1.2rem; }

/* --- intake: the signature --------------------------------------------- *
 * Here the drag IS the gesture, so `none` is right. The canvas is scaled by
 * CSS and `ingreso.js` already maps coordinates by `lienzo.width / caja.width`
 * — it was written for a scaled canvas that did not exist yet, so the fixed
 * width="600" overflowed a 375px phone sideways.
 */
.firma { margin: 1rem 0; }
#firma-canvas {
  width: 100%;
  height: auto;
  max-width: 100%;
  border: 1px dashed var(--borde);
  border-radius: 8px;
  background: var(--papel);
  touch-action: none;
}
.aviso-cerrado {
  border-left: 4px solid var(--exito);
  background: #eef7f1;
  padding: 0.75rem 1rem;
  border-radius: 0 6px 6px 0;
}

@media (max-width: 30rem) {
  .principal { padding: 0.75rem; }
  /* La casilla, fuera también aquí: un `width: 100%` la estiraría de lado a
     lado en el teléfono del taller. Hoy no pasa porque `.campo--interruptor`
     gana en especificidad, pero es la misma puerta que acaba de costar un
     reporte. */
  .busqueda input:not([type="checkbox"]), .busqueda select { min-width: 0; width: 100%; }
  .acciones .boton, .acciones button { width: 100%; }
}

/* --- evaluación del trabajo (H4) --------------------------------------- */

/* El ancho es lo primero que hace ilegible un formulario en pantalla grande:
   un <input> de 1900 px obliga a barrer la cabeza de lado a lado para leer un
   número de tres cifras. Se limita aquí y no campo por campo, para que una
   pantalla nueva lo herede sin acordarse. */
.punto input,
.punto select,
.punto textarea {
  max-width: 22rem;
  width: 100%;
}
.punto textarea { max-width: 34rem; }

.punto {
  border: 1px solid #d7dee2;
  border-radius: 6px;
  margin: 0.5rem 0;
  padding: 0.5rem 0.75rem;
  background: #fff;
}
.punto > summary {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.25rem 0;
}
.punto__nombre { font-weight: 600; flex: 1 1 auto; }

/* La pastilla dice el estado sin abrir el punto. Con trece paneles, esto es la
   diferencia entre leer la pantalla de un vistazo y abrirlos uno por uno. */
.pastilla {
  font-size: 0.85rem;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: #eef2f4;
  color: #33474f;
  white-space: nowrap;
}
.pastilla--ok        { background: #e3f3e8; color: #1c5c33; }
.pastilla--atencion  { background: #fdf0da; color: #7a4b00; }
.pastilla--critico   { background: #fbe3e3; color: #8a1c1c; }
.pastilla--pendiente { background: #f1f3f4; color: #5c6a70; }

.punto--registrado { border-color: #b9c8ce; }

/* La ayuda de un campo es un párrafo y no un <small> suelto: en línea se pegaba
   a la etiqueta siguiente y se leía "...cuánto tardaste. Repuesto sugerido". */
.ayuda--campo {
  margin: 0.15rem 0 0.75rem;
  font-size: 0.85rem;
  color: #5c6a70;
}

.punto label { display: block; margin-top: 0.6rem; font-weight: 500; }

/* La OTRA forma de entrar. Separada por una línea y centrada bajo el botón: es
   la salida del callejón --el técnico no tiene contraseña, el asesor no tiene
   PIN-- y tiene que verse sin competir con la acción principal de la pantalla,
   que es la que va a usar el 90 % de las veces. */
.otra-entrada {
  margin: var(--e-3) 0 0;
  padding-top: var(--e-3);
  border-top: 1px solid var(--borde);
  text-align: center;
}

/* «No soy yo» va en línea con el nombre y parece un enlace, porque se usa una
   vez de cada cien. Pintado como botón competía con la acción real. */
.evaluando { color: #5c6a70; }
.en-linea { display: inline; }
.enlace {
  background: none;
  border: 0;
  padding: 0 0 0 0.5rem;
  color: #0a6470;
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}

.grupo { margin-top: 1.5rem; border-bottom: 1px solid #e3e9eb; padding-bottom: 0.25rem; }

.fotos { display: flex; gap: 0.5rem; list-style: none; padding: 0; margin: 0.5rem 0; }
.fotos img { max-width: 7rem; border-radius: 4px; }
.subir-foto { margin-top: 0.5rem; }
.subir-foto input[type="file"] { max-width: 20rem; }

.cerrar { margin-top: 1.5rem; }

/* El aviso de la cola offline. Permanente y arriba, no en un menú: un contador
   de "pendientes por enviar" que no se ve es igual a no tenerlo, y el técnico
   se va a casa creyendo que sincronizó. */
.cola-aviso {
  background: #fdf0da;
  color: #7a4b00;
  border: 1px solid #e8c98d;
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  margin: 0 0 1rem;
  font-weight: 600;
}
.punto--encolado { border-color: #e8c98d; }

/* --- aprobación del cliente (H6) --------------------------------------- */

/* Esta página la abre alguien en su teléfono, sin cuenta y probablemente sin
   saber de coches. Por eso los botones son grandes y hay uno por decisión: un
   desplegable de tres opciones más un "confirmar" es un paso de más en la
   pantalla donde el taller se juega el trabajo. */
.linea-aprobar {
  border: 1px solid #d7dee2;
  border-radius: 6px;
  padding: 0.75rem 1rem;
  margin: 0.75rem 0;
  background: #fff;
}
.linea-aprobar h3 { margin: 0 0 0.25rem; }
.linea__precio strong { font-size: 1.25rem; }
.linea__garantia { color: #5c6a70; font-size: 0.9rem; }
.linea-aprobar button { margin-right: 0.5rem; margin-top: 0.5rem; }
.linea--decidida { background: #f6f8f9; }
.linea__decidida { font-weight: 600; color: #1c5c33; }

.urgencia { margin-top: 1.5rem; }
.urgencia--ahora { color: #8a1c1c; }

/* La casilla del art. 41 va visible y separada, no en letra pequeña: "no lo
   leyó" es la respuesta previsible a lo segundo. */
.consentimiento {
  display: block;
  background: #fdf0da;
  border: 1px solid #e8c98d;
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  margin: 0.5rem 0;
}

.total-aprobado {
  border-top: 2px solid #0a6470;
  margin-top: 1.5rem;
  padding-top: 0.75rem;
  font-size: 1.1rem;
}

.pastilla--aprobada { background: #e3f3e8; color: #1c5c33; }
.pastilla--rechazada { background: #fbe3e3; color: #8a1c1c; }
.pastilla--diferida { background: #fdf0da; color: #7a4b00; }

.enlace { width: 100%; max-width: 40rem; font-family: monospace; }
.enlace-nuevo { background: #e9f5f7; border-radius: 6px; padding: 0.75rem 1rem; }

/* --- la cola de recontacto ---------------------------------------------
   Una lista para llamar por teléfono, no una tabla para leer en pantalla
   grande: cada fila es un bloque con nombre, número y una sola acción
   principal, y el número es lo bastante grande para tocarlo con el pulgar. */
.cola-recontacto { list-style: none; padding: 0; margin: 0; }

.recontacto {
  background: var(--papel);
  border: 1px solid var(--borde);
  border-left: 4px solid var(--borde);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  margin-bottom: 0.75rem;
}

/* Lo vencido se distingue por el borde y no sólo por el color del texto: es
   lo que hace que la lista se pueda ordenar de un vistazo sin leerla. */
.recontacto--vencida { border-left-color: var(--alerta); }

.recontacto p { margin: 0 0 0.35rem; }
.recontacto__quien { font-size: 1.05rem; }
.recontacto__quien a { font-variant-numeric: tabular-nums; }
.recontacto__que strong { font-size: 1.1rem; }
.recontacto__contexto { font-size: 0.85rem; }

.recontacto__cerrar {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.recontacto__cerrar input {
  flex: 1 1 auto;
  min-width: 0;
}
.recontacto__aplazar { margin-top: 0.35rem; }

@media (max-width: 30rem) {
  /* En el teléfono el campo y el botón no caben en una línea sin encoger el
     campo hasta hacerlo inservible. */
  .recontacto__cerrar { flex-direction: column; }
}

/* Una etiqueta que existe para el lector de pantalla y no para la vista.
   `display: none` la escondería de los dos. */
.visualmente-oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* `aviso` se usaba en cuatro plantillas y no existía: el texto salía como
   párrafo suelto, que es justo lo que no se lee. */
.aviso {
  background: #fdf6e6;
  border: 1px solid #e8c98d;
  border-radius: 6px;
  padding: 0.6rem 0.9rem;
  color: var(--aviso);
}

/* --- las que estaban en las plantillas y no en la hoja ------------------
   Once clases del circuito nuevo se escribieron sin estilo, así que el
   presupuesto salía como una tabla sin formato y la lista de técnicos como
   radios sueltos. Es buena parte de por qué la aplicación "no se ve usable". */

.lineas {
  width: 100%;
  border-collapse: collapse;
  background: var(--papel);
}
.lineas th, .lineas td {
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--borde);
  text-align: left;
  vertical-align: top;
}
.lineas thead th {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--tinta-suave);
  border-bottom: 2px solid var(--borde);
}
.lineas tfoot th, .lineas tfoot td { border-bottom: none; padding-top: 0.75rem; }

/* Los importes alineados a la derecha y con cifras de ancho fijo. Una columna
   de precios que no alinea obliga a leer cada número entero para compararlos. */
.numero {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.precio {
  width: 7rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.anadir { margin-top: 1.25rem; }
.anadir summary { cursor: pointer; font-weight: 600; }
/* DOS COSAS DISTINTAS SE LLAMABAN `.anular`, y la de abajo ganaba.
   `caja.html` y `entrega.html` la ponen en un <form> y quieren `display:flex`;
   `evaluacion.html` y `ingreso/checklist.html` la ponen en un <details>, al que
   ese flex le pone el summary y el contenido en la misma linea y le rompe el
   plegado. Misma hoja, misma clase, ultima regla gana: el desplegable de
   evaluacion llevaba tiempo roto y nadie lo miro. Ahora son dos nombres. */
.anular-plegable { margin-top: 1.5rem; }
.anular-plegable summary { cursor: pointer; color: var(--alerta); }
.anular-plegable form { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.6rem; }
.anular-plegable input { min-width: 14rem; }

/* Anular es destructivo y se lee como tal, sin gritar: el peso lo pone el
   color del texto, no un bloque rojo que compita con el resto de la pantalla. */
.boton--peligro { border-color: var(--alerta); color: var(--alerta); background: var(--papel); }
.boton--peligro:hover { background: var(--alerta-piso); }

.lista-plantillas { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.lista-plantillas a {
  display: inline-block;
  border: 1px solid var(--borde);
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  background: var(--papel);
  text-decoration: none;
}

.punto__registrado { margin: 0.25rem 0 0; }
.punto__nota { margin: 0.15rem 0 0; color: var(--tinta-suave); font-size: 0.9rem; }

/* La pantalla del PIN se usa de pie, en el taller, con un aparato compartido y
   posiblemente con guantes. Cada nombre es un blanco grande. */
.tecnicos { border: none; padding: 0; margin: 0 0 1rem; }
.tecnicos legend { font-weight: 600; padding: 0; margin-bottom: 0.5rem; }
.tecnico {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  border: 1px solid var(--borde);
  border-radius: 6px;
  background: var(--papel);
  padding: 0.7rem 0.9rem;
  margin-bottom: 0.4rem;
  cursor: pointer;
  font-size: 1.05rem;
}
.tecnico:has(input:checked) {
  border-color: var(--marca);
  box-shadow: inset 0 0 0 1px var(--marca);
}

.verificar { max-width: 22rem; }

/* Las fotos del hallazgo en la página del cliente. Una tira horizontal y no
   una rejilla: en el teléfono la rejilla convierte doce fotos en una pantalla
   de miniaturas ilegibles, y esto se mira una a una. */
.fotos-hallazgo {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0;
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.fotos-hallazgo li { flex: 0 0 auto; scroll-snap-align: start; }
.fotos-hallazgo img {
  display: block;
  height: 6rem;
  width: auto;
  border-radius: 6px;
  border: 1px solid var(--borde);
}

/* La confirmación antes de sembrar una capacidad. Va destacada porque la
   decisión es irreversible, y con los nombres de lo que va a crear: «esto añade
   dos etapas y seis conceptos» se puede sopesar, «es irreversible» sólo asusta. */
.confirmar-capacidad {
  border: 2px solid var(--marca);
  border-radius: 8px;
  background: var(--papel);
  padding: 1rem 1.25rem;
  margin: 1rem 0;
}
.confirmar-capacidad h3 { margin-top: 0; }
.confirmar-capacidad p { margin: 0.4rem 0; }
.confirmar-capacidad__si { display: inline-block; margin-right: 0.5rem; }

/* --- los modificadores que el guardián no veía --------------------------
   `tests/test_estilos.py` descartaba el atributo entero en cuanto llevaba
   Jinja dentro, que es justo donde viven los modificadores. Estas tres se
   escribieron sin estilo y se ven en las dos pantallas que más importan. */

/* Las tres urgencias, no sólo la roja. Con «Ahora» en rojo y las otras dos en
   negro, el cliente lee que hay una cosa urgente y dos sin clasificar -- que es
   lo contrario de lo que el agrupado quiere decir. */
.urgencia--pronto { color: #9a6100; }
.urgencia--vigilar { color: var(--tinta-suave); }

/* Una línea bonificada tiene que distinguirse: el taller regaló algo y el
   documento existe para que se vea que lo regaló. */
.linea--bonificada { background: #f2f8f4; }
.linea--bonificada td { color: var(--tinta-suave); }

/* El botón de generar el presupuesto, con su recuento al lado: «genera 3
   líneas» se pulsa con confianza y «Generar» a secas no. */
.generar-presupuesto {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin: 0.5rem 0;
}

/* El alta del aparato compartido. Va en su propia sección porque es una
   decisión sobre ESTE aparato y no sobre el taller: quien la lee tiene que
   entender que le afecta sólo a la tablet que tiene en la mano. */
.aparato { margin-top: 2rem; }

/* Salir vive en la navegación y es un formulario, no un enlace: un GET a
   /salir desde un correo cerraría la sesión de quien lo abra. Se le quita el
   aspecto de botón para que no compita con las secciones. */
.salir { display: inline; }
.salir button {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: underline;
}

/* --- el comprobante de entrega -----------------------------------------
   Este papel se imprime y se le da al cliente, así que tiene dos vidas: en
   pantalla y en A4. Lo que se cuida es que la versión impresa no pierda
   nada -- una garantía que no sale al imprimir es una garantía que el cliente
   no puede reclamar. */
.comprobante {
  max-width: 48rem;
  margin: 0 auto;
  background: var(--papel);
  padding: 1.5rem;
  border: 1px solid var(--borde);
  border-radius: 8px;
}
.comprobante__cabecera {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--marca);
  padding-bottom: 0.75rem;
}
.comprobante__cabecera h1 { margin: 0; font-size: 1.4rem; }
.comprobante__folio { margin: 0.2rem 0 0; color: var(--tinta-suave); }
.comprobante__taller { text-align: right; font-size: 0.9rem; line-height: 1.45; }

/* La advertencia de que no es un DTE. Va destacada porque es lo que evita que
   un papel con RUT, detalle y total se confunda con una boleta. */
.comprobante__no_es_dte {
  background: #fdf6e6;
  border: 1px solid #e8c98d;
  border-radius: 6px;
  padding: 0.5rem 0.8rem;
  font-size: 0.85rem;
  margin: 1rem 0;
}

.comprobante__partes p { margin: 0.25rem 0; }
.comprobante__bloque { margin-top: 1.5rem; }
.comprobante__bloque h2 {
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--tinta-suave);
  border-bottom: 1px solid var(--borde);
  padding-bottom: 0.2rem;
}
/* La garantía, con su regla. Se distingue del resto porque es lo que el cliente
   va a buscar dentro de seis meses. */
.comprobante__garantia { color: var(--marca-oscura); }

.comprobante__totales { margin-top: 1.5rem; }
.comprobante__regalado {
  background: #f2f8f4;
  border-radius: 6px;
  padding: 0.5rem 0.8rem;
}
.comprobante__pie { margin-top: 2rem; border-top: 1px solid var(--borde); padding-top: 1rem; }
.comprobante__firmas {
  display: flex;
  justify-content: space-between;
  gap: 3rem;
  margin-bottom: 1.5rem;
}
.comprobante__firmas span {
  flex: 1;
  border-top: 1px solid var(--tinta);
  padding-top: 0.3rem;
  margin-top: 2.5rem;
  font-size: 0.85rem;
  text-align: center;
}

/* --- la pantalla de entrega ---------------------------------------------
   Los dos botones del técnico van uno al lado del otro y con el mismo peso:
   «no se pudo» es una respuesta legítima, y esconderla detrás de un enlace
   pequeño empuja a marcar «se hizo» para salir del paso. */
.por-marcar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--borde);
  border-radius: 8px;
  margin-bottom: 0.6rem;
}
.por-marcar p { flex-basis: 100%; margin: 0 0 0.3rem; }
.marcar { display: flex; align-items: center; gap: 0.4rem; margin: 0; }
.marcar input[type="text"], .marcar input:not([type]) { min-width: 14rem; }

.marcadas { list-style: none; padding: 0; margin: 0; }
.marcada {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.9rem;
  border-left: 3px solid var(--borde);
  margin-bottom: 0.4rem;
}
.marcada--realizado { border-left-color: #1c5c33; }
.marcada--no_realizado { border-left-color: #8a1c1c; }
.marcada small { flex-basis: 100%; }

.entrega {
  padding: 0.8rem 1rem;
  border: 1px solid var(--borde);
  border-radius: 8px;
  margin-bottom: 0.7rem;
}
/* Anulada y a la vista: se conserva el registro entero a propósito, así que
   tiene que leerse como anulado sin desaparecer de la pantalla. */
.entrega--anulada { opacity: 0.65; border-style: dashed; }
/* Deshacer no compite con emitir: mismo sitio, menos peso. */
.anular { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.6rem; }
.anular input { min-width: 14rem; }

/* Anulado: lo primero que se lee, y sobrevive a la impresión. Un cliente que
   guarda su copia tiene que poder verlo sin llamar a nadie. */
.comprobante__anulado {
  border: 2px solid #8a1c1c;
  background: #fbe3e3;
  color: #8a1c1c;
  padding: 0.7rem 1rem;
  border-radius: 6px;
  margin: 0 0 1.2rem;
}
.comprobante__anulacion { margin: 1.5rem 0; }
.comprobante__anulacion p { margin-bottom: 0.8rem; }

@media print {
  /* Al imprimir sobra todo lo que no es el documento, y el borde y el fondo
     gastan tinta sin añadir nada. Los saltos de página no pueden cortar un
     bloque de garantía: media fecha impresa no es una fecha. */
  .principal, .migas, .acciones-principales { display: none !important; }
  .comprobante { border: none; max-width: none; padding: 0; }
  .comprobante__bloque, .comprobante__totales, .comprobante__pie { break-inside: avoid; }
  .comprobante__garantia { break-inside: avoid; }
  /* El aviso de anulado se imprime SIEMPRE, con su borde: sin
     `print-color-adjust` el fondo desaparece y queda un texto suelto. */
  .comprobante__anulado {
    break-inside: avoid;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  a[href]::after { content: ""; }
}

/* --- los envíos al cliente ----------------------------------------------
   Lo fallido NO se esconde: un registro que sólo enseña los éxitos le hace
   creer al asesor que avisó cuando no avisó. */
.envios ul { list-style: none; padding: 0; margin: 0; }
.envio {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--borde);
}
.envio--fallido { opacity: 0.8; }

/* --- la caja -------------------------------------------------------------
   Lo prometido se distingue de lo cobrado a la vista: son dos cifras que no
   son la misma, y mezclarlas es como un taller descubre a fin de mes que le
   faltan tres transferencias. */
.saldo { margin-bottom: 1.2rem; }
.saldo--riesgo th, .saldo--riesgo td { color: #7a4b00; }

.pago {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--borde);
  border-radius: 8px;
  margin-bottom: 0.6rem;
}
.pago p { flex-basis: 100%; margin: 0; }
/* Anulado y a la vista: esconderlo deja al asesor mirando una caja que no
   cuadra sin saber por qué. */
.pago--anulado { opacity: 0.65; border-style: dashed; }
.pago--anulado > p > strong { text-decoration: line-through; }
.conciliar { margin: 0; }

/* --- por cobrar ---------------------------------------------------------- */
.cuadro { margin-bottom: 1.5rem; }
.deudor { margin-bottom: 1.2rem; }
.deudor h2 { display: flex; justify-content: space-between; gap: 1rem; }
.deudor ul { list-style: none; padding: 0; margin: 0; }
.deuda {
  padding: 0.4rem 0 0.4rem 0.7rem;
  border-left: 3px solid var(--borde);
  margin-bottom: 0.3rem;
}
/* Cuanto más vieja, más se ve. La que se cobra tarde es la que no se cobra. */
.deuda--al_dia   { border-left-color: #1c5c33; }
.deuda--treinta  { border-left-color: #7a4b00; }
.deuda--sesenta  { border-left-color: #b35c00; }
.deuda--noventa  { border-left-color: #8a1c1c; }

/* Un aviso que BLOQUEA no se parece a uno informativo: el asesor tiene un
   cliente delante y necesita ver de un vistazo que esto no sigue. */
.aviso--bloquea {
  border-left: 4px solid #8a1c1c;
  background: #fbe3e3;
  color: #8a1c1c;
}

/* --- los reclamos de garantía -------------------------------------------
   Lo cerrado NO se esconde: es la prueba de por qué el vencimiento de esta
   pieza es más tardío que el de sus vecinas. */
.reclamable {
  padding: 0.9rem 1rem;
  border: 1px solid var(--borde);
  border-radius: 8px;
  margin-bottom: 0.9rem;
}
.reclamable h2 { margin-top: 0; font-size: 1.05rem; }
.reclamos { list-style: none; padding: 0; margin: 0.6rem 0 0; }
.reclamo { padding: 0.4rem 0; }
.reclamo--abierto { border-left: 3px solid #7a4b00; padding-left: 0.7rem; }
.reclamo--cerrado { border-top: 1px solid var(--borde); }


/* --- el modo oscuro (2026-09-06) ----------------------------------------
 *
 * Un taller tiene el mostrador bajo tubo fluorescente y el patio a pleno sol o
 * de noche. Se respeta lo que el aparato pida; no hay interruptor propio porque
 * sería una preferencia más que guardar y que se desincroniza entre la tablet
 * compartida y el móvil de cada uno.
 *
 * Sólo se redefinen VARIABLES. Ninguna regla de componente vive aquí dentro: un
 * color declarado sólo en este bloque no existe en modo claro, y ése es el
 * fallo clásico que deja texto de un tema sobre el fondo del otro.
 */
@media (prefers-color-scheme: dark) {
  :root {
    --fondo: #0f1518;
    --papel: #161e22;
    --papel-alt: #1d272c;
    --tinta: #e8edef;
    --tinta-suave: #9cacb4;
    --borde: #2a363c;
    --borde-firme: #3a484f;
    --marca: #4fa9b6;
    --marca-oscura: #6fc3cf;
    --marca-piso: #10333a;
    --alerta: #e5877b;
    --alerta-piso: #331916;
    --exito: #6dbf95;
    --exito-piso: #14291f;
    --aviso: #d6a551;
    --aviso-piso: #2e2413;
    --sombra-1: 0 1px 2px rgba(0, 0, 0, .4);
    --sombra-2: 0 2px 8px rgba(0, 0, 0, .5);

    /* El diagrama de daños se dibuja con estas; sin ellas, la silueta del coche
       desaparece sobre el fondo oscuro y el técnico no puede marcar nada. */
    --silueta-fondo: #1d272c;
    --silueta-linea: #9cacb4;
    --silueta-vidrio: #2a363c;
    --silueta-techo: #222c31;
  }
}


/* --- el aviso del tablero ------------------------------------------------
 * Vive en la pantalla y no en un alert(): hay que poder leerlo MIENTRAS se mira
 * dónde volvió la tarjeta. Un alert tapa justo eso.
 */
.aviso-tablero {
  margin: 0 0 var(--e-3);
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-md);
  font-size: .9rem;
  background: var(--exito-piso);
  color: var(--exito);
  border: 1px solid var(--exito);
}
.aviso-tablero--error { background: var(--alerta-piso); color: var(--alerta); border-color: var(--alerta); }

/* Mientras el servidor contesta. Sin esto, un servidor lento parece un tablero
   que ya guardó -- y la tarjeta se queda donde no está. */
.tarjeta-ot--enviando { opacity: .55; pointer-events: none; }

/* --- el vídeo de un hallazgo (2026-09-06) --------------------------------
 *
 * Vive DENTRO del punto de evaluación, debajo de las fotos, y hereda sus
 * tamaños: esto se usa en el patio, con guantes y con el coche delante.
 */

.subir-video {
  margin-top: var(--e-3);
  padding-top: var(--e-3);
  border-top: 1px dashed var(--borde);
}
.subir-video label { display: block; margin-bottom: var(--e-1); font-weight: 500; }
.subir-video input[type="file"] {
  /* Igual que el de la foto: el dedo con guante necesita blanco donde pulsar. */
  width: 100%;
  min-height: 44px;
  padding: var(--e-2);
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  background: var(--papel);
}

.videos { list-style: none; margin: 0 0 var(--e-3); padding: 0; display: grid; gap: var(--e-2); }

.video {
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  padding: var(--e-2);
}

/* 16:9 sin JavaScript ni alto fijo: el iframe de Bunny se estira al ancho que
   tenga el punto, que en el móvil es toda la pantalla y en el mostrador no. */
.video__marco {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--r-sm);
  overflow: hidden;
}
.video__marco iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.video__aviso {
  margin: 0;
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-sm);
  font-size: .9rem;
  background: var(--papel-alt);
  color: var(--tinta-suave);
}
.video__aviso--error { background: var(--alerta-piso); color: var(--alerta); }

.video__quitar {
  margin-top: var(--e-2);
  min-height: 44px;
  padding: 0 var(--e-3);
  font: inherit;
  font-size: .88rem;
  background: none;
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  color: var(--tinta-suave);
  cursor: pointer;
}
.video__quitar:hover { border-color: var(--alerta); color: var(--alerta); }
.video__quitar[disabled] { opacity: .5; cursor: default; }

/* --- la ficha del cliente y la del vehículo (2026-09-06) -----------------
 *
 * Nacieron de una pregunta del dueño señalando la pantalla: «¿dónde accedo a la
 * información de los clientes?». Se apoyan en `.bloque` para las secciones y
 * sólo añaden lo que no existía: la rejilla de un formulario de ficha, la lista
 * de coches y el historial de dueños.
 */

/* La tabla de clientes NO hereda de `.tabla-ot`: allí la primera celda es el
   folio y va en cifras tabulares y en negrita. Aquí la primera celda es un
   nombre, y en tabulares se lee como un código de pieza. */
.tabla-clientes td:first-child { font-weight: 600; }
.tabla-clientes .patente + .patente { margin-left: var(--e-1); }

/* La de vehículos: la patente manda, así que va en su propia celda y el resto
   se lee alrededor. Como en la de clientes, NO hereda de `.tabla-ot`: allí la
   primera celda es un folio en cifras tabulares. */
.tabla-vehiculos td:nth-child(2) { color: var(--tinta-suave); }

/* Rejilla que se pliega sola: en el mostrador caben tres columnas y en la
   tablet del patio una, sin punto de ruptura escrito a mano. */
.ficha-form__campos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--e-3);
}
.ficha-form .acciones { margin-top: var(--e-3); }

.lista-vehiculos { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-2); }
.lista-vehiculos li { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.vehiculo__detalle { color: var(--tinta-suave); font-size: .9rem; }

/* El historial se lee de arriba abajo como una línea de tiempo, del dueño de
   hoy al primero. El tramo vigente lleva marca propia: sin ella hay que
   comparar fechas para saber cuál es el de ahora, y ése es el único que
   importa cuando suena el teléfono. */
.historial { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-2); }
.historial__tramo {
  display: flex; align-items: baseline; gap: var(--e-2); flex-wrap: wrap;
  padding-left: var(--e-3);
  border-left: 3px solid var(--borde);
}
.historial__tramo--vigente { border-left-color: var(--marca); font-weight: 600; }
.historial__fechas { font-family: var(--letra-dato); font-size: .82rem; color: var(--tinta-suave); }
.historial__motivo { color: var(--tinta-suave); font-size: .9rem; font-style: italic; }

/* --- quién trabaja aquí (2026-09-06) --------------------------------------
 *
 * El bloqueo del PIN era invisible: la persona decía «no me deja» y nadie podía
 * confirmarlo ni distinguirlo de un PIN olvidado. Esta lista existe para que se
 * vea, y el botón de devolverle los intentos vive al lado de la marca.
 */
.personas { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-2); }
.persona {
  display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap;
  padding: var(--e-2) 0;
  border-bottom: 1px solid var(--borde);
}
.persona:last-child { border-bottom: 0; }
.persona__nombre { font-weight: 600; margin-right: var(--e-1); }
/* Alguien desactivado sigue en la lista, atenuado: quitarlo dejaría la pregunta
   «¿y dónde está fulano?» sin respuesta en la única pantalla que la contesta. */
.persona--inactiva { opacity: .55; }

/* --- el índice de un formulario largo (2026-09-07) ------------------------
 *
 * Lo pidió el dueño: «es muy largo y hacer scroll hasta el final es un
 * problema». El alta de una orden son tres secciones --cliente, vehículo,
 * orden-- y la última queda fuera de pantalla siempre.
 */
.con-indice { display: grid; grid-template-columns: 11rem 1fr; gap: var(--e-6); align-items: start; }
/* En el móvil se pliega arriba: una columna de 11rem en una pantalla de 375px
   se come el formulario, y el alta se rellena también desde el teléfono. */
@media (max-width: 52rem) { .con-indice { grid-template-columns: 1fr; gap: var(--e-3); } }

.indice-form {
  position: sticky;
  /* Debajo de la barra pegajosa. Decía «que mide ~3.4rem» y ponía 4rem, pero la
     barra mide 69 px: los 5 px de arriba del índice quedaban debajo de ella. */
  top: calc(var(--alto-barra) + var(--e-2));
  display: flex; flex-direction: column; gap: 2px;
  font-size: .9rem;
}
@media (max-width: 52rem) {
  .indice-form { position: static; flex-direction: row; flex-wrap: wrap; gap: var(--e-2); }
}
.indice-form__et {
  font-family: var(--letra-titulo);
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--tinta-suave); font-weight: 700; margin-bottom: var(--e-1);
}
@media (max-width: 52rem) { .indice-form__et { width: 100%; margin: 0; } }
.indice-form a {
  color: var(--tinta-suave); text-decoration: none;
  padding: .3rem var(--e-2);
  border-left: 2px solid var(--borde);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.indice-form a:hover { color: var(--marca); border-left-color: var(--marca); background: var(--marca-piso); }
@media (max-width: 52rem) {
  .indice-form a { border-left: 0; border: 1px solid var(--borde); border-radius: var(--r-md); }
}

/* LOS SALTOS DEL ÍNDICE NO LLEVAN REGLA PROPIA. La barra de arriba es
   pegajosa y al saltar a una sección su título quedaría TAPADO --el fallo
   clásico de los índices de ancla, el que hace concluir que el enlace no
   funciona--; lo evita el `scroll-padding-top` de `html`, junto a `.barra`. Aquí
   había un `scroll-margin-top` sólo para estas tres, y sumado a aquél las
   dejaría 85 px más abajo de la cuenta. */

/* La firma, después de firmar. Se enseña grande y se puede abrir: es la prueba
   de cómo se entregó el coche, y en miniatura no sirve para discutir un rayón. */
.firma-vista { display: inline-block; margin-top: var(--e-3); }
.firma-vista img {
  max-width: min(420px, 100%);
  background: #fff;
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  padding: var(--e-2);
}

/* El estado del enlace de aprobación. «No me deja entrar» no se podía
   diagnosticar desde el taller: ni los intentos gastados ni la caducidad
   salían en ninguna pantalla. */
.estado-enlace { display: flex; align-items: baseline; gap: var(--e-2); flex-wrap: wrap; margin-bottom: var(--e-3); }

/* --- las alternativas de una línea (2026-09-07) --------------------------
 *
 * «Original a 180.000 con 12 meses, alternativo a 95.000 con 6». Van DENTRO de
 * la tabla, en una fila propia bajo su línea, y no en un panel aparte: lo que
 * se compara es esa pieza contra esa pieza, y separarlas obligaría a recordar
 * cuál era la de arriba.
 */
.cantidad {
  font-family: var(--letra-dato); font-size: .82rem; font-weight: 600;
  color: var(--tinta-suave); margin-left: var(--e-1);
}
.fila-alternativas > td { padding-top: 0; background: var(--papel-alt); }
.alternativas { list-style: none; margin: 0 0 var(--e-2); padding: 0; display: grid; gap: var(--e-1); }
.alternativa {
  display: flex; align-items: baseline; gap: var(--e-2); flex-wrap: wrap;
  padding: var(--e-2) var(--e-3);
  background: var(--papel);
  border: 1px solid var(--borde);
  border-left: 3px solid var(--borde-firme);
  border-radius: 0 var(--r-md) var(--r-md) 0;
}
.alternativa__que { flex: 1 1 14rem; }
.alternativa__que small { display: block; }
/* La elegida se ve sin leerla: es la que se va a emitir, con su precio y su
   garantía, y confundirla con otra cambia el papel que firma el cliente. */
.alternativa--elegida { border-left-color: var(--exito); background: var(--exito-piso); }

/* Las alternativas en la página del CLIENTE. Van dentro de la línea que
   comparan, no en un bloque aparte: separarlas obligaría a recordar cuál era
   la de arriba, y esta pantalla se lee en el móvil y de una pasada. */
.opciones-linea { margin-top: var(--e-3); padding-top: var(--e-3); border-top: 1px dashed var(--borde); }
.opciones-linea__et {
  font-family: var(--letra-titulo);
  font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--tinta-suave); font-weight: 700; margin: 0 0 var(--e-2);
}

/* Si el comprobante sigue siendo el que se emitió.

   Lo normal --que cuadre-- va discreto A PROPÓSITO: una marca verde en cada
   reimpresión enseña a no mirar esa línea, y entonces la roja pasa
   desapercibida justo el día que aparece. La rota grita, y en el papel: quien
   la ve está a punto de usar el documento como prueba de lo que se entregó. */
.huella { font-size: .78rem; margin-left: var(--e-2); }
.huella--ok { color: var(--exito); }
.huella--rota {
  color: var(--alerta);
  font-weight: 700;
  background: var(--alerta-piso);
  padding: .1rem .4rem;
  border-radius: var(--r-sm);
}

/* Lo que se dijo en la llamada, en la fila de la llamada. Con el filete a la
   izquierda porque es una CITA de una conversación y no un campo más: leídas
   seguidas --«demasiado caro», «demasiado caro», «lo hizo el vecino»-- son lo
   que convierte veinte llamadas sueltas en una conclusión. */
.recontacto__resultado {
  margin: var(--e-2) 0 0;
  padding-left: var(--e-3);
  border-left: 3px solid var(--borde-firme);
  color: var(--tinta);
}

/* Por qué no llegó el mensaje, en la misma línea que la pastilla roja: leer
   «falló» sin la razón lleva a reintentar, y reintentar REVOCA el enlace que el
   cliente ya tiene abierto. La razón es lo que evita el segundo envío. */
.envio__porque { color: var(--tinta-suave); }
/* La respuesta cruda del proveedor: jerga en inglés, plegada. Se conserva
   porque es lo único con lo que se le puede preguntar a Meta qué pasó con ESE
   mensaje, y los registros del servidor en este taller no los mira nadie. */
.envio__detalle { display: inline; }
.envio__detalle summary { display: inline; cursor: pointer; font-size: .82rem; color: var(--tinta-suave); }
.envio__detalle code { display: block; margin-top: var(--e-1); font-size: .78rem; word-break: break-all; }

/* El selector de color y su «sin color», en la misma celda. En columna se
   leían como dos campos distintos de la misma fila; en línea se lee como lo
   que es: un color y el interruptor que lo apaga. */
.celda-color { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.celda-color input[type="color"] {
  width: 2.4rem; height: 1.8rem; padding: 0;
  border: 1px solid var(--borde); border-radius: var(--r-sm); background: none;
}
/* --- el margen y la cuenta del cliente (2026-09-07) ---------------------- */

/* El margen se distingue de las otras dos cifras y no compite con ellas: la que
   contesta «cuánto sale» es el total, y ésta contesta otra pregunta, la del
   dueño. Filete a la izquierda en vez de otro tamaño de letra. */
.cifra--margen { border-left: 3px solid var(--borde-firme); padding-left: var(--e-3); }
.cifra__nota { display: block; color: var(--tinta-suave); font-size: .74rem; }

/* La cuenta corriente dentro de la ficha del cliente. Reutiliza `.deuda`, que
   ya trae el color por tramo de antigüedad: dos listas de deuda con dos
   aspectos distintos se leerían como dos cosas distintas. */
.bloque--deuda .bloque__cabeza { background: var(--aviso-piso); }
.cuenta { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-2); }

/* --- «¿venía así, o pasó aquí?» (2026-09-08) ----------------------------- */

/* Las dos columnas al mismo ancho: lo que se hace aquí es LEERLAS EN PAREJA,
   fila por fila, y una más estrecha que la otra empuja a leer sólo una. */
.comparar th[scope="row"] { white-space: nowrap; vertical-align: top; }
.comparar td { vertical-align: top; width: 42%; }

/* La zona que merece una mirada. Filete a la izquierda y fondo muy tenue: tiene
   que encontrarse de un vistazo entre seis filas sin gritar, porque esto NO es
   un veredicto -- es una fila que hay que leer antes de hablar con el cliente. */
.fila--mirar { background: var(--alerta-piso); }
.fila--mirar th[scope="row"] { box-shadow: inset 3px 0 0 var(--alerta); }
.aviso--mirar { border-left: 3px solid var(--alerta); }

/* Varias marcas o varios hallazgos en la misma celda, sin viñetas: son dos o
   tres líneas dentro de una casilla, no una lista con vida propia. */
.lista-llana { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-1); }
.lista-llana .nota { display: block; }

/* --- la portada del dia (2026-09-08) ------------------------------------- */

/* Dos tarjetas lado a lado en escritorio y apiladas en el movil. `auto-fit` y
   no dos columnas fijas: cuando solo hay una tarjeta --lo normal a media
   manana-- ocupa el ancho entero en vez de dejar media pantalla en blanco, que
   se lee como que falta algo. */
.portada {
  display: grid;
  gap: var(--e-4);
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
}
/* `cuadro` da margen inferior y aqui lo pone el `gap`: sumados, las dos
   tarjetas quedan mas separadas entre si que del resto de la pagina. */
.portada .cuadro { margin-bottom: 0; }

/* --- el menu lateral plegable (2026-09-08) ------------------------------- */

/* Un `<details>` y no un script. Sin npm y sin build, todo JS de este producto
   es una mejora sobre algo que ya funciona --lo dice `static/js/vendor/LEEME`--
   y un menu que necesita JavaScript para abrirse es un menu que a veces no se
   abre. `<details>` lo hace el navegador, sin red y sin nada cargado. */
.lateral {
  border-bottom: 1px solid var(--borde);
  background: var(--papel);
}
.lateral__tirador {
  display: flex; align-items: center; gap: var(--e-2);
  padding: .5rem var(--e-4);
  font-family: var(--letra-titulo);
  font-size: .78rem; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 700; color: var(--tinta-suave);
  cursor: pointer; list-style: none;
}
/* El triangulo por defecto de Safari e iOS no se quita con `list-style`. */
.lateral__tirador::-webkit-details-marker { display: none; }
.lateral__tirador svg { width: 16px; height: 16px; }
/* Y el estado se dice, porque el triangulo no esta: cerrado dice «abrir». */
.lateral[open] .lateral__tirador { color: var(--tinta); }

.lateral__lista { display: flex; flex-direction: column; padding: 0 var(--e-2) var(--e-2); }
.lateral__lista a {
  display: flex; align-items: center; gap: .55rem;
  padding: .5rem var(--e-3); border-radius: var(--r-md);
  font-size: .9rem; color: var(--tinta-suave); text-decoration: none;
}
.lateral__lista a:hover { background: var(--papel-alt); color: var(--tinta); }
.lateral__lista a[aria-current="page"] { background: var(--marca-piso); color: var(--marca); font-weight: 600; }
.lateral__lista svg { width: 17px; height: 17px; flex-shrink: 0; }

/* EN ESCRITORIO va a la izquierda y abierto; EN EL MOVIL, plegado arriba. Es el
   mismo patron que `.con-indice` usa para el indice del alta de OT, y por la
   misma razon: en 375 px un lateral desplegado se come lo que se viene a leer.

   `max-width` y no `min-width` para que el movil sea el caso por defecto: si el
   CSS no llegara a cargar, lo que queda es la lista entera visible, que es lo
   utilizable. */
@media (min-width: 52.0625rem) {
  .lateral {
    position: fixed; top: 0; left: 0; bottom: 0; width: 12rem;
    border-right: 1px solid var(--borde); border-bottom: none;
    overflow-y: auto; z-index: 5;
    /* Debajo de la barra. Eran 3.4rem, 54 px, contra una barra de 69: la
       primera fila del lateral quedaba 15 px por encima de la del contenido. */
    padding-top: var(--alto-barra);
  }
  /* El contenido se aparta. `body` y no `main`, para que la barra de arriba
     tampoco quede debajo del lateral. */
  body { padding-left: 12rem; }
}

/* Los interruptores de configuracion, en rejilla: ocho casillas en columna son
   ocho lineas de scroll para una decision que se toma de un vistazo. */
.interruptores {
  display: grid; gap: var(--e-2);
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
}
/* --- la agenda (2026-09-08) ---------------------------------------------- */

/* La hora en monoespaciada: es por lo que se recorre la lista, y sin ancho fijo
   las 9:00 y las 14:30 no alinean -- que es justo lo que hace que se lea de un
   vistazo o no. */
.cita__hora {
  font-family: var(--letra-dato);
  font-variant-numeric: tabular-nums;
  margin-right: var(--e-2);
}
/* Una línea de la agenda. Sin adornos: la lista se lee de arriba abajo por la
   hora, y una tarjeta por cita convertiría doce citas en doce cajas. */
.cita { display: flex; align-items: baseline; gap: var(--e-1); flex-wrap: wrap; }
/* La que ya se resolvió se apaga sin desaparecer: la agenda del día se mira
   también para saber a quién falta atender. */
.cita--llego, .cita--no_llego { color: var(--tinta-suave); }
/* «NO LLEGO» NO ES LO MISMO QUE «LLEGO», y con la regla de arriba a secas se
   leian igual: los dos en gris. La diferencia es la que decide si hay que
   llamar a alguien, y `proximas` sólo trae RESERVADA, así que «quién no llegó
   el lunes» no se puede contestar en ninguna otra parte de la agenda. */
.cita--no_llego .cita__hora { color: var(--aviso); font-weight: 600; }
/* ANULADA: se usaba en `todas.html` desde el primer día y no tenía NINGUNA
   regla, así que en el único listado que las incluye a propósito una cita
   anulada se veía igual que una viva. El guardián de clases no lo caza: el
   nombre lo construye un dato, y un test no puede leer lo que no está escrito
   en la plantilla. */
.cita--anulada { color: var(--tinta-suave); text-decoration: line-through; }
.cita--anulada .patente { text-decoration: line-through; }
.cita__acciones { display: inline-flex; gap: var(--e-3); margin-left: var(--e-2); }

/* LA FECHA DEL DIA QUE SE ESTA MIRANDO, al lado del titulo y en cifras
   tabulares. Decir solo «Hoy» fue lo que escondio una cita: el dia del taller
   vuelca a las 03:00Z, asi que entre las 21:00 y medianoche del reloj de quien
   trabaja en UTC-6 su «hoy» y el del taller son dias distintos. */
.cita__fecha {
  font-family: var(--letra-dato);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  color: var(--tinta-suave);
  margin-left: var(--e-2);
}
/* Los saltos de dia. En linea y discretos: se usan cuando hace falta, no son
   lo que se viene a hacer a esta pantalla. */
.dias {
  display: flex; flex-wrap: wrap; gap: var(--e-2);
  padding: 0 var(--e-3) var(--e-2);
  font-size: 0.9rem;
}

/* --- los repuestos (2026-09-08) ------------------------------------------ */

/* Las horas en cifras tabulares: es la columna por la que se recorre la lista
   --lo que lleva más tiempo parado va arriba-- y sin ancho fijo «7 h» y «31 h»
   no alinean, que es justo lo que hace que se lea de un vistazo o no.
   NO hereda de `.tabla-ot`: allí la primera celda es un folio, aquí es texto
   largo, y una tabla que hereda el ancho de otra acaba con la pieza cortada. */
.tabla-repuestos td:first-child { font-weight: 600; }
.tabla-repuestos .numero { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* El número de pieza y el proveedor, debajo y en gris: son el detalle que se
   mira cuando ya se eligió la fila, no lo que hace elegirla. */
.tabla-repuestos .folio,
.tabla-repuestos .nota { display: block; color: var(--tinta-suave); font-weight: 400; }
/* La celda del siguiente paso lleva un formulario por línea. En la tablet del
   patio caben en columna; en el mostrador, uno al lado del otro. */
.tabla-repuestos td:last-child { display: flex; flex-wrap: wrap; gap: var(--e-2); }

/* --- el lateral plegado: solo iconos (2026-09-08) ------------------------ */

/* El dueño lo pidió así: «este menú debe contraer hacia la izquierda y quedan
   visibles sólo los íconos de cada módulo». Hasta ahora, plegado, desaparecía
   entero -- lo que en escritorio deja una franja vacía y obliga a abrirlo para
   ir a cualquier sitio.

   SE APOYA EN QUE EL CONTENIDO DE UN `<details>` CERRADO SE PUEDE VOLVER A
   MOSTRAR, Y ES AHÍ DONDE ESTUVO EL FALLO. El navegador lo esconde con
   `content-visibility: hidden`, y eso el autor lo puede sobrescribir -- pero
   ese `hidden` NO vive en el hijo: vive en `details::details-content`, el
   hueco que el navegador crea alrededor del contenido, y ése es ANCESTRO del
   `<nav>` en el árbol plano.

   LA TRAMPA, y por eso queda escrita: poner `content-visibility: visible` en
   `.lateral__lista` se LEE como correcto y es INERTE. Un descendiente no puede
   des-saltar un subárbol que su ancestro salta -- ni con `!important`. El
   resto del bloque sí aplicaba, así que el carril salía con su ancho, su
   centrado y su recorte, y VACÍO: exactamente lo que reportó el dueño con una
   captura el 2026-09-08.

   DOS `@supports` Y NO UNO, porque son dos capacidades distintas y una sirve
   sin la otra:
     - el CARRIL sólo necesita `:has`. Sin él, plegar dejaba una columna vacía
       de 12rem, que es el mismo síntoma más ancho.
     - los ICONOS necesitan además poder tocar `::details-content`. Donde no se
       pueda (Chrome < 131, Safari < 18.4, Firefox < 139) queda el carril
       estrecho con sólo el tirador -- utilizable, un clic para abrir -- en vez
       de la franja ancha y muerta de antes.
   Nada de JavaScript: un menú que necesita JS para abrirse es un menú que a
   veces no se abre.

   El nombre se oculta RECORTADO y no con `display: none`, para que el enlace
   conserve su nombre accesible: plegado, un enlace que sólo es un dibujo no se
   puede leer en voz alta ni encontrar con el buscador del navegador. */
@media (min-width: 52.0625rem) {
  /* El carril. Sólo necesita `:has`. */
  @supports selector(body:has(a)) {
    .lateral:not([open]) { width: 3.5rem; }
    .lateral:not([open]) .lateral__tirador { justify-content: center; padding-inline: 0; }
    /* El contenido se acerca. `:has` sobre `body` porque el lateral es fijo y
       no participa del flujo: sin esto, plegarlo deja 12rem de hueco. */
    body:has(.lateral:not([open])) { padding-left: 3.5rem; }
  }
  /* Y los iconos, que necesitan el pseudo-elemento. */
  @supports selector(details::details-content) and selector(body:has(a)) {
    .lateral:not([open])::details-content { content-visibility: visible; }
    .lateral:not([open]) .lateral__lista { padding-inline: 0; }
    /* Centrado y cuadrado: con el nombre fuera, el icono manda el ancho. */
    .lateral:not([open]) .lateral__lista a {
      justify-content: center;
      padding-inline: 0;
    }
    .lateral:not([open]) .lateral__nombre {
      position: absolute;
      width: 1px; height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }
  }
}


/* --- el lateral nace plegado, se abre al pasar y se fija (2026-09-19) ---- */

/* El dueño: «quiero que el menú esté por defecto contraído solo mostrando los
   íconos. Al pasar el mouse que se expanda, y que en el tope de la barra tenga
   un pin para dejarlo fijo».

   PLEGADO ES EL CARRIL DE ARRIBA, sin tocarlo: `base.html` ya no pinta el
   `open` salvo que se haya fijado (`lateral_fijo`, de una cookie).

   AL PASAR EL RATÓN SE DESPLIEGA ENCIMA, SIN MOVER LA PÁGINA. El `body` sigue
   apartado sólo el ancho del carril, así que el lateral abierto por hover tapa
   el borde del contenido en vez de empujarlo. Empujarlo haría saltar la página
   entera 8,5rem cada vez que el ratón cruza el borde izquierdo camino de otra
   cosa. Por lo mismo entra con un retraso corto: cruzar no es querer abrirlo.
   Con el teclado lo abre el foco VISIBLE, para quien tabula por el menú; no
   `:focus-within`, que también cuenta el foco de un clic: tras pulsar el pin
   para plegarlo, el lateral se quedaba abierto hasta hacer clic en otra parte.

   EL PIN ES EL PROPIO TIRADOR. Pulsarlo abre el `<details>` de verdad --el
   contenido se aparta 12rem, como antes-- y `lateral.js` lo recuerda. Un
   segundo botón aparte sería otro control para lo mismo que ya hace «Todo el
   menú».

   Dentro del mismo `@supports` que los iconos: desplegar el carril necesita
   poder enseñar el contenido de un `<details>` cerrado, que es lo que ese
   bloque comprueba. Donde no se pueda queda lo de antes: un clic lo abre. */
.lateral__pin { display: none; }
@media (min-width: 52.0625rem) {
  .lateral__pin { display: inline-block; margin-left: auto; width: 15px; height: 15px; opacity: .7; }
  .lateral[open] .lateral__pin { fill: currentColor; color: var(--marca); opacity: 1; }
  @supports selector(details::details-content) and selector(body:has(a)) {
    .lateral { overflow-x: hidden; }
    /* Se anima sólo si nadie pidió que no le muevan la pantalla. */
    @media (prefers-reduced-motion: no-preference) {
      .lateral { transition: width .12s ease; }
    }
    .lateral:not([open]) .lateral__pin { display: none; }
    .lateral:not([open]):is(:hover, :has(:focus-visible)) {
      width: 12rem;
      box-shadow: 6px 0 20px rgb(0 0 0 / .14);
      transition-delay: .12s;
    }
    .lateral:not([open]):is(:hover, :has(:focus-visible)) .lateral__tirador { justify-content: flex-start; padding-inline: var(--e-4); }
    .lateral:not([open]):is(:hover, :has(:focus-visible)) .lateral__pin { display: inline-block; }
    .lateral:not([open]):is(:hover, :has(:focus-visible)) .lateral__lista { padding-inline: var(--e-2); }
    .lateral:not([open]):is(:hover, :has(:focus-visible)) .lateral__lista a { justify-content: flex-start; padding-inline: var(--e-3); }
    .lateral:not([open]):is(:hover, :has(:focus-visible)) .lateral__nombre {
      position: static;
      width: auto; height: auto;
      overflow: visible;
      clip-path: none;
      white-space: nowrap;
    }
  }
}


/* --- la ayuda: el manual dentro del sistema (2026-09-09) ----------------- */

/* TODO VA PREFIJADO `ay-`, y no es manía: tres de las clases del manual
   --`marca`, `nota`, `portada`-- chocaban ya con las de aquí, y `n`, `no`,
   `si`, `titulo` y `url` chocarían en cuanto alguien las usara. Este repo ya
   tuvo una clase definida dos veces que rompió otra pantalla en silencio.

   NO HAY TOKENS NUEVOS. Los colores, la letra y las escalas son las de arriba,
   así que el manual cambia de tema con el producto y no hay una segunda
   paleta que un día se quede atrás. */

/* EL ÍNDICE, EN ÁRBOL Y A LA IZQUIERDA. El dueño lo pidió así: «el menú en
   forma de jerarquía de carpetas en el lado izquierdo para facilitar la
   navegación de la ayuda».

   Antes era un desplegable arriba, y tenía un defecto que sólo se ve usándolo:
   al bajar por el manual desaparecía de la pantalla, así que para saltar a otro
   apartado había que volver arriba.

   VA DENTRO DE `main`, no al lado del lateral de la aplicación: el lateral es
   fijo y el cuerpo ya se aparta 12rem de él. Esta segunda columna vive en el
   hueco que quedaba a la izquierda del texto. */
/* TRES COLUMNAS EN PANTALLA GRANDE: el árbol, el manual, y la guía de dónde
   estás. La del medio se lleva el espacio; las otras dos son estrechas y van
   pegadas. */
.ay-armazon { display: block; }
@media (min-width: 64rem) {
  .ay-armazon {
    display: grid;
    grid-template-columns: 15rem minmax(0, 1fr);
    gap: var(--e-8);
    align-items: start;
  }
}
@media (min-width: 82rem) {
  .ay-armazon { grid-template-columns: 15rem minmax(0, 1fr) 11rem; }
}

/* EL ASISTENTE. Botón flotante abajo a la derecha, panel encima.

   NO IMITA UN CHAT DE SOPORTE, y es una decisión: no hay burbujas ni avatar, y
   la pregunta se pinta como una CITA con un filete a la izquierda. Vestirlo de
   conversación prometería algo que no hace -- no guarda historial, cada
   pregunta se contesta sola.

   El prefijo `ia` va en todas. Este repo ya tuvo una clase definida dos veces
   que apagó otra pantalla sin dar ningún error. */
.ia {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 50;
}
/* En papel no existe: el comprobante ya lo apaga desde la plantilla, y esto es
   el cinturón por si algún día se pinta en otra pantalla que se imprima. */
@media print {
  .ia { display: none; }
}
.ia__boton {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  /* SIN ESTO EL RÓTULO SE PARTE EN TRES LÍNEAS y el botón queda como una
     pastilla apretada. Se vio mirando la pantalla, no leyendo la hoja. */
  white-space: nowrap;
  min-height: 44px;
  padding: var(--e-2) var(--e-4);
  border: 1px solid var(--marca-oscura);
  border-radius: 999px;
  background: var(--marca);
  color: #fff;
  font: inherit;
  font-weight: 600;
  box-shadow: 0 2px 10px rgb(0 0 0 / .18);
  cursor: pointer;
}
.ia__boton:hover { background: var(--marca-oscura); }
/* EL TAMAÑO DEL ICONO LO PONE QUIEN LO USA. Los `svg` del macro `icono()`
   traen `viewBox` y NINGÚN tamaño --a propósito: así cada sitio lo escala a lo
   suyo-- y sin esta regla el navegador lo pintó a su tamaño por defecto, un
   círculo enorme que empujó el rótulo fuera de la pantalla. Se vio mirando,
   no leyendo. Es la misma medida que usa el «?» de la barra de arriba. */
.ia__boton svg { width: 1.15rem; height: 1.15rem; flex: 0 0 auto; }
.ia__panel {
  position: absolute;
  right: 0;
  bottom: calc(100% + .6rem);
  /* El `min()` es para el móvil: 26rem no caben en un teléfono y un panel que
     se sale por la derecha deja el botón de enviar fuera de la pantalla. */
  width: min(26rem, calc(100vw - 2.5rem));
  max-height: min(32rem, calc(100vh - 6rem));
  /* Este `display` pisaba el `hidden` del panel --una clase del autor gana a la
     regla del navegador-- y el panel nacía abierto y la × no lo cerraba. Lo
     sostiene la regla global `[hidden]` del principio de la hoja. */
  display: flex;
  flex-direction: column;
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  box-shadow: 0 8px 28px rgb(0 0 0 / .22);
  overflow: hidden;
}
.ia__cabecera {
  display: flex;
  /* Centrado y no arriba: sin el subtítulo, que el dueño pidió quitar, el título
     es una sola línea y arriba del todo quedaba descolgado de la × de 44 px. */
  align-items: center;
  justify-content: space-between;
  gap: var(--e-2);
  padding: var(--e-3);
  border-bottom: 1px solid var(--borde);
  background: var(--papel-alt);
}
.ia__quien { margin: 0; font-weight: 600; }
.ia__cerrar {
  border: 0;
  background: none;
  color: var(--tinta-suave);
  font-size: 1.4rem;
  line-height: 1;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
}
.ia__hilo {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--e-3);
  display: grid;
  gap: var(--e-3);
  align-content: start;
}
.ia__saludo { margin: 0; color: var(--tinta-suave); font-size: .92rem; }
.ia__form {
  display: flex;
  gap: var(--e-2);
  padding: var(--e-3);
  border-top: 1px solid var(--borde);
}
.ia__campo {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: var(--e-2) var(--e-3);
  border: 1px solid var(--borde);
  border-radius: var(--r-sm);
  background: var(--fondo);
  color: var(--tinta);
  font: inherit;
}
.ia__campo:focus-visible { outline: 2px solid var(--marca); outline-offset: 1px; }

/* LO QUE SE PINTA EN EL HILO */
.ia-respuesta { display: grid; gap: var(--e-2); }
/* La pregunta como CITA, no como burbuja. */
.ia-mia {
  margin: 0;
  padding-left: var(--e-3);
  border-left: 3px solid var(--borde-firme);
  color: var(--tinta-suave);
  font-size: .92rem;
}
.ia-esperando { margin: 0; color: var(--tinta-suave); font-style: italic; }
.ia-texto { display: grid; gap: var(--e-2); }
.ia-texto p { margin: 0; }
.ia-cita {
  font-family: var(--letra-dato);
  font-size: .82rem;
  text-decoration: none;
  padding: 0 .15rem;
}
.ia-nada, .ia-aviso {
  margin: 0;
  padding: var(--e-3);
  border-radius: var(--r-sm);
  background: var(--aviso-piso);
  font-size: .92rem;
}
.ia-fuentes__titulo {
  margin: var(--e-2) 0 0;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--tinta-suave);
}
.ia-fuentes { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-2); }
.ia-fuente {
  padding: var(--e-2) var(--e-3);
  background: var(--marca-piso);
  border-radius: var(--r-sm);
  font-size: .9rem;
}
.ia-fuente__n {
  display: inline-grid;
  place-items: center;
  width: 1.3rem;
  height: 1.3rem;
  margin-right: var(--e-2);
  border-radius: 999px;
  background: var(--marca);
  color: #fff;
  font-family: var(--letra-dato);
  font-size: .72rem;
}
.ia-fuente__camino { margin: var(--e-1) 0 0; color: var(--tinta-suave); font-size: .84rem; }

/* BUSCAR EN EL MANUAL. Va dentro de la columna de lectura, arriba del todo,
   y no en la barra lateral: quien busca ya está mirando el texto, y una caja
   en el lateral compite con el árbol de apartados por el mismo sitio.

   Las clases van prefijadas `ay-` como todo lo del manual. No es manía: este
   repo ya tuvo una clase definida dos veces que apagó otra pantalla sin dar
   ningún error, y `marca`, `nota` y `portada` ya chocaban antes de prefijar. */
.ay-buscador {
  margin: 0 0 var(--e-6);
  padding: var(--e-4);
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  max-width: 46rem;
}
.ay-buscador__rotulo {
  display: block;
  font-weight: 600;
  margin-bottom: var(--e-2);
}
/* En pantalla estrecha el botón cae debajo del campo en vez de estrujarlo:
   una caja de búsqueda de seis caracteres no sirve para escribir una frase. */
.ay-buscador__linea {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
}
.ay-buscador__campo {
  flex: 1 1 18rem;
  min-width: 0;
  padding: var(--e-2) var(--e-3);
  border: 1px solid var(--borde);
  border-radius: var(--r-sm);
  background: var(--fondo);
  color: var(--tinta);
  font: inherit;
  min-height: 44px;
}
.ay-buscador__campo:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 1px;
}

/* LOS RESULTADOS. El manual sigue debajo, entero: los resultados NO lo
   esconden. Encontrar tres apartados y perder de vista el resto convierte una
   búsqueda fallida en un callejón. */
.ay-hallazgos {
  margin: 0 0 var(--e-8);
  max-width: 46rem;
}
.ay-hallazgos__titulo {
  font-family: var(--letra-titulo);
  font-size: 1.1rem;
  margin: 0 0 var(--e-3);
}
.ay-hallazgos__lista {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--e-3);
}
.ay-hallazgo {
  padding: var(--e-3);
  background: var(--papel);
  border: 1px solid var(--borde);
  border-left: 3px solid var(--marca);
  border-radius: var(--r-sm);
}
.ay-hallazgo__ir {
  display: block;
  font-weight: 600;
  font-size: 1.02rem;
  margin-bottom: var(--e-2);
}
.ay-hallazgo__camino {
  margin: 0 0 var(--e-2);
  font-size: .92rem;
  color: var(--tinta-suave);
}
/* El extracto sale del cuerpo del apartado, no de la entradilla: tres
   entradillas seguidas se parecen entre sí y no dicen por qué salió cada una. */
.ay-hallazgo__extracto {
  margin: 0;
  font-size: .92rem;
  color: var(--tinta-suave);
}
.ay-hallazgos__nada {
  padding: var(--e-4);
  background: var(--aviso-piso);
  border-radius: var(--r-sm);
  margin: 0 0 var(--e-3);
}
.ay-hallazgos__todo { margin: var(--e-3) 0 0; font-size: .92rem; }

.ay-arbol {
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--r-lg);
  padding: var(--e-3);
  margin-bottom: var(--e-6);
}
/* EL TOPE DE ALTO ES SÓLO PARA PANTALLA PEQUEÑA, y aquí estaba el fallo: la
   regla base iba DESPUÉS de la media query, así que `max-height: 14rem` pisaba
   el `calc(100vh - 5rem)` de escritorio -- misma especificidad, gana la última.
   El dueño lo vio antes que ningún test: «el listado lateral tiene que ser más
   largo, porque hace muy difícil utilizar una pantalla tan pequeña».

   Es el mismo fallo de cascada que ya mordió dos veces en esta hoja. Ahora cada
   alto vive en su propia media query y no pueden pisarse. */
@media (max-width: 63.99rem) {
  /* En una tablet en vertical el árbol NO se come la pantalla: se queda en su
     alto y se desplaza dentro. Sin esto, abrir la ayuda en el patio enseñaría
     veintitrés enlaces y ni una línea de manual. */
  .ay-arbol { max-height: 14rem; overflow-y: auto; }
}
@media (min-width: 64rem) {
  /* Pegado y ALTO: es lo que hace que sirva de navegación en vez de de
     portada.

     PEGADO DEBAJO DE LA BARRA, y no del borde de la ventana. Con `top: 1rem` la
     barra --pegajosa también, y encima-- le tapaba 52 px de cabeza en cuanto se
     bajaba por el manual: «Tanto el menú izquierdo como el derecho siempre
     deberían estar visibles desde tope y no cortarse al hacer scroll» (dueño,
     2026-09-11, con captura).

     EL ALTO TAMBIÉN DESCUENTA LA BARRA. Con las cuatro carpetas abiertas el
     árbol mide 877 px, que en una pantalla de 900 ya no caben: lo que sobra se
     desplaza DENTRO. Abajo deja lo mismo que el relleno de `main` (`--e-6`),
     porque ahí acaba el manual, y un árbol más alto se dejaría empujar hacia
     arriba al llegar al final -- otra vez debajo de la barra. Por lo mismo va
     sin margen de abajo: en la rejilla el hueco lo pone `gap`, y lo pegajoso
     cuenta el margen como parte de lo que no puede salirse de su columna. */
  .ay-arbol {
    position: sticky;
    top: calc(var(--alto-barra) + var(--e-4));
    max-height: calc(100vh - var(--alto-barra) - var(--e-4) - var(--e-6));
    overflow-y: auto;
    margin-bottom: 0;
  }
}
/* LA GUÍA: EN QUÉ NIVEL DE LA PÁGINA ESTÁS. «Se puede crear una especie de guía
   lateral que establece en qué nivel de la página se está, para poder subir y
   bajar más rápido hasta el inicio o el fin» (dueño).

   Sólo aparece cuando hay sitio de sobra: por debajo de 82rem el manual y el
   árbol ya se reparten el ancho, y una tercera columna dejaría la lectura en un
   canal estrecho -- que es justo lo que acaba de arreglarse. Debajo de ese
   ancho no se pierde nada esencial: los dos saltos son anclas y el árbol sigue
   navegando. */
.ay-guia { display: none; }
@media (min-width: 82rem) {
  /* Debajo de la barra por lo mismo que el árbol, y con el mismo tope de alto:
     es corta, pero en una ventana baja su pie tampoco puede salirse. */
  .ay-guia {
    display: block;
    position: sticky;
    top: calc(var(--alto-barra) + var(--e-4));
    max-height: calc(100vh - var(--alto-barra) - var(--e-4) - var(--e-6));
    overflow-y: auto;
    padding: var(--e-3);
    background: var(--papel);
    border: 1px solid var(--borde);
    border-radius: var(--r-lg);
  }
}
.ay-guia__titulo {
  font-family: var(--letra-titulo);
  font-size: .72rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--tinta-suave);
  margin: 0 0 var(--e-1);
}
/* El apartado en el que se está. En dos líneas como mucho: es una etiqueta, no
   un titular, y un nombre largo no puede empujar la barra fuera de la vista. */
.ay-guia__aqui {
  font-family: var(--letra-titulo);
  font-size: .95rem;
  line-height: 1.25;
  color: var(--marca-oscura);
  margin: 0 0 var(--e-2);
}
/* LA BARRA DE AVANCE SE LLENA SOLA, sin JavaScript: la animación va atada al
   desplazamiento de la página. Donde el navegador no lo soporte, la barra se
   queda vacía y no molesta -- por eso el relleno vive dentro de un `@supports`
   y no al revés. */
.ay-guia__barra {
  height: 4px;
  border-radius: 999px;
  background: var(--papel-alt);
  overflow: hidden;
  margin-bottom: var(--e-2);
}
.ay-guia__avance {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--marca);
  transform: scaleX(0);
  transform-origin: left center;
}
@supports (animation-timeline: scroll()) {
  .ay-guia__avance {
    animation: ay-avance linear both;
    animation-timeline: scroll(root block);
  }
}
@keyframes ay-avance {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}
/* Y quien pidió que no le muevan la pantalla no ve la animación tampoco aquí. */
@media (prefers-reduced-motion: reduce) {
  .ay-guia__avance { animation: none; transform: scaleX(1); opacity: .35; }
}
.ay-guia__saltos { display: grid; gap: var(--e-1); margin: 0; font-size: .88rem; }
.ay-guia__saltos a {
  text-decoration: none;
  color: var(--tinta);
  padding: var(--e-1) var(--e-2);
  border-radius: var(--r-sm);
}
.ay-guia__saltos a:hover { background: var(--marca-piso); color: var(--marca-oscura); }
.ay-guia__saltos a:focus-visible { outline: 2px solid var(--marca); outline-offset: 1px; }

/* DÓNDE ESTÁS, TAMBIÉN EN EL ÁRBOL. Lo pone `ayuda.js`, y es la mitad que hace
   útil un índice de veintitrés entradas: sin ella dice a dónde se PUEDE ir,
   no dónde se ESTÁ. */
.ay-carpeta__hojas a[aria-current="true"] {
  background: var(--marca-piso);
  color: var(--marca-oscura);
  font-weight: 600;
}

/* El canal de lectura. `min-width: 0` para que una tabla ancha se desborde
   DENTRO de su envoltorio en vez de ensanchar la columna y empujar el árbol
   fuera de la pantalla: es el fallo clásico de una rejilla con contenido de
   ancho libre, y en este manual hay seis tablas. */
.ay-lectura { min-width: 0; }
.ay-arbol__titulo {
  font-family: var(--letra-titulo);
  font-size: .78rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--tinta-suave);
  margin: 0 0 var(--e-2);
  padding-inline: var(--e-1);
}
/* Cada grupo es una CARPETA que se puede cerrar. Nacen abiertas: un árbol que
   arranca cerrado obliga a dos clics para ver qué hay, y la primera vez que
   alguien abre la ayuda es cuando más falta hace ver el mapa entero. */
.ay-carpeta > summary {
  cursor: pointer;
  font-family: var(--letra-titulo);
  font-size: .82rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--marca-oscura);
  padding: var(--e-1);
  border-radius: var(--r-sm);
}
.ay-carpeta > summary:hover { background: var(--marca-piso); }
/* La sangría ES la jerarquía: sin ella, carpeta y hoja se leen al mismo nivel
   y el árbol deja de ser un árbol. La línea marca de qué carpeta cuelgan. */
.ay-carpeta__hojas {
  list-style: none;
  margin: var(--e-1) 0 var(--e-2);
  padding: 0 0 0 var(--e-3);
  border-left: 1px solid var(--borde);
  display: grid;
  gap: 1px;
}
.ay-carpeta__hojas a {
  display: flex;
  gap: var(--e-2);
  padding: .2rem var(--e-2);
  border-radius: var(--r-sm);
  text-decoration: none;
  color: var(--tinta);
  font-size: .88rem;
  line-height: 1.35;
}
.ay-carpeta__hojas a:hover { background: var(--marca-piso); color: var(--marca-oscura); }
.ay-carpeta__hojas a:focus-visible { outline: 2px solid var(--marca); outline-offset: 1px; }
.ay-n {
  font-family: var(--letra-dato);
  font-size: .78rem;
  color: var(--tinta-suave);
  min-width: 1.5rem;
  text-align: right;
}

/* El canal de lectura. Ancho de línea y no ancho de pantalla: una línea de
   ciento veinte caracteres se pierde al volver al margen. */
.ay-parte {
  font-family: var(--letra-titulo);
  font-size: .82rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--marca);
  border-top: 2px solid var(--marca);
  padding-top: var(--e-2);
  margin: var(--e-8) 0 var(--e-6);
  max-width: 46rem;
}
/* El árbol, los saltos de la guía y el «?» de cada pantalla llevan a
   `#apartado`, y el título queda a la vista por el `scroll-padding-top` de
   `html`. Con el `scroll-margin-top: 1rem` que llevaba aquí quedaba 52 px
   DEBAJO de la barra, y un enlace que tapa lo que abre se lee como roto. */
.ay-area { margin-bottom: var(--e-8); max-width: 46rem; }
.ay-area > h3 {
  font-family: var(--letra-titulo);
  font-size: clamp(1.4rem, 3.4vw, 1.9rem);
  line-height: 1.12;
  margin: 0 0 var(--e-2);
  text-wrap: balance;
  display: flex;
  gap: var(--e-3);
  align-items: baseline;
  flex-wrap: wrap;
}
.ay-area > h3 .ay-n {
  font-size: .85rem;
  color: var(--marca);
  border: 1px solid var(--marca);
  border-radius: 999px;
  padding: .1rem .5rem;
  min-width: 0;
  flex: none;
}
.ay-area h4 { font-family: var(--letra-titulo); font-size: 1.1rem; margin: var(--e-6) 0 var(--e-2); }
.ay-entradilla { color: var(--tinta-suave); }

/* CÓMO SE LLEGA. El dueño lo pidió con el apartado del checklist delante: «no
   veo que se mencione en ningún lugar, cómo se llega a esta opción». El manual
   daba la DIRECCIÓN de cada pantalla y no la RUTA DE CLICS, que es lo que se
   usa.

   Va con fondo propio y no como un párrafo más: es lo que se busca con el ojo
   al abrir un apartado, y un párrafo entre otros cinco no se encuentra. */
.ay-camino {
  background: var(--marca-piso);
  border-left: 3px solid var(--marca);
  border-radius: var(--r-sm);
  padding: var(--e-2) var(--e-3);
  margin: 0 0 var(--e-4);
  font-size: .95rem;
}
/* Los rótulos citados dentro NO van en cursiva aquí: en una ruta de clics lo
   que se lee son los nombres de los botones uno detrás de otro, y en cursiva
   toda la línea se convierte en un bloque gris. */
.ay-camino .ay-pantalla { font-style: normal; font-weight: 600; }

/* La dirección de una pantalla: es un dato que se teclea, así que va en
   monoespaciada como el resto de los datos del producto. */
.ay-url {
  font-family: var(--letra-dato);
  font-size: .86em;
  background: var(--papel-alt);
  border: 1px solid var(--borde);
  border-radius: var(--r-sm);
  padding: .08em .38em;
  white-space: nowrap;
}
/* Lo que sale LITERAL en la pantalla, entre comillas angulares: el lector tiene
   que poder buscarlo con los ojos en la aplicación. */
.ay-pantalla { font-style: italic; }
.ay-pantalla::before { content: "«"; }
.ay-pantalla::after { content: "»"; }

/* Quién puede. Las pastillas repiten los colores de estado del producto para
   que «del asesor» se lea igual aquí y allí. */
.ay-roles { display: flex; gap: var(--e-2); flex-wrap: wrap; margin-bottom: var(--e-4); }
.ay-rol {
  font-family: var(--letra-titulo);
  font-size: .74rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: .15rem .6rem;
  border: 1px solid;
}
.ay-rol--dueno { color: var(--marca-oscura); border-color: var(--marca); background: var(--marca-piso); }
.ay-rol--asesor { color: var(--exito); border-color: var(--exito); background: var(--exito-piso); }
.ay-rol--tecnico { color: var(--aviso); border-color: var(--aviso); background: var(--aviso-piso); }
.ay-rol--todos { color: var(--tinta-suave); border-color: var(--borde-firme); background: var(--papel-alt); }

/* Los cuatro avisos, cada uno con su papel. Un solo estilo de recuadro los
   igualaría, y «esto lo exige la ley» no es lo mismo que «esto todavía no
   existe». */
.ay-nota {
  border: 1px solid var(--borde);
  border-left: 4px solid var(--borde-firme);
  border-radius: var(--r-md);
  background: var(--papel);
  padding: var(--e-4);
  margin-bottom: var(--e-4);
}
.ay-nota > .ay-titulo {
  font-family: var(--letra-titulo);
  font-size: .76rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  display: block;
  margin-bottom: var(--e-2);
}
.ay-nota > :last-child { margin-bottom: 0; }
.ay-nota--ley { border-left-color: var(--marca); background: var(--marca-piso); }
.ay-nota--ley > .ay-titulo { color: var(--marca-oscura); }
.ay-nota--sinvuelta { border-left-color: var(--alerta); background: var(--alerta-piso); }
.ay-nota--sinvuelta > .ay-titulo { color: var(--alerta); }
.ay-nota--ojo { border-left-color: var(--aviso); background: var(--aviso-piso); }
.ay-nota--ojo > .ay-titulo { color: var(--aviso); }
.ay-nota--falta { border-left-color: var(--borde-firme); background: var(--papel-alt); }
.ay-nota--falta > .ay-titulo { color: var(--tinta-suave); }

/* Los recorridos van NUMERADOS porque son secuencias de verdad: el orden en que
   se pulsan las cosas. Numerar una lista que no es una secuencia es decorar. */
.ay-pasos { counter-reset: ay-paso; list-style: none; padding: 0; margin-bottom: var(--e-4); display: grid; gap: var(--e-3); }
.ay-pasos > li { counter-increment: ay-paso; position: relative; padding-left: 2.4rem; }
.ay-pasos > li::before {
  content: counter(ay-paso);
  position: absolute;
  left: 0;
  top: .05rem;
  font-family: var(--letra-dato);
  font-size: .8rem;
  width: 1.7rem;
  height: 1.7rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--marca);
  color: var(--papel);
  font-weight: 500;
}
.ay-llana { margin-bottom: var(--e-4); padding-left: 1.2rem; display: grid; gap: var(--e-2); }

/* Las tablas se desbordan DENTRO de su envoltorio: la del reparto de permisos
   tiene cuatro columnas y en una tablet no cabe, y una página que se mueve de
   lado entera es peor que una tabla que se desliza. */
.ay-tabla-envoltorio {
  overflow-x: auto;
  margin-bottom: var(--e-4);
  border: 1px solid var(--borde);
  border-radius: var(--r-md);
  background: var(--papel);
  max-width: 46rem;
}
.ay-tabla-envoltorio table { border-collapse: collapse; width: 100%; font-size: .92rem; }
.ay-tabla-envoltorio th,
.ay-tabla-envoltorio td { text-align: left; padding: var(--e-2) var(--e-3); border-bottom: 1px solid var(--borde); vertical-align: top; }
.ay-tabla-envoltorio thead th {
  font-family: var(--letra-titulo);
  font-size: .78rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--tinta-suave);
  background: var(--papel-alt);
}
.ay-tabla-envoltorio tbody tr:last-child td { border-bottom: none; }
.ay-si { color: var(--exito); font-weight: 600; }
.ay-no { color: var(--tinta-suave); }

.ay-fina { border: none; border-top: 1px solid var(--borde); margin: var(--e-8) 0; max-width: 46rem; }
.ay-pie { color: var(--tinta-suave); font-size: .9rem; max-width: 46rem; }

/* El «?» de la barra. Va a la IZQUIERDA de «Salir» y no al revés: cerrar la
   sesión es lo último que se quiere pulsar por error. */
.barra__ayuda {
  display: inline-grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  border: 1px solid var(--borde-firme);
  color: var(--tinta-suave);
  text-decoration: none;
}
.barra__ayuda svg { width: 1.15rem; height: 1.15rem; }
.barra__ayuda:hover { background: var(--marca-piso); color: var(--marca-oscura); border-color: var(--marca); }


/* --- el calendario de la agenda (2026-09-09) ----------------------------- */

/* «Sería valioso agregar un 3er bloque con un calendario que se pueda
   configurar por semana o por mes» (dueño). Los dos bloques de arriba dicen
   QUIÉN viene hoy y QUÉ hay en catorce días; esto dice CÓMO ESTÁ EL MES, que es
   una pregunta de forma y sólo se ve en una cuadrícula.

   REJILLA CON `minmax(0, 1fr)` Y NO `1fr` A SECAS: con `1fr`, una patente larga
   dentro de una celda ensancha su columna y desalinea las siete. Es el fallo
   clásico de una rejilla con contenido de ancho libre. */
.mes { display: grid; gap: 2px; }
.mes__fila { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.mes__cabecera {
  font-family: var(--letra-titulo);
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tinta-suave);
  text-align: center;
  padding: var(--e-1) 0;
}

/* LA CELDA ES EL BLANCO TÁCTIL. Toda ella, no el número: en la tablet del patio
   se toca con guantes. El alto va atado a `POR_CELDA` en
   `app/agenda/calendario.py` -- tres citas de 0,72 rem más el «+N» --; si se
   cambia uno, el otro. */
.mes__dia {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-height: 5.75rem;
  padding: var(--e-1);
  border: 1px solid var(--borde);
  border-radius: var(--r-sm);
  background: var(--papel);
  color: var(--tinta);
  overflow: hidden;
}
.mes__dia:hover { border-color: var(--marca); }
/* EL ENLACE DE MIRAR EL DÍA CUBRE LA CELDA ENTERA. En la tablet del patio se
   toca con guantes: el blanco es toda la casilla, no el número. Va detrás del
   contenido (`z-index: 0`) para que el «+» y las citas queden encima y se
   puedan seleccionar. */
.mes__ver { position: absolute; inset: 0; z-index: 0; }
/* EL FOCO SE VE. La hoja no tenía ni un estilo de foco antes de esto, y una
   rejilla de cuarenta y dos enlaces recorrida con el tabulador sin saber dónde
   estás no se puede usar. */
.mes__ver:focus-visible { outline: 2px solid var(--marca); outline-offset: -2px; }

/* APUNTAR EN ESTE DÍA. El dueño lo pidió como doble clic; se hizo con un botón
   porque la casilla ES un enlace y el primer clic de un doble clic ya arranca
   la navegación, así que el `dblclick` llega tarde o no llega -- un gesto que
   funciona a veces es peor que ninguno.

   SE ENSEÑA AL PASAR O AL ENFOCAR en escritorio, y SIEMPRE donde no hay ratón:
   cuarenta y dos «+» permanentes en una rejilla que existe para leer la forma
   del mes son cuarenta y dos manchas, pero en una tablet no hay «pasar por
   encima» y esconderlo sería esconder la función. */
.mes__apuntar {
  position: absolute;
  top: 1px;
  right: 1px;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: var(--r-sm);
  color: var(--marca);
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  opacity: 0;
}
/* `:focus` Y NO SÓLO `:focus-visible`: un control ENFOCADO tiene que verse
   llegue el foco como llegue. Con sólo `:focus-visible`, el «+» recibía el foco
   con opacidad 0 en cuanto el foco no venía del teclado -- un control invisible
   que responde a Enter. */
.mes__dia:hover .mes__apuntar,
.mes__apuntar:focus { opacity: 1; background: var(--marca-piso); }
.mes__apuntar:focus-visible { outline: 2px solid var(--marca); outline-offset: 1px; }
/* DONDE NO HAY RATON NO HAY «PASAR POR ENCIMA», asi que el «+» se queda
   visible -- y mas grande, porque se toca con guantes: 22 px de blanco es una
   promesa que el dedo no cumple. */
@media (hover: none) {
  .mes__apuntar { opacity: 1; width: 2rem; height: 2rem; }
}
/* PERO EN EL MOVIL SE VA. La casilla mide 48 px de ancho ahi, y dos blancos
   dentro se pelean: gana el equivocado la mitad de las veces. El camino en el
   telefono es pulsar el dia --que llena la casilla-- y usar el boton de arriba,
   que ya llega con esa fecha puesta. */
@media (max-width: 40rem) {
  .mes__apuntar { display: none; }
}
.mes__numero {
  position: relative;
  z-index: 1;
  font-family: var(--letra-dato);
  font-size: .78rem;
  font-variant-numeric: tabular-nums;
  color: var(--tinta-suave);
  pointer-events: none;
}
/* Los días de relleno --los del mes de al lado que completan la fila-- se
   apagan. Se pintan igual: una fila de siete con cuatro huecos se lee peor que
   una completa. */
.mes__dia--fuera { background: var(--fondo); }
.mes__dia--fuera .mes__numero { opacity: .5; }
/* Con trabajo dentro: el tinte es lo que hace que la FORMA del mes se lea de un
   vistazo, que es para lo que existe el bloque. */
.mes__dia--ocupado { background: var(--marca-piso); border-color: var(--borde-firme); }
/* Hoy y el día que se está mirando son dos cosas distintas y se ven distintas:
   `--hoy` es un hecho del calendario, `--mirando` dice qué pinta la lista de
   arriba. El orden de estas dos reglas ES la cascada: las dos pesan igual, y
   `--mirando` gana porque va después. */
.mes__dia--hoy .mes__numero {
  background: var(--marca);
  color: var(--papel);
  border-radius: 999px;
  padding: 0 .35rem;
  align-self: flex-start;
}
.mes__dia--mirando { border-color: var(--marca); box-shadow: inset 0 0 0 1px var(--marca); }

/* La cuenta: en escritorio sobra --las líneas la dicen-- y en el móvil es lo
   único que cabe. Se esconde arriba y se enseña abajo, no al revés. */
.mes__cuenta { display: none; position: relative; z-index: 1; pointer-events: none; }
/* Las citas van por encima del enlace pero SIN capturar el clic: así se leen
   y a la vez toda la celda sigue llevando al día. */
.mes__citas { position: relative; z-index: 1; display: grid; gap: 1px; min-width: 0; pointer-events: none; }
.mes__cita {
  font-size: .72rem;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.mes__hora {
  font-family: var(--letra-dato);
  font-variant-numeric: tabular-nums;
  color: var(--tinta-suave);
  margin-right: .2rem;
}
/* Las tres reglas de estado dentro de la celda, con el mismo criterio que la
   lista de arriba: gris lo resuelto, y la marca en `--aviso` sólo para quien NO
   llegó, que es lo que decide si hay que llamar a alguien. */
.mes__cita--llego, .mes__cita--no_llego { color: var(--tinta-suave); }
.mes__cita--no_llego .mes__hora { color: var(--aviso); font-weight: 600; }
.mes__resto { font-size: .7rem; color: var(--tinta-suave); font-weight: 600; }

/* EN EL MÓVIL LA REJILLA NO SE CONVIERTE EN LISTA. Siete columnas siguen siendo
   siete: una lista por días ya existe arriba, y lo que este bloque aporta es la
   forma. Lo que se va es el detalle -- se queda el número y la cuenta -- porque
   en 48 px de ancho una patente no cabe y recortarla no dice nada. */
@media (max-width: 40rem) {
  .mes__dia { min-height: 3.1rem; align-items: center; }
  .mes__citas { display: none; }
  .mes__cuenta {
    display: inline-grid;
    place-items: center;
    min-width: 1.15rem;
    height: 1.15rem;
    border-radius: 999px;
    background: var(--marca);
    color: var(--papel);
    font-size: .68rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }
}

/* --- La web del taller (/sitio) ------------------------------------------
 * La pantalla donde el dueño la arma. La página PÚBLICA no usa esta hoja:
 * tiene la suya (`sitio.css`), para que un cambio aquí no mueva la vitrina.
 */
.sitio-servicio {
  padding: 1rem 0 1.25rem;
  border-bottom: 1px solid var(--borde, #e4e4e7);
  display: grid;
  gap: 0.75rem;
}
.sitio-nuevo { margin-top: 1.25rem; }
.sitio-miniatura {
  display: block;
  max-width: 220px;
  max-height: 140px;
  object-fit: contain;
  margin: 0.25rem 0 0.5rem;
  border-radius: 8px;
  background: #18181b;
}
.sitio-videos { display: grid; gap: 0.5rem; }
.sitio-videos__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.sitio-videos__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--borde, #e4e4e7);
  border-radius: 8px;
}
.sitio-videos__item .acciones { margin-left: auto; }
.sitio-videos__nuevo { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem; }
.sitio-bandeja { display: grid; gap: 0.75rem; }
.sitio-bandeja__mensaje { margin: 0; }
.sitio-bandeja__mensaje--nuevo { border-left: 4px solid var(--acento, #e10600); }
.sitio-bandeja__texto { white-space: pre-line; }

/* El permiso de marketing, dentro de la recepción y la entrega. */
.consentimiento-marketing {
  margin: 1rem 0;
  padding: 0.75rem 1rem;
  border: 1px solid var(--borde, #e4e4e7);
  border-radius: 8px;
}
.consentimiento-marketing legend { font-weight: 600; padding: 0 0.25rem; }
