/* ============================================================================
   FlotaLista · site — hoja única
   ----------------------------------------------------------------------------
   Un archivo plano, sin preprocesador y sin utilidades. El orden es el de
   siempre: tokens, fuentes, base, composición, primitivas, la firma, secciones,
   formulario, movimiento. Nada de aquí depende de un paso de construcción.

   REGLA DE ESPECIFICIDAD: cada bloque se pinta con UNA clase de composición
   (`.banda`) y sus modificadores solo cambian color, nunca espaciado. El relleno
   vertical vive en `.banda` y en ningún otro sitio, para que dos reglas no se
   cancelen entre sí cuando una sección crezca.
   ========================================================================== */

/* ── 1 · TOKENS ─────────────────────────────────────────────────────────────
   Ni un hex inventado. Los CUATRO de marca los decidió el dueño (D-146) y la
   autoridad viva es la skill `.claude/skills/marca-flotalista/SKILL.md`: ante
   discrepancia manda ella y se corrige este archivo. Hasta el 2026-08-08 esta
   línea decía que los derivados salían del brand book y del árbol de tokens del
   sitio React, y los dos estaban borrados —el segundo desde el 2026-07-29—, así
   que este comentario mandaba a leer dos archivos inexistentes para justificar
   sus propios valores. Cada uno declara el contraste CALCULADO contra la
   superficie donde se usa.

   DÓNDE VIVE EL NARANJA — el inventario de site. Son CUATRO, los mismos cuatro
   que la skill declara. Este bloque ES el inventario; no hay espejo en otro
   archivo desde que se borró el árbol del sitio React:
     .rotulo             el rótulo de cada banda y de cada cabecera de página
     :focus-visible      el anillo, claro y oscuro
     .enlace-flecha svg  la punta, no el rótulo
     .plan__etiqueta     el relleno de «Recomendado» en /precios
   Eran CINCO mientras existió el filo de 3 px de la bitácora del hero. Al
   retirarse la bitácora entera, el inventario volvió solo a su tamaño
   declarado: no hubo que quitar nada para cuadrarlo.

   FUERA DEL INVENTARIO, y por escrito: el «Lista» del wordmark
   (`.marca__nombre span`, en sus dos superficies). Es MARCA, no acento —el
   brand book §2 exime al logotipo del mínimo de contraste porque la decisión
   es de marca—, así que no gasta ninguno de los cuatro. `tools/site-check.mjs`
   lo lleva anotado igual: lo que no se declara, la puerta lo caza.
   Los cinco son ORIENTACIÓN: dicen por dónde va la lectura y dónde se actúa.
   NINGUNO marca estado —de eso se encarga el semáforo verde/ámbar/rojo/gris—,
   porque naranja contra rojo mide 2.31:1 y no se distinguen de un vistazo.
   Los 01/02/03 de Producto no tienen equivalente aquí a propósito: las bandas
   no son una secuencia, así que un numeral sería decoración disfrazada de
   estructura.
   ------------------------------------------------------------------------- */
:root {
  /* Los cuatro de marca (D-146). No se negocian. */
  --naranja: #ff6b35;         /* acento · 2.84:1 blanco · relleno, nunca estado */
  --marino: #004e64;          /* primario · 9.24:1 blanco · el botón sólido     */
  --amarillo: #ffb703;        /* ámbar «por vencer» · 1.75:1 blanco: relleno    */
  --pizarra: #1e1e24;         /* texto y estructura · 16.58:1 blanco            */

  /* Superficies. Blanco es la banda base; nube la alterna; patio la tabla. */
  --blanco: #ffffff;
  --nube: #edeef0;            /* 14.29:1 con pizarra                            */
  --patio: #f5f6f8;           /* 15.34:1 con pizarra                            */
  --borde: #dddee3;           /* separador. NUNCA texto                         */

  /* Derivados sobre claro: el puro no llega a 4.5:1, el fuerte sí.
     OJO con nube: naranja-fuerte da 4.46:1 y amarillo-fuerte 4.28:1 ahí, o sea
     que NO son texto pequeño sobre nube. Por eso las bandas que llevan rótulo
     de color o estado van en blanco: ver §3 Composición. */
  --naranja-fuerte: #c2410c;  /* 5.18:1 blanco · 4.46:1 nube                    */
  --amarillo-fuerte: #8f6a00; /* 4.97:1 blanco · 4.28:1 nube                    */
  --marino-noche: #00394a;    /* 12.47:1 blanco                                 */
  --marino-claro: #00728f;    /* 5.52:1 · enlace dentro de texto corrido        */
  --tinta-suave: #5b6270;     /* 6.13:1 blanco · 5.28:1 nube · secundario       */
  --verde: #0f7346;           /* 5.90:1 blanco · 5.08:1 nube                    */
  --rojo: #b3261e;            /* 6.54:1 blanco · 5.63:1 nube                    */

  /* Sobre superficie oscura se cambia de estante ENTERO. Estos tonos superan
     4.5:1 contra pizarra, así que sirven para texto y no solo para relleno. */
  --claro: #eaf2f5;
  --claro-texto: #d6e6eb;     /* 12.93:1 sobre pizarra                          */
  --claro-suave: #9bc2cd;     /*  8.68:1 · terciario y nivel «cerrado»          */
  --verde-claro: #7fd9aa;     /*  9.80:1                                        */
  --rojo-claro: #f8b4ad;      /*  9.57:1                                        */
  /* El amarillo NO necesita variante clara: 9.50:1 sobre pizarra tal cual.
     Venía así del árbol de tokens del sitio React y aquí se respeta —medido— en
     vez de derivar una. */

  /* Escala tipográfica. Titulares fluidos; el resto en rem fijos. */
  /* 4rem y no 4.5: a 72 px «Sabes qué unidad está parada y desde cuándo.»
     caía en cuatro renglones y el tercero era la palabra «parada» sola. A 64 px
     son tres y ninguno queda huérfano. Sigue siendo lo más grande del sitio: el
     titular de página va un escalón por debajo, a 52 px. */
  --t-xl: clamp(2.5rem, 1.6rem + 3.4vw, 4rem);
  --t-l: clamp(1.875rem, 1.3rem + 2.4vw, 3rem);
  --t-h3: clamp(1.25rem, 1.1rem + 0.8vw, 1.625rem); /* titular h3. NO confundir con --t-m, que el producto usa para metadato denso */
  --t-entrada: 1.125rem;
  --t-cuerpo: 1rem;
  --t-dato: 0.8125rem;
  --t-rotulo: 0.6875rem;

  /* Espacio. `--banda-y` es el ÚNICO relleno vertical de sección. */
  --banda-y: clamp(3.5rem, 2rem + 6vw, 6.5rem);
  --contenedor: 1200px;
  --riel: 168px;
  --radio: 4px;               /* herramienta de trabajo, no app de meditación   */
}

/* ── 2 · FUENTES ────────────────────────────────────────────────────────────
   Dos woff2 VARIABLES autohospedadas (H055): nada se pide a Google Fonts en
   ejecución, que es promesa publicada en /tecnologias-de-seguimiento. Cada
   archivo cubre su rango completo por el eje `wght`, así que dos peticiones
   sustituyen a los cinco pesos que llegarían de un CDN. Los dos van precargados
   en el <head> porque los dos están sobre el pliegue.
   ------------------------------------------------------------------------- */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url("/assets/fuentes/archivo-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/assets/fuentes/ibm-plex-sans-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── 3 · BASE ─────────────────────────────────────────────────────────────── */
*,
*::before,
*::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--blanco);
  color: var(--pizarra);
  font-family: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--t-cuerpo);
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: "Archivo", Georgia, serif;
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: var(--t-xl); font-weight: 700; line-height: 1.02; letter-spacing: -0.022em; }
h2 { font-size: var(--t-l);  font-weight: 700; line-height: 1.08; letter-spacing: -0.022em; }
h3 { font-size: var(--t-h3); font-weight: 600; line-height: 1.15; letter-spacing: -0.01em;  }

p { margin: 0 0 1rem; max-width: 65ch; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 1rem; padding-left: 1.25rem; }
li { margin-bottom: 0.4rem; max-width: 65ch; }

a { color: var(--marino-claro); text-underline-offset: 0.18em; }
a:hover { color: var(--marino); }

img, svg { max-width: 100%; }

/* El anillo de foco es NARANJA —uno de los cinco del inventario— y cambia de
   tono con la superficie: sobre claro el puro no llega ni a 3:1. */
:focus-visible {
  outline: 2px solid var(--naranja-fuerte);
  outline-offset: 3px;
  border-radius: 2px;
}

.superficie-oscura :focus-visible { outline-color: var(--naranja); }

/* Salto al contenido: primer tabulador de cada página. */
/* Se oculta con `clip-path` y no con `left:-9999px`: un elemento a −9999px sigue
   ocupando esa coordenada y en algunos navegadores arrastra scroll horizontal.
   Así queda fuera de la vista sin salirse del documento. */
.saltar {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--pizarra);
  color: var(--nube);
  font-weight: 600;
  clip-path: inset(50%);
}
.saltar:focus { clip-path: none; }

/* ── 4 · COMPOSICIÓN ────────────────────────────────────────────────────────
   Bandas a sangre. `--banda-y` es el único relleno vertical: los modificadores
   solo cambian color, nunca espaciado, para que no se cancelen entre sí.

   El ritmo NO es decorativo, lo fija el contraste: `--naranja-fuerte` sobre nube
   da 4.46:1 y falla AA para texto pequeño, así que la banda que lleva rótulo de
   color va en BLANCO. La nube es la alterna, y ahí el rótulo baja a
   `--tinta-suave` (5.28:1). Pizarra aparece dos veces en toda la portada: el
   hero y el cierre. El patio al amanecer y el patio al cerrar.
   ------------------------------------------------------------------------- */
.banda {
  padding: var(--banda-y) 1.25rem;
  border-top: 1px solid var(--borde);
}

/* La ÚNICA excepción a «los modificadores no tocan el espaciado», y va
   declarada para que no se convierta en dos. La primera banda de una página
   interior es su cabecera —titular y entradilla, nada más— y con el relleno
   completo abre medio metro de blanco antes de que empiece el contenido. Recorta
   solo por abajo: el aire de arriba es el que la separa del cabezal. */
.banda--cabecera { padding-bottom: clamp(1.5rem, 1rem + 2vw, 2.5rem); }

/* Toda banda o escena con ancla descuenta el cabezal pegajoso. Sin esto, saltar
   a `#costos` deja el titular DEBAJO de los 65 px de cabezal y quien pulsó cree
   que el enlace lo mandó al sitio equivocado. Por debajo de 1120 px el cabezal
   deja de ser pegajoso y el margen sobra, pero no estorba. */
.banda[id],
.escena[id] { scroll-margin-top: 5rem; }

.banda--nube { background: var(--nube); }

/* La banda de cierre va en MARINO —el primario institucional de la marca—, no
   en pizarra. Cierra con el color del producto en vez de con un campo negro, y
   el blanco encima mide 9.24:1.

   NO HAY `.banda--pizarra`, y su ausencia es deliberada. Existió mientras el
   hero y el cierre iban sobre campo casi negro; al pasar el sitio a claro dejó
   de usarse, y dejarla puesta era dejar cargada la escopeta: una clase que
   pinta media pantalla de #1E1E24 a un `class=` de distancia. `--pizarra` sigue
   siendo el token del TEXTO y de la estructura; como fondo de banda, no. */
.banda--marino { background: var(--marino); border-top-color: var(--marino-noche); }

/* TODO lo que cambia sobre campo oscuro cuelga de `.superficie-oscura`, y esa
   separación costó un titular invisible. `--marino` es un FONDO;
   `superficie-oscura` es el CONTRATO de color que ese fondo impone —lo llevan
   también el pie y el cierre, que no son la misma pieza—. Cuando los colores
   colgaban del modificador de fondo, el h1 del hero salía en pizarra sobre
   pizarra: contraste 1:1, texto que no estaba. */
.superficie-oscura { color: var(--claro-texto); }

.superficie-oscura h1,
.superficie-oscura h2,
.superficie-oscura h3 { color: var(--nube); }

.contenedor {
  max-width: var(--contenedor);
  margin: 0 auto;
}

/* La rejilla de dos columnas: riel + contenido. */
.rejilla {
  display: grid;
  grid-template-columns: var(--riel) minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
}

/* `.riel` sobrevive en UN sitio: el índice de apartados de las páginas legales.
   Ahí no es decoración —es navegación de un documento largo—, a diferencia de
   la columna de 168 px que encabezaba cada banda y que se retiró. */
.riel { position: sticky; top: 5rem; }

/* Había un `.riel__rotulo` idéntico a `.rotulo`, con las mismas tres reglas
   duplicadas. Dos nombres para una cosa significa dos entradas en el inventario
   del naranja y dos sitios donde corregir un contraste. El índice legal usa
   `.rotulo` como todo lo demás. */
.rotulo {
  margin: 0;
  color: var(--naranja-fuerte);
  font-size: var(--t-rotulo);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  line-height: 1.2;
}

/* Sobre nube el naranja-fuerte se queda en 4.46:1: el rótulo baja a tinta. */
.banda--nube .rotulo { color: var(--tinta-suave); }
.superficie-oscura .rotulo { color: var(--naranja); }

.riel__dato {
  margin: 0.5rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--borde);
  color: var(--tinta-suave);
  font-size: var(--t-dato);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.superficie-oscura .riel__dato { color: var(--claro-suave); border-top-color: var(--marino); }

.contenido > h1,
.contenido > h2 { margin-bottom: 1rem; }
.contenido > p  { color: var(--tinta-suave); max-width: 55ch; }
.superficie-oscura .contenido > p { color: var(--claro-texto); }

.entrada { font-size: var(--t-entrada); line-height: 1.6; max-width: 55ch; }

/* Bajo 900 px el riel se acuesta como tira horizontal sobre el contenido. */
@media (max-width: 900px) {
  /* `minmax(0, 1fr)` y no `1fr`: un `1fr` a secas vale `minmax(auto, 1fr)`, y
     ese `auto` impide que la columna encoja por debajo del ancho mínimo de su
     contenido. Con eso, el `overflow-x: auto` de la tabla comparativa y del
     bloque de código de /api no llegaba a actuar nunca: en vez de desplazarse
     dentro de su caja, empujaban la página entera y a 360 px el cuerpo se
     desplazaba en horizontal. Es el desborde más común de CSS grid y no se ve
     hasta que se mide. */
  .rejilla { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }
  .riel {
    position: static;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.75rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--borde);
  }
  .riel__dato { margin: 0; padding: 0; border: 0; }
}

/* ── 5 · PRIMITIVAS ─────────────────────────────────────────────────────────
   El botón primario CAMBIA DE ESTANTE con la superficie. El brand book §3 fija
   «marino con texto blanco», y esa regla está escrita para superficie clara:
   marino mide 1.80:1 sobre pizarra, y un componente necesita 3:1 contra lo que
   lo rodea. Sobre oscuro se aplica el mismo cambio de estante que el brand book
   ya manda para el texto —relleno nube, etiqueta pizarra, 14.29:1 en ambos
   sentidos—. Hay además una razón de composición: el marino es la SUPERFICIE
   elevada del campo oscuro, así que un botón marino encima sería la misma tinta
   haciendo dos trabajos.
   ------------------------------------------------------------------------- */
.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 48px;
  padding: 0.75rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--radio);
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.boton--primario { background: var(--marino); border-color: var(--marino); color: var(--blanco); }
.boton--primario:hover { background: var(--marino-noche); border-color: var(--marino-noche); color: var(--blanco); }

.boton--secundario { background: transparent; border-color: var(--marino); color: var(--marino); }
.boton--secundario:hover { background: var(--marino); color: var(--blanco); }

/* Sobre campo oscuro: relleno claro con etiqueta oscura. 14.29:1 en ambos
   sentidos, contra los 1.80:1 que daria un boton marino sobre pizarra. */
.superficie-oscura .boton--primario {
  background: var(--nube);
  border-color: var(--nube);
  color: var(--pizarra);
}
.superficie-oscura .boton--primario:hover { background: var(--claro); border-color: var(--claro); color: var(--pizarra); }

.superficie-oscura .boton--secundario { border-color: var(--nube); color: var(--nube); }
.superficie-oscura .boton--secundario:hover { background: var(--nube); color: var(--pizarra); }

.acciones { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 1.75rem 0 0.75rem; }

/* La punta de la flecha es naranja; el rótulo NO. Uno de los cinco. */
.enlace-flecha {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--marino);
}
.enlace-flecha svg { color: var(--naranja-fuerte); flex: none; transition: transform 0.15s ease; }
.enlace-flecha:hover svg { transform: translateX(3px); }
.superficie-oscura .enlace-flecha { color: var(--nube); }
.superficie-oscura .enlace-flecha svg { color: var(--naranja); }

/* La placa: la identidad de la unidad, en Archivo. Es el componente más
   reconocible del producto (brand book §7) y no se imita con un chip genérico.
   No es un dato medido, así que no lleva `tabular-nums`: lleva Archivo. */
.placa {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55rem;
  font-family: "Archivo", Georgia, serif;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.placa__matricula { font-size: 0.9375rem; }
.placa__eco { font-size: var(--t-dato); color: var(--tinta-suave); }
.superficie-oscura .placa__eco { color: var(--claro-suave); }

/* Todo número MEDIDO —km, importe, folio, hora, conteo— va aquí: IBM Plex Sans
   con cifras tabulares. Sin `tabular-nums` las cifras bailan de renglón a
   renglón y la tabla deja de leerse de un vistazo. */
.dato {
  font-variant-numeric: tabular-nums;
  font-size: var(--t-dato);
  letter-spacing: 0.02em;
}

/* AQUÍ ESTABA EL SEMÁFORO DEL SITIO —`.nivel--*` y `.texto-*`—, y se fue con la
   bitácora que era su única clienta. No se pierde nada: el semáforo verdadero
   vive en la capa de producto (`.rail`, `.estado`, `.punto-estado`,
   `.disponibilidad`), que es la del sistema real y la que se enseña en las
   pantallas. Tener dos semáforos con la misma regla y distinto nombre era la
   forma más segura de que se desincronizaran.

   La regla de contraste que documentaban SIGUE EN PIE y por eso se conserva
   escrita: sobre `--nube`, `--amarillo-fuerte` mide 4.28:1 y deja de ser AA
   para texto pequeño —igual que `--naranja-fuerte`, 4.46:1—. Como filete de
   3 px cumple (piso gráfico 3:1); como TEXTO no. Un estado escrito en color
   quiere banda blanca; sobre nube se escribe en `--pizarra` y el color lo pone
   el filete. Es la misma ley que gobierna el rótulo de sección. */

/* Tabla densa: donde hay datos, el aire estorba. */
.tabla { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.tabla th,
.tabla td { padding: 0.7rem 0.9rem; text-align: left; border-bottom: 1px solid var(--borde); vertical-align: top; }
.tabla thead th {
  background: var(--patio);
  color: var(--tinta-suave);
  font-size: var(--t-rotulo);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.tabla td.es-dato { font-variant-numeric: tabular-nums; white-space: nowrap; }

.tabla-desliza { overflow-x: auto; }

/* ── 6 · LA ESCENA ──────────────────────────────────────────────────────────
   La unidad de composición de la portada. Una PANTALLA de producto a un lado y
   dos frases al otro. Nada más.

   Sustituye a la banda con riel de la primera versión, que era: 170 px de
   columna vacía a la izquierda con una etiqueta gris, titular, párrafo y bloque
   de texto. Nueve veces la misma figura. Aquí el ritmo lo da el contenido —un
   panel, una hoja de inspección, una tabla de dinero y un teléfono se ven
   distintos porque SON distintos— y la alternancia izquierda/derecha, que se
   pinta con `escena--invertida` y no con dos rejillas distintas.
   ------------------------------------------------------------------------- */
.escena {
  padding: var(--banda-y) 1.25rem;
  border-top: 1px solid var(--borde);
}
.escena--nube { background: var(--nube); }

.escena__rejilla {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: center;
  max-width: var(--contenedor);
  margin: 0 auto;
}

/* La pantalla pasa a la izquierda. `order` y no una rejilla nueva: el orden del
   marcado se queda como se lee —primero el argumento, luego la prueba—, que es
   también el orden en que lo recorre un lector de pantalla.

   Y LAS COLUMNAS SE INTERCAMBIAN CON ELLA. Sin esto, `order` movía la pantalla
   a la izquierda pero la dejaba en la columna estrecha: la misma pantalla salía
   un 26 % más chica en las escenas invertidas que en las normales, y en una
   página con dos de cada una eso se lee como que unas importan menos. La
   pantalla es el contenido: siempre le toca la columna ancha. */
.escena--invertida .escena__rejilla  { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
.escena--invertida .escena__texto    { order: 2; }
.escena--invertida .escena__pantalla { order: 1; }

.escena__texto h2 { margin-bottom: 1rem; }
.escena__texto p  { color: var(--tinta-suave); max-width: 46ch; }

/* El teléfono no necesita tanto ancho: se centra en su columna en vez de
   estirarse, que es lo que delataría que es un marco decorativo. */
.escena__pantalla--telefono { display: flex; justify-content: center; }

.sello {
  max-width: var(--contenedor);
  margin: 1.25rem auto 0;
  color: var(--tinta-suave);
  font-size: var(--t-dato);
}

.centrado { text-align: center; }
.acciones--centro { justify-content: center; }

@media (max-width: 900px) {
  /* Las dos, y la de `--invertida` explícita: tiene más especificidad que la
     base (0,2,0 contra 0,1,0) y ganaría también aquí dentro, dejando las
     escenas invertidas en dos columnas en un teléfono. */
  .escena__rejilla,
  .escena--invertida .escena__rejilla { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  /* En una sola columna la alternancia no significa nada y el argumento tiene
     que ir SIEMPRE antes que la prueba. Se deshace el intercambio. */
  .escena--invertida .escena__texto    { order: 1; }
  .escena--invertida .escena__pantalla { order: 2; }
}

/* ── 6b · EL HERO ───────────────────────────────────────────────────────────
   AQUÍ VIVÍA LA BITÁCORA, y se fue entera: marcado, CSS y JavaScript.

   Era el elemento firma del plan original —una tabla de unidades dibujada a
   mano, con el hilo de la ECO-07 avanzando doce segundos y deteniéndose—. Al
   rehacer el sitio sobre pantallas reales del producto quedó como la única
   pieza inventada de la página, compitiendo con ocho capturas verdaderas que
   cuentan lo mismo y además existen. Dejarla «por si vuelve» era servirle a
   cada visitante 2.2 KB de JavaScript que no encuentra su marcado y 110 líneas
   de CSS sin selector que las use. El repositorio guarda la historia; el sitio
   no tiene por qué cargarla.

   EL HERO VA EN CLARO, y esto es una corrección de fondo.
   La primera versión lo pintaba sobre `--pizarra`: campo casi negro, titular
   claro, pantalla flotando encima. Venía heredado de la paleta inventada de la
   skill y sobrevivió a la corrección de color sin que nadie lo revisara. Está
   mal para este comprador: al dueño de una flotilla un sitio negro no le dice
   «serio», le dice «esto no es para mí».

   Superficie `--patio` (#F5F6F8): casi blanca, pero lo justo para que el marco
   blanco de la ventana se despegue. Sobre patio el rótulo naranja-fuerte mide
   4.79:1 y sí es AA para texto pequeño; sobre `--nube` daría 4.46:1 y no
   llegaría. Por eso patio y no nube.

   Y SE CONTIENE, no sangra. La sangría al canto venía de cuando el hero era una
   bitácora dibujada —ahí decía «esta superficie sigue»—. Con un marco de
   navegador no significa nada: una ventana tiene bordes por definición, y
   sacarla de la pantalla solo recorta el marco. */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: center;
  max-width: 1320px;
  margin: 0 auto;
  background: transparent;
  padding: clamp(2.5rem, 1.5rem + 3vw, 4.5rem) 1.25rem;
}

/* La banda que sí pinta el fondo. Separarla de la rejilla es lo que permite
   centrar el contenido sin que el color se corte con él. */
.hero-banda {
  background: var(--patio);
  border-bottom: 1px solid var(--borde);
}

/* La FAQ y «Lo que todavía no hacemos», lado a lado. La lista de pendientes no
   es una nota al pie: es la única prueba de confianza que este sitio puede dar
   —no hay clientes que enseñar—, así que va a la misma altura que las preguntas
   y no debajo de las veinticuatro. */
.faq__rejilla {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: clamp(2rem, 1rem + 3vw, 3.5rem);
  align-items: start;
}

.hero__texto .rotulo { margin-bottom: 1.25rem; }
.hero__texto h1 { margin-bottom: 1.5rem; }
.hero__condiciones { margin-top: 0.5rem; color: var(--tinta-suave); }

@media (max-width: 900px) {
  .hero { grid-template-columns: minmax(0, 1fr); }
  .hero__pantalla .ventana, .escena__pantalla .ventana { max-width: none; }
  .escena--invertida .escena__pantalla { justify-content: flex-start; }
  .faq__rejilla { grid-template-columns: minmax(0, 1fr); }
}

/* ── 6c · LAS DOS FOTOGRAFÍAS ───────────────────────────────────────────────
   El sitio decidió venderse con pantallas reales, y eso lo dejó sin una sola
   imagen del mundo que esas pantallas ordenan: todo era letra y marcos. Estas
   dos fotografías son la corrección (2026-08-17), y su inventario es CERRADO
   como el del naranja: el patio (a sangre, tras el hero, donde vivía la escena
   de la ficha) y el taller (en columna y con marco, antes de los precios). Una
   tercera se discute y se pesa antes de subirse. Las dos son de archivo
   (Pexels) y el sitio lo dice junto a cada una y en el pie legal: la regla de
   honestidad prohíbe insinuar clientes que no hay. Van perezosas y con srcset
   —una pantalla de densidad ≤2 baja 47/67 KB; las más densas bajan el grande,
   y el presupuesto del README cuenta ESE peor caso con sus cifras medidas—.

   EL VELO ESTÁ CALCULADO, no estimado. El relleno superior de
   `.banda-foto__texto` mide exactamente lo que la rampa del degradado (4rem),
   así que la primera línea de texto ya pisa pizarra al 88 %. El peor fotograma
   posible debajo —cielo blanco puro— compone rgb(57 57 62) ≈ #39393E
   (0.12·255 + 0.88·cada canal de #1E1E24; el azul es 36, no 30). Sobre ese
   compuesto, los pares que el contrato `superficie-oscura` pinta DE VERDAD:
   el h2 va en `--nube` y mide 9.9:1, `--claro-texto` 9.0:1 y `--claro-suave`
   (el sello) 6.0:1. La primera versión de este párrafo midió un titular
   BLANCO que ningún selector pinta (11.6:1) y la revisión adversarial lo
   cazó: la regla de la skill es calcular cada par TAL COMO SE USA, y un
   cálculo de un par inexistente es un contraste copiado con más pasos.
   ------------------------------------------------------------------------- */
.banda-foto {
  position: relative;
  border-top: 1px solid var(--borde);
}

/* La altura la fija la banda, no la foto: es una franja de contexto, no una
   galería. El recorte lo hace `object-fit` sobre el centro. */
.banda-foto img {
  display: block;
  width: 100%;
  height: clamp(300px, 44vw, 440px);
  object-fit: cover;
}

.banda-foto__texto {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  padding: 4rem 1.25rem 1.25rem;
  background: linear-gradient(180deg, rgb(30 30 36 / 0), rgb(30 30 36 / 0.88) 4rem);
}

.banda-foto__contenido {
  max-width: var(--contenedor);
  margin: 0 auto;
}

.banda-foto__contenido h2 { margin-bottom: 0.5rem; }
.banda-foto__contenido .entrada { max-width: 55ch; }

/* El sello hereda su regla general (§12·7); aquí solo pierde el margen
   centrador para alinearse con el titular. */
.banda-foto__contenido .sello { margin: 0.75rem 0 0; }

/* La foto del taller: en columna y con el MISMO marco que una pantalla de
   producto (radio de marco, sombra 2), porque ocupa el lugar compositivo de
   una —la columna ancha de la escena—. Repetir la figura a sangre del patio
   sería la sección repetitiva que este sitio se prohibió. La superficie
   `--patio` es la tercera clara del sitio (la del hero): sin superficie
   propia, insertarse entre tipos (blanco) y precios (nube) rompía la
   alternancia. */
.escena--foto { background: var(--patio); }

.escena__foto {
  display: grid;
  gap: 0.6rem;
  margin: 0;
  justify-items: start;
}

.escena__foto img {
  display: block;
  width: 100%;
  max-width: 620px;
  height: auto;
  border: var(--borde-fino);
  border-radius: var(--r-marco);
  box-shadow: var(--sombra-2);
}

.escena__foto .sello { margin: 0; }

@media (max-width: 900px) {
  .escena__foto img { max-width: none; }
}

/* ── 7 · SECCIONES ──────────────────────────────────────────────────────── */

/* AQUÍ ESTABA `.expediente`: la ficha de la ECO-07 REDIBUJADA a mano, con sus
   ocho renglones y sus notas. La sustituyó `pantalla_ficha()` —la ficha de
   verdad dentro de su marco de ventana—, y esa a su vez se fue el 2026-08-17
   con la escena entera, cuando su hueco lo tomó la fotografía del patio
   (§6c). `.renglones` sigue viva porque la usa la pantalla de costos; sus
   pestañas (`.app__pestanas`) se fueron con ella, ver §13. */

/* Los nueve tipos: rejilla densa, con su medida bajo el rótulo. */
/* NUEVE tipos entran exactos en 3×3. Con `auto-fit` la rejilla se estiraba a
   ocho columnas y dejaba siete celdas huecas: un agujero gris abajo a la
   derecha que se leía como un fallo de carga. El ancho se acota para que el
   reparto caiga en tres y no en «las que quepan». */
.tipos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  max-width: 760px;
  margin: 1.75rem auto 0;
  background: var(--borde);
  border: 1px solid var(--borde);
}
@media (max-width: 560px) { .tipos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.tipos > div { padding: 1rem; background: var(--blanco); }
.banda--nube .tipos > div { background: var(--nube); }
.tipos__tipo { display: block; font-weight: 600; }
.tipos__medida { display: block; margin-top: 0.15rem; color: var(--tinta-suave); font-size: var(--t-dato); }

/* La escala de aviso 60·30·15·7·3·1 tenía aquí su banda propia, con seis
   recuadros de 20 px. Sobrevive donde sí trabaja: en el filo del pie
   (`.pie__escala`), como remate, y dicha en prosa en la escena de
   mantenimiento. Una banda entera para seis números era darle a un dato el
   tamaño de un argumento. */

/* Bloque de código de /api. Mono DEL SISTEMA: no es una tercera familia de
   marca, es la voz de la máquina (brand book §4). Desborda con scroll propio
   para que el cuerpo de la página nunca se desplace en horizontal. */
/* EN CLARO, y es corrección. Iban sobre `--pizarra` con texto claro, que es la
   convención de todo editor de código —y en esta página son dos rectángulos
   casi negros de 400 px de alto en mitad de un sitio que decidió no tenerlos—.
   Quien lee /api no es un desarrollador buscando su tema oscuro: es el dueño
   viendo si su proveedor podrá conectar algo. Sobre blanco con filete, el
   bloque sigue siendo obviamente código —lo dice el mono y lo dice su marco— y
   deja de gritar. Es además lo que hace el producto: el ejemplo copiable de la
   pantalla de llaves va sobre superficie clara. Pizarra sobre blanco: 16.58:1. */
.codigo {
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  overflow-x: auto;
  background: var(--blanco);
  color: var(--pizarra);
  border: 1px solid var(--borde);
  border-left: 3px solid var(--marino);
  border-radius: var(--radio);
  font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
  font-size: 0.8125rem;
  line-height: 1.6;
  tab-size: 2;
}
.codigo code { white-space: pre; }

/* Preguntas: acordeón nativo, funciona sin JavaScript. */
.preguntas { border-top: 1px solid var(--borde); }
.pregunta { border-bottom: 1px solid var(--borde); }
.pregunta summary {
  padding: 1rem 2rem 1rem 0;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  position: relative;
}
.pregunta summary::-webkit-details-marker { display: none; }
.pregunta summary::after {
  content: "+";
  position: absolute;
  right: 0.25rem;
  top: 0.9rem;
  color: var(--tinta-suave);
  font-size: 1.25rem;
  line-height: 1;
}
.pregunta[open] summary::after { content: "−"; }
.pregunta__respuesta { padding: 0 2rem 1.25rem 0; color: var(--tinta-suave); }

/* «Lo que todavía no hacemos»: sin clientes ni testimonios, la única prueba de
   confianza disponible es la que cuesta algo. */
.sin-hacer { padding: 1.5rem; background: var(--patio); border: 1px solid var(--borde); border-radius: var(--radio); }
.banda--nube .sin-hacer { background: var(--blanco); }
.sin-hacer ul { list-style: none; padding: 0; margin: 1rem 0; }
.sin-hacer li { padding-left: 1.1rem; position: relative; color: var(--tinta-suave); font-size: 0.9375rem; }
.sin-hacer li::before { content: "—"; position: absolute; left: 0; color: var(--tinta-suave); }
.sin-hacer__nota { color: var(--tinta-suave); font-size: var(--t-dato); }

/* ── 7b · PÁGINAS LEGALES ───────────────────────────────────────────────────
   Un documento legal se lee de dos formas: de corrido, o buscando un apartado
   concreto porque alguien pidió «el punto de cancelación». De ahí el índice en
   el riel y el ancla por apartado. `scroll-margin-top` evita que el cabezal
   pegajoso tape el título al saltar a un ancla.
   ------------------------------------------------------------------------- */
.legal__fecha { margin-bottom: 2rem; color: var(--tinta-suave); font-size: 0.9375rem; }

.indice-legal { margin-top: 1.25rem; }
.indice-legal ul { list-style: none; padding: 0; margin: 0; }
.indice-legal li { margin-bottom: 0.5rem; }
.indice-legal a { color: var(--tinta-suave); font-size: 0.8125rem; line-height: 1.35; text-decoration: none; display: block; }
.indice-legal a:hover { color: var(--marino); text-decoration: underline; }

.texto-legal .apartado { margin-top: 2.5rem; scroll-margin-top: 5rem; }
.texto-legal .apartado h2 { font-size: var(--t-h3); margin-bottom: 0.75rem; }
.texto-legal p, .texto-legal li { color: var(--tinta-suave); }
.texto-legal strong { color: var(--pizarra); }

@media (max-width: 900px) {
  /* En el riel acostado el índice sobra: el documento entero cabe debajo y una
     lista de doce enlaces en horizontal es peor que desplazarse. Aplica igual
     en /preguntas-frecuentes, que comparte el patrón. */
  .indice-legal { display: none; }
}

/* ── 7c · /preguntas-frecuentes ─────────────────────────────────────────────
   La FAQ completa se lee como un documento legal —de corrido o buscando un
   punto concreto— y por eso REUTILIZA el patrón de 7b entero: `.rejilla`,
   `.riel` y `.indice-legal` (que pese al nombre es «el índice de apartados de
   un documento»; un `.indice-faq` idéntico sería el mismo duplicado que ya se
   retiró una vez con `.riel__rotulo`). Aquí solo vive lo que 7b no da: el
   ritmo entre temas y el ancla que descuenta el cabezal pegajoso. */
.faq-tema { scroll-margin-top: 5rem; }
.faq-tema + .faq-tema { margin-top: 2.75rem; }
.faq-tema h2 { font-size: var(--t-h3); margin-bottom: 0.5rem; }

/* ── 8 · PLANES ─────────────────────────────────────────────────────────── */
.planes { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; }

.plan {
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  background: var(--blanco);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
}
.banda--nube .plan { background: var(--blanco); }
.plan--destacado { border-color: var(--marino); }

.plan__nombre { margin: 0 0 0.15rem; }
.plan__rango { margin: 0 0 1rem; color: var(--tinta-suave); font-size: var(--t-dato); font-variant-numeric: tabular-nums; }

/* El precio es TITULAR, no dato medido: va en Archivo. */
.plan__precio { font-family: "Archivo", Georgia, serif; font-weight: 700; font-size: 2.25rem; line-height: 1; letter-spacing: -0.022em; }
.plan__periodo { margin: 0.35rem 0 1rem; color: var(--tinta-suave); font-size: var(--t-dato); }

/* «Recomendado»: relleno naranja con pizarra encima, 5.85:1. Uno de los cuatro
   del inventario. Es ORIENTACIÓN —a qué plan apuntamos—, no un estado del plan. */
.plan__etiqueta {
  align-self: flex-start;
  margin-bottom: 0.75rem;
  padding: 0.2rem 0.6rem;
  background: var(--naranja);
  color: var(--pizarra);
  border-radius: var(--radio);
  font-size: var(--t-rotulo);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.plan__incluye { list-style: none; padding: 0; margin: 0 0 1.25rem; }
.plan__incluye li { padding-left: 1.25rem; position: relative; font-size: 0.9375rem; }
.plan__incluye li::before { content: "✓"; position: absolute; left: 0; color: var(--verde); font-weight: 700; }

/* «En camino»: anunciado y NO construido. Guion, nunca palomita, y nunca verde
   —el verde es de lo que ya existe—. Sin fecha y sin «próximamente». */
.plan__en-camino { margin: 0 0 1.25rem; padding-top: 0.75rem; border-top: 1px dashed var(--borde); }
.plan__en-camino ul { list-style: none; padding: 0; margin: 0.4rem 0 0; }
.plan__en-camino li { padding-left: 1.25rem; position: relative; color: var(--tinta-suave); font-size: 0.9375rem; }
.plan__en-camino li::before { content: "–"; position: absolute; left: 0; color: var(--tinta-suave); }
.plan__marca-camino { color: var(--tinta-suave); font-size: var(--t-rotulo); font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; }

.plan .boton { margin-top: auto; }

.celda__camino { color: var(--tinta-suave); font-size: var(--t-rotulo); font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; white-space: nowrap; }
.celda__si { color: var(--verde); font-weight: 700; }
.celda__no { color: var(--borde); }

/* ── 9 · FORMULARIO ─────────────────────────────────────────────────────── */
.campo { margin-bottom: 1.25rem; }
.campo label { display: block; margin-bottom: 0.35rem; font-weight: 600; font-size: 0.9375rem; }
.campo__opcional { color: var(--tinta-suave); font-weight: 400; }

.campo input,
.campo select,
.campo textarea {
  width: 100%;
  min-height: 48px;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--tinta-suave);
  border-radius: var(--radio);
  background: var(--blanco);
  color: var(--pizarra);
  font: inherit;
}
.campo textarea { min-height: 96px; resize: vertical; }
.campo input:focus,
.campo select:focus,
.campo textarea:focus { border-color: var(--marino); }

.campo--error input,
.campo--error select,
.campo--error textarea { border-color: var(--rojo); border-width: 2px; }
.campo__error { margin: 0.35rem 0 0; color: var(--rojo); font-size: 0.875rem; font-weight: 500; }

.campo--casilla { display: flex; gap: 0.6rem; align-items: flex-start; }
.campo--casilla input { width: auto; min-height: 0; margin-top: 0.35rem; }
.campo--casilla label { font-weight: 400; }

.parejas { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 1rem; }

/* El señuelo: invisible para quien ve, alcanzable para un robot. No usa
   `display:none` porque muchos robots lo detectan y saltan el campo, y no usa
   `left:-9999px` por la misma razón que `.saltar`: eso deja tres elementos
   colgando a diez mil píxeles a la izquierda del documento y puede arrastrar
   scroll horizontal. `clip-path` lo saca de la vista sin sacarlo del flujo, y
   un robot que lee el HTML lo sigue encontrando, que es de lo que se trata. */
.senuelo { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

.aviso { padding: 1rem 1.25rem; border-radius: var(--radio); border-left: 3px solid; margin-bottom: 1.5rem; }
.aviso--error { background: #fbe9e7; border-left-color: var(--rojo); color: var(--pizarra); }
.aviso--exito { background: #e3f2ea; border-left-color: var(--verde); color: var(--pizarra); }

/* ── 10 · CABEZAL Y PIE ─────────────────────────────────────────────────── */
/* Cabezal claro por la misma razón que el hero: es lo primero que se ve y
   marca el tono de todo lo demás. Filete de 1 px y nada más. */
.cabezal {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--blanco);
  border-bottom: 1px solid var(--borde);
}
.cabezal__fila {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 64px;
  max-width: var(--contenedor);
  margin: 0 auto;
  padding: 0.5rem 1.25rem;
}

.marca { display: inline-flex; align-items: center; gap: 0.5rem; text-decoration: none; }
.marca__nombre { font-family: "Archivo", Georgia, serif; font-weight: 700; font-size: 1.125rem; letter-spacing: -0.022em; color: var(--pizarra); }
.marca__nombre span { color: var(--naranja-fuerte); }

/* EL LOGOTIPO CAMBIA DE ESTANTE COMO TODO LO DEMÁS, y esto faltaba: en el pie
   —fondo marino— el «FlotaLista» seguía en `--pizarra`, que sobre marino mide
   1.80:1. Ilegible. `marca('claro')` solo repintaba el SVG; el texto de al lado
   se quedó atrás, que es exactamente el fallo que separar el FONDO del CONTRATO
   de color evita en el resto del sitio.
   Sobre marino: nube 7.96:1. El naranja de «Lista» mide 3.26:1 y se queda —el
   brand book §2 exime al logotipo del mínimo (WCAG 1.4.11) y es la pareja de
   color de la marca—; lo que no puede pasar es que la palabra entera se pierda. */
.superficie-oscura .marca__nombre { color: var(--nube); }
.superficie-oscura .marca__nombre span { color: var(--naranja); }

/* EL MENÚ VA EN DOS GRUPOS, separados por un filete. A la izquierda lo que te
   mueve DENTRO de esta página; a la derecha lo que te SACA de ella. Es la única
   información que un menú puede dar ANTES de que lo pulses —si vas a perder el
   sitio donde ibas— y cuesta un borde de 1 px.

   El separador es `border-left` del segundo grupo y no un `<li>` con una barra:
   una barra vertical escrita es un carácter que los lectores de pantalla leen
   en voz alta («barra vertical») entre dos enlaces. El borde no existe para
   ellos, y para ellos el grupo ya está dicho con `aria-label`. */
.menu { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem; margin-left: auto; }
.menu__grupo { display: flex; flex-wrap: wrap; gap: 1.25rem; margin: 0; padding: 0; list-style: none; }
.menu__grupo--paginas { padding-left: 1.25rem; border-left: 1px solid var(--borde); }
.menu li { margin: 0; }
.menu a { color: var(--tinta-suave); text-decoration: none; font-size: 0.9375rem; white-space: nowrap; }
.menu a:hover { color: var(--marino); }
.menu a[aria-current="page"] { color: var(--pizarra); font-weight: 600; }

/* «Iniciar sesión» es un enlace, no un botón con filete: dos botones seguidos
   compiten, y de los dos el que importa es el de probar. Va en marino para que
   se distinga del menú —9.24:1— sin gritar. */
.cabezal__acciones { display: flex; gap: 1rem; align-items: center; }
.cabezal__sesion { color: var(--marino); font-size: 0.9375rem; font-weight: 600; text-decoration: none; white-space: nowrap; }
.cabezal__sesion:hover { text-decoration: underline; }
.cabezal .boton { min-height: 40px; padding: 0.45rem 1rem; font-size: 0.9375rem; }

/* El corte sube de 860 a 1120 px: con siete entradas en vez de cuatro, entre
   esos dos anchos el menú y los botones se pisaban en la misma línea. Medido,
   no supuesto. */
@media (max-width: 1120px) {
  .cabezal { position: static; }
  .cabezal__fila { flex-wrap: wrap; gap: 0.75rem 1rem; }
  .menu { width: 100%; margin-left: 0; order: 3; gap: 1rem; }
  .menu__grupo { gap: 1rem; }
  .menu__grupo--paginas { padding-left: 1rem; }
  .cabezal__acciones { margin-left: auto; }
}

/* EN TELÉFONO LAS ANCLAS SE RETIRAN, y no es esconder el menú detrás de tres
   rayas. A 360 px las siete entradas ocupaban tres renglones y el cabezal se
   comía 213 px —el 27 % de la pantalla— antes del titular: en un teléfono eso
   no es navegación, es peaje.

   Se van las CINCO anclas y se quedan las dos páginas y las dos acciones. La
   diferencia importa: un ancla lleva a algo que está en esta misma página, a
   unos deslizamientos de distancia; una página está en otro sitio y sin enlace
   no se llega. Nada queda inalcanzable, y el pie lleva las cinco escritas para
   quien quiera el mapa completo. El filete también se va: separaba dos grupos
   y ya solo queda uno. */
@media (max-width: 560px) {
  .menu__grupo { display: none; }
  .menu__grupo--paginas { display: flex; gap: 0.9rem; padding-left: 0; border-left: 0; }

  /* DOS RENGLONES, no tres. Con `API · Precios` reducido a dos palabras cabe
     al lado del logotipo —240 px de 360— y las acciones bajan solas al
     segundo. Sin reordenar quedaban en tres filas: logotipo, acciones y un
     renglón casi vacío con los dos enlaces. */
  .menu { width: auto; order: 1; margin-left: 1rem; }
  .cabezal__acciones { order: 2; width: 100%; justify-content: flex-end; }
}

.pie { padding: var(--banda-y) 1.25rem 2.5rem; background: var(--marino); color: var(--claro-texto); }
.pie__rejilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; max-width: var(--contenedor); margin: 0 auto; }
.pie h3 { color: var(--nube); font-size: 1rem; margin-bottom: 0.75rem; }
.pie ul { list-style: none; padding: 0; }
.pie a { color: var(--claro-texto); text-decoration: none; }
.pie a:hover { color: var(--nube); text-decoration: underline; }
.pie__legal { max-width: var(--contenedor); margin: 2.5rem auto 0; padding-top: 1.5rem; border-top: 1px solid var(--marino); color: var(--claro-suave); font-size: var(--t-dato); }

/* El filo del pie: la escala 60·30·15·7·3·1. Es la única «decoración»
   permitida porque no es decoración: es el producto contado en números
   (brand book §7). */
.pie__escala { display: flex; gap: 0.75rem; margin: 0 0 1.5rem; padding: 0; list-style: none; color: var(--claro-suave); font-variant-numeric: tabular-nums; font-size: var(--t-dato); letter-spacing: 0.09em; }
.pie__escala li { margin: 0; }

/* ── 11 · MOVIMIENTO ────────────────────────────────────────────────────────
   NO SE MUEVE NADA, y es una decisión, no un olvido.

   El plan tenía el hilo de la ECO-07 avanzando doce segundos en la bitácora del
   hero. Con la bitácora retirada, lo único animable que quedaba habría sido
   inventarle movimiento a una captura de producto —una barra que se llena sola,
   una fila que cambia de color—, y eso ya no es demostrar: es fingir que la
   pantalla está viva. Lo que se mueve son las dos micro-transiciones que sirven
   para algo: la punta de la flecha de un enlace al pasar el ratón y el estado
   de un botón. El bloque de `reduced-motion` se queda igual, porque cubre
   también el desplazamiento suave del navegador.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── 12 · LA CAPA DE PRODUCTO ───────────────────────────────────────────────
   Las reconstrucciones del producto, portadas de `site/src/estilos/primitivas.css`
   sin cambiarles una regla. Cada pantalla existe en la aplicación con el mismo
   nombre, la misma forma y el mismo vocabulario: los DATOS son de ejemplo y el
   sitio lo dice donde los enseña, pero las PANTALLAS son las verdaderas. Es la
   única manera honesta de vender software del que todavía no se pueden publicar
   capturas de clientes reales.

   Aquí está el giro de esta versión del sitio: el producto deja de ser el TEMA
   del texto y pasa a ser el CONTENIDO. Quien compra esto le tiene miedo al
   software, y lo único que quita ese miedo es verlo y que le parezca simple.
   ------------------------------------------------------------------------- */

/* Tokens que la capa de producto da por existentes. Ninguno es inventado: son
   los del árbol de tokens del sitio React con su valor exacto, copiados aquí
   cuando ese árbol se borró el 2026-07-29 — este bloque ES ahora su única
   copia. `--tinta` es un ALIAS de `--pizarra` —el mismo #1E1E24 con el nombre
   que usaba el sitio viejo— para no reescribir 503 líneas y para dejar el
   rastro del rename. */
:root {
  --tinta: var(--pizarra);
  --display: "Archivo", "Segoe UI", system-ui, sans-serif;
  --texto: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;

  /* El claro de marca: la etiqueta de sistema y los rellenos claros CUANDO el
     fondo es marino. Verificado, no estimado: 5.50:1 sobre --marino y 7.42:1
     sobre --marino-noche, que son las dos cifras que el CSS de origen declara.
     Faltaba, y sin él `.superficie-oscura .etiqueta-sistema` se caía entera. */
  --claro-marca: #aecdd6;

  --verde-tinte: #e3f2ea;
  --amarillo-tinte: #fff6e1;
  --rojo-tinte: #fbe9e7;
  --linea-oscura: rgb(255 255 255 / 0.14);

  --t-2xs: 0.6875rem;
  --t-xs: 0.75rem;
  --t-s: 0.8125rem;
  --t-m: 0.875rem;
  --t-base: 1rem;
  --t-lg: 1.125rem;

  --peso-normal: 400;
  --peso-medio: 500;
  --peso-semi: 600;
  --peso-fuerte: 700;
  --track-etiqueta: 0.09em;    /* versalitas de rótulo (brand book §4)       */
  --track-etiqueta-s: 0.06em;  /* la misma etiqueta cuando va dentro de fila */

  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 20px;

  --r-s: 4px;
  --r-m: 6px;
  --r-marco: 12px;
  --r-pildora: 99px;
  --borde-fino: 1px solid var(--borde);
  --rail: 3px;

  /* Dos sombras y ni una más. La 2 levanta una pantalla del papel; la 3 es
     para la ventana del hero, que es la pieza estrella. El resto del sitio
     sigue sin sombra: esto es una herramienta de trabajo. */
  --sombra-2: 0 4px 12px rgb(30 30 36 / 0.1);
  --sombra-3: 0 2px 4px rgb(30 30 36 / 0.05), 0 24px 48px -12px rgb(30 30 36 / 0.22);
}

.placa__eco {
  font-family: var(--display);
  font-weight: var(--peso-semi);
  font-size: var(--t-base);
  letter-spacing: 0;
  color: inherit;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.placa--sm .placa__eco {
  font-size: var(--t-m);
}
.placa__matricula {
  flex: none;
  font-size: var(--t-2xs);
  font-weight: var(--peso-medio);
  letter-spacing: var(--track-etiqueta-s);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--tinta-suave);
  border: 1px solid var(--borde);
  border-radius: var(--r-s);
  padding: 1px var(--e-2);
  line-height: 1.5;
  white-space: nowrap;
}
.superficie-oscura .placa__matricula {
  color: var(--claro-suave);
  border-color: var(--linea-oscura);
}
/* Misma excepción que la etiqueta de sistema en composicion.css, y por la misma
   razón: la línea de tiempo del historial es una tarjeta BLANCA dentro de la
   banda oscura, así que el selector de arriba la alcanza aunque su fondo no sea
   oscuro. La matrícula de ECO-07 se quedaba en `--claro-suave` sobre blanco:
   1.91:1. Sobre la tarjeta vuelve a sus colores de fondo claro. */
.superficie-oscura .linea-tiempo .placa__matricula {
  color: var(--tinta-suave);
  border-color: var(--borde);
}
/* ---------------------------------------------------------------------------
   4. Estado — badge del semáforo
   Color + forma + palabra, siempre (§A6.3). El texto sobre los tintes es
   `--tinta`; el color de estado solo aparece en el glifo y en el borde.

   Los bordes van escritos en `rgb(… / α)` y no en `var(--token)` porque llevan
   alfa: son EL MISMO color del token, rebajado. Si un token de estado cambia de
   hex, estos tres canales cambian con él o el borde se queda en la paleta vieja.
     verde  #0F7346 → rgb(15 115 70)
     amarillo-fuerte #8F6A00 → rgb(143 106 0)
     rojo   #B3261E → rgb(179 38 30)
   --------------------------------------------------------------------------- */

.estado {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  font-size: var(--t-xs);
  font-weight: var(--peso-medio);
  line-height: 1.5;
  color: var(--tinta);
  border: 1px solid;
  border-radius: var(--r-pildora);
  padding: 2px var(--e-3) 2px 8px;
  white-space: nowrap;
}
.estado svg {
  flex: none;
  width: 13px;
  height: 13px;
}
/* Punto de estado suelto (cuando la palabra ya está en el texto de al lado). */
.punto-estado {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tinta-suave);
}
/* ---------------------------------------------------------------------------
   6. Rail de severidad
   Todo lo urgente lo señala con borde izquierdo + glifo + palabra. El verde no
   lleva rail: lo sano no grita. El color nunca es fondo del contenedor.
   --------------------------------------------------------------------------- */

.rail {
  border-left: var(--rail) solid transparent;
  padding-left: var(--e-3);
}
/* ---------------------------------------------------------------------------
   7. Sello de reconstrucción
   El sitio no presume capturas de clientes que no tiene: donde enseña el
   producto con datos inventados, lo dice una vez por figura.
   --------------------------------------------------------------------------- */

/* `align-items: baseline` y no `center`: en móvil el sello parte en dos
   renglones y con `center` el punto quedaba flotando a media altura, separado
   de la primera palabra. Alineado a la línea base viaja pegado a ella. */
.sello {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: var(--t-2xs);
  font-weight: var(--peso-medio);
  letter-spacing: var(--track-etiqueta-s);
  text-transform: uppercase;
  color: var(--tinta-suave);
}
.sello::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border: 1px solid currentcolor;
  border-radius: 50%;
}
.superficie-oscura .sello {
  color: var(--claro-suave);
}
/* ---------------------------------------------------------------------------
   8. Franja de disponibilidad — el elemento de firma
   Una unidad, un segmento. Codifica la promesa del producto (ver el estado de
   toda la flotilla de un vistazo). Nunca viaja sin su leyenda: no depende del
   color para comunicar.
   --------------------------------------------------------------------------- */

.disponibilidad {
  display: grid;
  gap: var(--e-2);
}
.disponibilidad__barra {
  display: flex;
  gap: 2px;
  height: 14px;
}
.disponibilidad__barra i {
  flex: 1 1 0;
  min-width: 4px;
  background: var(--verde);
  border-radius: 2px;
}
/* La franja cierra la página sobre la banda marino («Así se ve una flotilla
   lista»: doce segmentos verdes). Ahí el verde de superficie clara se hundía en
   el fondo —1.57:1 sobre marino, 2.11:1 sobre marino noche—: el elemento de
   firma del sitio, el que resume la promesa del producto, era una barra casi
   lisa. `--verde-claro` da 5.46:1 y 7.37:1; `--rojo-claro`, 5.33:1 y 7.20:1.
   Va inmediatamente después de la regla base y ANTES de los modificadores de
   severidad a propósito: comparte especificidad con `.es-ambar` y `.es-gris`,
   así que si se moviera abajo pintaría de verde también esos segmentos. */
.superficie-oscura .disponibilidad__barra i {
  background: var(--verde-claro);
}
.disponibilidad__barra i.es-ambar {
  background: var(--amarillo);
}
.disponibilidad__barra i.es-rojo {
  background: var(--rojo);
}
/* Especificidad mayor que la regla base oscura: el orden aquí da igual. */
.superficie-oscura .disponibilidad__barra i.es-rojo {
  background: var(--rojo-claro);
}
.disponibilidad__barra i.es-gris {
  background: var(--borde);
}
.disponibilidad--alta .disponibilidad__barra {
  height: 22px;
}
.disponibilidad__leyenda {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-1) var(--e-4);
  font-size: var(--t-s);
  color: var(--tinta-suave);
  font-variant-numeric: tabular-nums;
}
.disponibilidad__leyenda li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.disponibilidad__leyenda b {
  font-weight: var(--peso-semi);
  color: var(--tinta);
}
.superficie-oscura .disponibilidad__leyenda {
  color: var(--claro-texto);
}
.superficie-oscura .disponibilidad__leyenda b {
  color: var(--blanco);
}
/* El highlight va en la barra y no en el marco: la barra pinta su propio
   fondo --patio encima del canto del marco y taparía un inset del padre. */
.ventana--elevada .ventana__barra {
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.7);
}
.ventana__barra {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  min-height: 40px;
  padding-inline: var(--e-4);
  background: var(--patio);
  border-bottom: var(--borde-fino);
}
.ventana__puntos {
  display: flex;
  flex: none;
  gap: 6px;
}
.ventana__puntos i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--borde);
}
.ventana__ruta {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 320px;
  margin-inline: auto;
  padding: 3px var(--e-3);
  background: var(--blanco);
  border: var(--borde-fino);
  border-radius: var(--r-pildora);
  font-size: var(--t-2xs);
  color: var(--tinta-suave);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ventana__lienzo {
  padding: clamp(16px, 2vw, 24px);
}
/* No hay variante «a sangre» de `.foto`, y no por descuido: la única imagen
   del sitio que llega al filo de la pantalla es la del cierre, y ahí no es un
   `<img>` dentro de una columna sino el `background` de la `<section>`
   (secciones.css §Cierre). Una `.foto--sangre` que nadie renderiza no está
   probada; cuando exista una segunda imagen a sangre que sí necesite `<img>`
   —por el `alt`, o por `srcset`— se escribe entonces, con su consumidor
   delante. Ver también composicion.css §Sangre. */

/* ---------------------------------------------------------------------------
   13. Pantallas — lo que va DENTRO de los marcos
   --------------------------------------------------------------------------- */

.app {
  display: grid;
  gap: var(--e-5, 20px);
  font-size: var(--t-m);
}
/* `wrap` para el teléfono: a 360 px la insignia de estado le robaba la mitad
   del ancho al título y «Plan y facturación» partía en dos renglones con el
   subtítulo en tres. Dejándola bajar, el título recupera la línea completa. */
.app__cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-2) var(--e-4);
  padding-bottom: var(--e-3);
  border-bottom: var(--borde-fino);
}
.app__titulo {
  font-family: var(--display);
  font-size: var(--t-lg);
  font-weight: var(--peso-semi);
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--tinta);
}
.app__sub {
  margin-top: 2px;
  font-size: var(--t-s);
  color: var(--tinta-suave);
}
.app__bloque {
  display: grid;
  gap: var(--e-3);
}
.app__bloque-titulo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-3);
}
.app__cifra {
  font-family: var(--display);
  font-size: var(--t-base);
  font-weight: var(--peso-fuerte);
  color: var(--tinta);
}
/* AQUÍ ESTABAN `.app__pestanas` y su máscara de desvanecido: las cinco
   pestañas de la ficha de la ECO-07, que era su única clienta. Se fueron con
   `pantalla_ficha()` el 2026-08-17 — CSS sin selector que lo use es
   exactamente el peso muerto que la retirada de la bitácora ya cobró una vez.
   Si una pantalla vuelve a necesitar pestañas, la máscara está en Git con su
   razonamiento (los lienzos angostos cortaban un glifo a media letra). */
.app__pie {
  padding-top: var(--e-3);
  border-top: var(--borde-fino);
  font-size: var(--t-s);
  line-height: 1.5;
  color: var(--tinta-suave);
}
/* Pendientes del día (panel del hero) */
.pendientes {
  display: grid;
  gap: var(--e-3);
}
.pendiente {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--e-3);
}
.pendiente__glifo {
  display: flex;
}
.pendiente__cuerpo {
  display: grid;
  gap: 2px;
  min-width: 0;
}
.pendiente__asunto {
  font-weight: var(--peso-medio);
  line-height: 1.35;
  color: var(--tinta);
}
.pendiente__dato {
  font-size: var(--t-s);
  color: var(--tinta-suave);
  white-space: nowrap;
}
/* Renglones clave–valor (ficha y gastos) */
.renglones {
  display: grid;
}
.renglon {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-4);
  padding-block: 11px;
  border-bottom: var(--borde-fino);
}
.renglon:last-child {
  border-bottom: 0;
}
.renglon__clave {
  flex: none;
  font-weight: var(--peso-semi);
  color: var(--tinta);
}
.renglon__clave--normal {
  font-weight: var(--peso-normal);
  color: var(--tinta-suave);
}
.renglon__valor {
  color: var(--tinta-suave);
  text-align: right;
}
.renglon--total {
  margin-top: var(--e-1);
  border-top: 2px solid var(--tinta);
}
.renglon--total .renglon__valor {
  font-weight: var(--peso-semi);
  color: var(--tinta);
}
/* Servicios programados, con avance hacia el vencimiento */
.servicios {
  display: grid;
  gap: var(--e-4);
}
.servicio {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--e-2) var(--e-3);
}
.servicio__unidad {
  display: flex;
  align-items: baseline;
  gap: var(--e-2);
  min-width: 0;
}
/* El número económico no se parte ni se encoge; quien cede es el nombre del
   servicio, que sí puede terminar en puntos suspensivos. */
.servicio__unidad .placa {
  flex: none;
}
.servicio__nombre {
  color: var(--tinta-suave);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.servicio__falta {
  font-size: var(--t-s);
  font-weight: var(--peso-semi);
  white-space: nowrap;
  text-align: right;
}
.servicio__barra {
  grid-column: 1 / -1;
  display: block;
  height: 6px;
  background: var(--patio);
  border: var(--borde-fino);
  border-radius: var(--r-pildora);
  overflow: hidden;
}
.servicio__barra i {
  display: block;
  height: 100%;
  background: var(--verde);
}
.servicio__barra i.es-ambar {
  background: var(--amarillo);
}
/* Hoja de inspección */
.revision {
  display: grid;
}
.revision__punto {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--e-3);
  padding-block: 10px;
  border-bottom: var(--borde-fino);
}
.revision__punto:last-child {
  border-bottom: 0;
}
.revision__glifo {
  display: flex;
  color: var(--verde);
}
.revision__resultado {
  font-size: var(--t-s);
  color: var(--tinta-suave);
}
.revision__punto--falla .revision__glifo {
  color: var(--rojo);
}
.revision__punto--falla .revision__nombre,
.revision__punto--falla .revision__resultado {
  font-weight: var(--peso-semi);
  color: var(--tinta);
}
/* Evidencia adjunta */
.evidencia {
  display: grid;
  gap: var(--e-2);
  padding: var(--e-3);
  background: var(--patio);
  border-radius: var(--r-m);
}
.evidencia__nota {
  font-size: var(--t-s);
  line-height: 1.5;
  color: var(--tinta-suave);
}
.evidencia__fotos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-2);
}
.evidencia__foto {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px var(--e-2);
  background: var(--blanco);
  border: var(--borde-fino);
  border-radius: var(--r-s);
  font-size: var(--t-2xs);
  color: var(--tinta-suave);
}
.evidencia__salida {
  font-size: var(--t-s);
  font-weight: var(--peso-semi);
  color: var(--marino);
}
/* La etiqueta de sistema nace en tinta suave, que sobre el marino del cierre da
   1.5:1 —el rótulo «Así se ve una flotilla lista» era ilegible—. Sobre fondo
   oscuro pasa a `--claro-marca` (5.5:1 sobre marino, 7.4:1 sobre marino noche). */
.superficie-oscura .etiqueta-sistema {
  color: var(--claro-marca);
}
/* Excepción: la línea de tiempo es una tarjeta BLANCA dentro de una banda
   oscura, así que ahí la etiqueta vuelve a su color de fondo claro. */
.superficie-oscura .linea-tiempo .etiqueta-sistema {
  color: var(--tinta-suave);
}
/* Los titulares NO llevan 700. A 56 y 64 px un peso fuerte se lee como grito:
   la escala ya hace el trabajo que antes hacía el trazo, y el registro que
   busca la portada es grande y ligero. 600 (--peso-semi, heredado de la regla
   de arriba) es LA LIGEREZA MÁXIMA DISPONIBLE: el woff2 de Archivo va
   subseteado a `font-weight: 600 700` (fuentes.css:24), así que pedir 400 no
   adelgaza nada —el navegador sintetiza o cae en Segoe UI—. El resto de la
   ligereza la pone el tracking negativo (--track-titular). El 700 sigue vivo
   donde sí es dato y no titular: .app__cifra, .etiqueta-unidad__eco. */
/* Todo número de dato alinea: kilometrajes, precios, folios, horas. */
.tnum {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* Etiqueta de sistema: 12 px, mayúsculas, tracking. Solo en los cuatro sitios
   permitidos (§3.2): eyebrow de sección, encabezado de bitácora, encabezado de
   grupo de severidad y etiqueta de grupo. Nunca en cuerpo de texto. */
.etiqueta-sistema {
  font-family: var(--texto);
  font-size: var(--t-xs);
  font-weight: var(--peso-semi);
  line-height: 1.2;
  letter-spacing: var(--track-etiqueta);
  text-transform: uppercase;
  color: var(--tinta-suave);
}

.ventana {
  width: 100%;
  background: var(--blanco);
  border: var(--borde-fino);
  border-radius: var(--r-marco);
  box-shadow: var(--sombra-2);
  overflow: hidden;
}
.ventana--elevada {
  border-color: rgb(0 78 100 / 0.2);
  box-shadow: var(--sombra-3);
}


/* ── 13 · EL ANCHO DE LA PANTALLA ───────────────────────────────────────────
   Una interfaz tiene un ancho para el que fue diseñada. Estirada más allá, las
   filas se vacían por el centro —el rótulo a la izquierda y su cifra a 700 px—
   y deja de leerse como una pantalla densa para parecer una tabla reventada.
   El tope es del MARCO, no de la columna: la columna puede crecer, la ventana no.
   ------------------------------------------------------------------------- */
.hero__pantalla .ventana { max-width: 760px; }
.escena__pantalla .ventana { max-width: 620px; }
.escena--invertida .escena__pantalla { display: flex; justify-content: flex-end; }


/* ── 14 · EL TELÉFONO ───────────────────────────────────────────────────────
   El de `site/` medía 240 px porque allí era una viñeta pequeña dentro de una
   banda de texto. Aquí es la protagonista de su escena, y a ese ancho no parecía
   un teléfono: «Niveles y fugas» partía en dos renglones, el titular también, y
   la proporción salía 1:3 —un teléfono real es 1:2.1—. Un marco negro con las
   esquinas poco redondeadas es una caja, no un aparato.

   Lo que lo hace leerse como teléfono, en orden de importancia:
     1. el ANCHO de pantalla real (360 px de lienzo, que es lo que mide un
        teléfono de gama media), para que el texto no se parta donde no se parte;
     2. el radio grande y proporcional —46 px fuera, 34 dentro—;
     3. la isla del altavoz y la barra de inicio, que son los dos detalles que
        el ojo usa para reconocer la forma sin tener que pensarlo.
   ------------------------------------------------------------------------- */
.telefono {
  flex: none;
  position: relative;
  width: 380px;
  max-width: 100%;
  padding: 10px;
  background: var(--pizarra);
  border-radius: 46px;
  box-shadow: var(--sombra-3);
}

.telefono__pantalla {
  position: relative;
  overflow: hidden;
  background: var(--blanco);
  border-radius: 36px;
  padding: 0 0 1.5rem;
  /* 9:19 es la proporción de un teléfono actual. Sin ella el marco salía a
     1:1.63 —la altura la marcaba el contenido— y parecía una tableta pequeña.
     Que sobre blanco abajo no es un defecto: es como se ve una pantalla real
     cuando la lista no llega al final. */
  aspect-ratio: 9 / 19;
}

/* La isla del altavoz. Va sobre el lienzo, no dentro del flujo, para que el
   contenido de la pantalla empiece donde empezaría de verdad. */
.telefono__pantalla::before {
  content: "";
  position: absolute;
  top: 9px;
  left: 50%;
  transform: translateX(-50%);
  width: 88px;
  height: 22px;
  background: var(--pizarra);
  border-radius: 99px;
  z-index: 2;
}

/* La barra de inicio. Dos píxeles de detalle que rematan la forma. */
.telefono__pantalla::after {
  content: "";
  position: absolute;
  bottom: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 118px;
  height: 4px;
  background: var(--pizarra);
  opacity: 0.28;
  border-radius: 99px;
}

/* Barra de estado: la hora a la izquierda, señal, wifi y batería a la derecha.
   Se reserva la altura de la isla para que la hora no quede debajo de ella. */
.telefono__estado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 40px;
  padding: 0 1.5rem;
  font-size: var(--t-2xs);
  font-weight: var(--peso-semi);
  color: var(--pizarra);
}

.telefono__senal { display: flex; align-items: center; gap: 5px; }
.telefono__senal i { display: block; background: var(--pizarra); }

/* Las tres barras de cobertura. */
.telefono__senal i:nth-child(1),
.telefono__senal i:nth-child(2),
.telefono__senal i:nth-child(3) { width: 3px; border-radius: 1px; }
.telefono__senal i:nth-child(1) { height: 5px; }
.telefono__senal i:nth-child(2) { height: 8px; }
.telefono__senal i:nth-child(3) { height: 11px; }

/* La batería: cuerpo con borde y su tapa. */
.telefono__bateria {
  position: relative;
  width: 22px;
  height: 11px;
  margin-left: 3px;
  border: 1.5px solid var(--pizarra);
  border-radius: 3px;
}
.telefono__bateria::before {
  content: "";
  position: absolute;
  inset: 1.5px;
  background: var(--pizarra);
  border-radius: 1px;
}
.telefono__bateria::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -4px;
  transform: translateY(-50%);
  width: 2px;
  height: 4px;
  background: var(--pizarra);
  border-radius: 0 1px 1px 0;
}

/* La aplicación dentro del teléfono no lleva el marco de tarjeta: ya está
   dentro de uno. Las DOS pantallas que caben aquí, porque son clases distintas
   y con solo `.app` el contenido de la de campo corría hasta el filo del
   cristal: «3 de 5» quedaba medio cortado contra el borde. */
.telefono .app,
.telefono .campo-app { border: 0; border-radius: 0; box-shadow: none; padding: 0 1.25rem; }

@media (max-width: 460px) {
  .telefono { width: 100%; padding: 8px; border-radius: 36px; }
  .telefono__pantalla { border-radius: 28px; }
}


/* ── 15 · PIEZAS DE PRODUCTO PARA /precios Y /api ───────────────────────────
   Las tres pantallas nuevas —Plan y facturación, Llaves de API y el alta de
   permisos— existen en la aplicación con este nombre y esta forma. Se portan
   porque son las que contestan la objeción de su página: en /precios, si los
   topes son letra chica; en /api, si hay que prestar la contraseña del dueño.
   Ninguna respuesta escrita hace ese trabajo tan rápido.
   ------------------------------------------------------------------------- */

/* El medidor de topes. La regla de «apretado» es la del producto —el 90 % del
   tope— y por eso una de las cuatro pinta en rojo. Enseñar el medidor lleno es
   más honesto que enseñar cuatro barras a la mitad: lo que el comprador quiere
   saber es qué pasa cuando se acaba. */
.medidores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--e-4) var(--e-5);
}

.medidor__fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-2);
  font-size: var(--t-s);
}
.medidor__clave { color: var(--tinta-suave); }
.medidor__valor { font-weight: var(--peso-medio); }

.medidor__barra {
  margin-top: 6px;
  height: 6px;
  border-radius: var(--r-pildora);
  background: var(--nube);
  overflow: hidden;
}
.medidor__barra i {
  display: block;
  block-size: 100%;
  border-radius: var(--r-pildora);
  background: var(--marino);
}

/* Al 90 % del tope el medidor cambia de color Y el número engorda: el color
   nunca es el único indicador. */
.medidor--apretado .medidor__valor { color: var(--rojo); font-weight: var(--peso-semi); }
.medidor--apretado .medidor__barra i { background: var(--rojo); }

/* A dónde apunta la llave. Es lo primero de la pantalla real, porque es lo
   primero que pregunta quien va a escribir la integración. */
.base-url {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-2) var(--e-3);
  margin: 0 0 var(--e-4);
  padding: var(--e-3);
  background: var(--patio);
  border: var(--borde-fino);
  border-radius: var(--r-m);
}
.base-url code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: var(--t-s);
  color: var(--pizarra);
  overflow-wrap: anywhere;
}

/* Botón dibujado dentro de una pantalla. No es un enlace y no se puede pulsar:
   es parte de la reconstrucción, así que no lleva estados. */
.boton-falso {
  flex: none;
  padding: 0.4rem 0.8rem;
  background: var(--marino);
  color: var(--blanco);
  border-radius: var(--r-s);
  font-size: var(--t-s);
  font-weight: var(--peso-semi);
}

/* La tabla de llaves emitidas. Cuatro columnas en pantalla ancha; abajo de
   760 px se parte en dos renglones, que es lo que hace la tabla del producto. */
.llaves { list-style: none; margin: 0; padding: 0; }
.llaves__encabezado,
.llave {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1.4fr) minmax(0, 0.8fr) minmax(0, 0.85fr);
  gap: var(--e-3);
  align-items: baseline;
  padding: 0.6rem 0;
  border-bottom: var(--borde-fino);
}
.llaves__encabezado {
  margin: 0;
  padding-top: 0;
  font-size: var(--t-2xs);
  font-weight: var(--peso-semi);
  letter-spacing: var(--track-etiqueta-s);
  text-transform: uppercase;
  color: var(--tinta-suave);
}
.llave:last-child { border-bottom: 0; }

.llave__sistema { font-size: var(--t-m); font-weight: var(--peso-semi); }
.llave__prefijo {
  display: block;
  margin-top: 2px;
  font-size: var(--t-2xs);
  font-weight: var(--peso-normal);
  color: var(--tinta-suave);
}
.llave__permisos,
.llave__uso,
.llave__vence { font-size: var(--t-s); color: var(--tinta-suave); }

/* Los permisos, uno por uno. Es el argumento entero de /api en una imagen.
   Sin `margin-top`: los grupos son hijos directos de `.app`, que ya es una
   rejilla con su propio hueco, y sumar los dos los separaba 36 px. */
.permisos { list-style: none; margin: 6px 0 0; padding: 0; }

.permiso {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: 0.35rem 0;
  font-size: var(--t-m);
  color: var(--tinta-suave);
}
.permiso--marcado { color: var(--pizarra); font-weight: var(--peso-medio); }

/* El filete de la casilla vacía va en `--tinta-suave` y no en `--borde`: contra
   blanco, `--borde` mide 1.34:1 y desaparece. Aquí la casilla apagada tiene que
   VERSE —el argumento de la pantalla es que veintiún permisos se dan uno por
   uno, y sin caja vacía visible no hay tal cosa que ver—. Con tinta suave son
   6.13:1, de sobra para un elemento gráfico. */
.casilla {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--tinta-suave);
  border-radius: 3px;
  background: var(--blanco);
  color: var(--blanco);
}
.casilla--marcada { background: var(--marino); border-color: var(--marino); }

/* El alta de llave es un DIÁLOGO, no una página: se estrecha para que se lea
   como lo que es. */
.app--dialogo { max-width: 460px; margin-inline: auto; }

@media (max-width: 760px) {
  .llaves__encabezado { display: none; }
  .llave { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.2rem var(--e-3); }
  .llave__sistema  { grid-column: 1 / -1; }
  .llave__permisos { grid-column: 1 / -1; }
}


/* ── 16 · COMPOSICIONES DE /precios, /api Y /demo ───────────────────────────
   Las tres páginas venían de la primera versión —riel de 168 px a la izquierda,
   titular, párrafo, muro de texto— y con la portada rehecha se leían como otro
   sitio. Aquí adoptan la misma gramática: superficie clara, una pantalla real
   por argumento y la prosa a pie de foto.
   ------------------------------------------------------------------------- */

/* La cabecera de página: el mismo campo patio del hero, sin pantalla. Se centra
   solo cuando lo que sigue es una rejilla ancha —las tarjetas de plan—, porque
   un titular centrado sobre texto corrido no se lee. */
.cabecera-pagina {
  max-width: 44rem;
  margin: 0 auto;
  padding: clamp(2.5rem, 1.5rem + 3vw, 4rem) 1.25rem clamp(1.5rem, 1rem + 2vw, 2.5rem);
  text-align: center;
}
/* Un escalón por debajo del h1 de la portada, a propósito: el titular de la
   portada es la tesis del producto y tiene que ser lo más grande del sitio. A
   72 px dentro de esta columna, «Cuánto cuesta, sin llamar a nadie» se partía
   en tres renglones con el corte en mal sitio. */
.cabecera-pagina h1,
.demo__rejilla h1,
.texto-legal h1 {
  font-size: clamp(2.25rem, 1.7rem + 2.2vw, 3.25rem);
  margin-bottom: 1rem;
}
.cabecera-pagina .entrada { max-width: 58ch; margin-inline: auto; color: var(--tinta-suave); }
.cabecera-pagina .rotulo { margin-bottom: 1rem; }

/* Condiciones del precio: tres hechos cortos en una tira, no viñetas. Llevan
   punto medio entre ellos porque son del mismo rango, no una secuencia. */
.condiciones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem 1.25rem;
  margin: 1.25rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--tinta-suave);
  font-size: 0.9375rem;
}
.condiciones li { position: relative; }
.condiciones li + li::before {
  content: "·";
  position: absolute;
  left: -0.7rem;
  color: var(--borde);
}

/* Qué plan me toca. El dueño no sabe qué plan quiere: sabe cuántas unidades
   tiene. Cuatro traducciones en una tira, debajo de las tarjetas, que es donde
   se hace la pregunta. */
.guia {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  margin: 2rem 0 0;
  padding: 0;
  list-style: none;
  background: var(--borde);
  border: var(--borde-fino);
  border-radius: var(--r-m);
  overflow: hidden;
}
.guia li {
  margin: 0;
  padding: 0.85rem 1rem;
  background: var(--patio);
  text-align: center;
}
.guia__rango {
  display: block;
  font-variant-numeric: tabular-nums;
  font-weight: var(--peso-semi);
}
.guia__plan { display: block; margin-top: 0.15rem; color: var(--tinta-suave); font-size: var(--t-dato); }

/* Los cuatro sistemas de /api. Tarjetas y no viñetas: cada una es un caso de
   uso completo, y en lista corrida se leían como una promesa de conectores. */
.casos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
  margin-top: 2rem;
}
.caso {
  padding: 1.25rem;
  background: var(--blanco);
  border: var(--borde-fino);
  border-radius: var(--radio);
}
.caso h3 { font-size: 1.0625rem; margin-bottom: 0.5rem; }
.caso p { color: var(--tinta-suave); font-size: 0.9375rem; max-width: none; }

/* Petición y respuesta, lado a lado. En columna se leían como dos bloques sin
   relación; juntos se ve de un golpe lo corto que es el trato. */
.llamada {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}
.llamada__parte { min-width: 0; display: flex; flex-direction: column; }
.llamada__parte .etiqueta-sistema { display: block; margin-bottom: 0.5rem; }
/* Los dos bloques igualan altura. Con alturas distintas la pareja se leía como
   dos cosas sueltas en vez de como el ida y vuelta de una sola llamada. */
.llamada__parte .codigo { margin: 0; flex: 1; }

/* /demo: el argumento a la izquierda, el formulario a la derecha. La pregunta
   se ve sin desplazarse, que es la mitad del trabajo de esta página.

   Va por ÁREAS y no por orden de marcado porque en una sola columna el orden
   correcto no es el mismo: la salida por correo tiene que ir DESPUÉS del
   formulario. Con las tres piezas dentro de la columna izquierda, en móvil la
   puerta de escape se leía antes que la pregunta. */
.demo__rejilla {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  grid-template-areas:
    "argumento forma"
    "salida    forma";
  gap: clamp(2rem, 1rem + 3vw, 3.5rem);
  align-items: start;
  max-width: var(--contenedor);
  margin: 0 auto;
  padding: clamp(2rem, 1.5rem + 2vw, 3.5rem) 1.25rem;
}
.demo__argumento { grid-area: argumento; }
.demo__forma     { grid-area: forma; }
.demo__salida    { grid-area: salida; }

.demo__forma {
  padding: clamp(1.25rem, 1rem + 1vw, 2rem);
  background: var(--blanco);
  border: var(--borde-fino);
  border-radius: var(--r-marco);
  box-shadow: var(--sombra-2);
}
.demo__forma h2 { font-size: var(--t-h3); margin-bottom: 1.25rem; }

/* Los tres pasos de la llamada. AQUÍ el numeral sí es estructura y no adorno:
   es una secuencia en el tiempo, ocurre en ese orden y dura veinte minutos. En
   el resto del sitio no hay un solo 01/02/03 por esa misma razón. */
.pasos { list-style: none; margin: 2rem 0 0; padding: 0; counter-reset: paso; }
.paso {
  position: relative;
  counter-increment: paso;
  margin-left: 0.85rem;
  padding: 0 0 1.5rem 2.75rem;
  border-left: 1px solid var(--borde);
}
.paso:last-child { border-left-color: transparent; padding-bottom: 0; }
.paso::before {
  content: counter(paso);
  position: absolute;
  left: -0.85rem;
  top: -0.15rem;
  display: grid;
  place-items: center;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  background: var(--marino);
  color: var(--blanco);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-dato);
  font-weight: var(--peso-semi);
}
.paso__minuto {
  display: block;
  color: var(--tinta-suave);
  font-size: var(--t-2xs);
  font-weight: var(--peso-semi);
  letter-spacing: var(--track-etiqueta);
  text-transform: uppercase;
}
.paso__titulo { display: block; font-weight: var(--peso-semi); margin-top: 0.15rem; }
.paso p { margin: 0.25rem 0 0; color: var(--tinta-suave); font-size: 0.9375rem; max-width: none; }

/* La salida honesta: si no quieres llenar un formulario, escribe. Va dentro de
   la columna del argumento y no como nota al pie del formulario. */
/* En blanco y no en patio: la banda de /demo YA es patio, así que un recuadro
   patio sobre patio solo se veía por el filete. En blanco hace pareja con la
   tarjeta del formulario, que es justo la relación que tiene con ella —la
   alternativa a llenarlo—. */
.demo__salida {
  padding: 1.25rem;
  background: var(--blanco);
  border: var(--borde-fino);
  border-radius: var(--radio);
}
.demo__salida p { margin: 0; color: var(--tinta-suave); font-size: 0.9375rem; }
.demo__salida p + p { margin-top: 0.5rem; }

@media (max-width: 900px) {
  .demo__rejilla {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "argumento" "forma" "salida";
    gap: 2rem;
  }
}


/* ── 17 · LA ETIQUETA QR Y LA PANTALLA DE CAMPO ─────────────────────────────
   La escena del patio: la calcomanía pegada en la puerta y el teléfono que la
   acaba de escanear, uno al lado del otro. Es la única figura del sitio que
   enseña una pieza FÍSICA del producto, y hace un trabajo que ningún párrafo
   hace igual de rápido: contesta «¿qué tiene que instalar mi conductor?» con
   una calcomanía y un navegador.
   ------------------------------------------------------------------------- */

.escena-qr {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 2.4vw, 2.5rem);
  margin: 0;
  width: 100%;
}

.escena-qr__etiqueta {
  display: grid;
  justify-items: center;
  gap: 0.6rem;
}

/* El pie va bajo la etiqueta y no bajo la escena entera: describe LA
   CALCOMANÍA, no la figura. Puesto abajo del todo se leería como si el teléfono
   también fuera algo que se pega en la puerta. */
.escena-qr__pie {
  max-width: 16ch;
  color: var(--tinta-suave);
  font-size: var(--t-dato);
  line-height: 1.4;
  text-align: center;
}

/* ── La calcomanía ────────────────────────────────────────────────────────── */
.etiqueta-unidad {
  position: relative;
  width: 158px;
  padding: var(--e-4) var(--e-3) var(--e-3);
  background: var(--blanco);
  border: var(--borde-fino);
  border-radius: 10px;
  box-shadow: var(--sombra-2);
  color: var(--pizarra);
  text-align: center;
}

/* El troquel del colgador. Cinco píxeles que convierten un recuadro blanco en
   una etiqueta impresa: es el detalle que el ojo usa para reconocer el objeto
   sin tener que leer nada. */
.etiqueta-unidad::before {
  content: "";
  position: absolute;
  top: 7px;
  left: 50%;
  transform: translateX(-50%);
  width: 28px;
  height: 5px;
  background: var(--patio);
  border: var(--borde-fino);
  border-radius: var(--r-pildora);
}

.etiqueta-unidad svg.qr { display: block; margin: var(--e-2) auto; }

/* El número económico en Archivo (brand book §4 y §7): es la identidad de la
   unidad, no un dato medido. */
.etiqueta-unidad__eco {
  display: block;
  font-family: var(--display);
  font-weight: var(--peso-fuerte);
  font-size: var(--t-lg);
  letter-spacing: 0.01em;
}

.etiqueta-unidad__placa {
  display: block;
  font-size: var(--t-2xs);
  letter-spacing: var(--track-etiqueta-s);
  text-transform: uppercase;
  color: var(--tinta-suave);
}

/* El filete discontinuo antes de la marca: el troquel de corte de una etiqueta
   impresa de verdad. */
.etiqueta-unidad__marca {
  display: block;
  margin-top: var(--e-2);
  padding-top: var(--e-2);
  border-top: 1px dashed var(--borde);
  font-size: var(--t-2xs);
  font-weight: var(--peso-semi);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--marino);
}

/* ── La pantalla del conductor ────────────────────────────────────────────── */
.campo-app { display: grid; gap: var(--e-3); }

.campo-app__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-2);
  padding-bottom: var(--e-2);
  border-bottom: var(--borde-fino);
}

/* «3 de 5» y no «2 de 5 hechos»: quien está de pie junto a la unidad quiere
   saber cuánto le falta, no cuánto lleva. */
.campo-app__paso { font-size: var(--t-2xs); color: var(--tinta-suave); }

.campo-app__titulo {
  margin: 0;
  font-family: var(--display);
  font-size: var(--t-base);
  font-weight: var(--peso-semi);
  color: var(--pizarra);
}

.campo-app__puntos { display: grid; gap: var(--e-3); list-style: none; margin: 0; padding: 0; }
.campo-app__puntos li { display: grid; gap: 6px; margin: 0; }

.campo-app__nombre {
  font-size: var(--t-s);
  font-weight: var(--peso-medio);
  color: var(--pizarra);
}

/* DOS BOTONES DEL MISMO TAMAÑO, a mitad de ancho cada uno. Es la prueba visual
   de «botones grandes y pocos pasos»: se tocan con guante, sin apuntar. */
.campo-app__opciones { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }

.campo-app__opciones span {
  padding: 9px 4px;
  border: var(--borde-fino);
  border-radius: var(--r-m);
  font-size: var(--t-s);
  text-align: center;
  color: var(--tinta-suave);
}

/* Lo elegido se marca con relleno Y con peso, no solo con color: el tinte verde
   sobre blanco es 1.1:1 y por sí solo no distingue nada. El texto encima es
   pizarra —14.3:1 sobre el tinte— y el borde da el filo que el relleno no da. */
.campo-app__opciones .es-elegida {
  border-color: rgb(15 115 70 / 0.45);
  background: var(--verde-tinte);
  color: var(--pizarra);
  font-weight: var(--peso-semi);
}
.campo-app__opciones .es-falla {
  border-color: rgb(179 38 30 / 0.45);
  background: var(--rojo-tinte);
}

.campo-app__evidencia {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: var(--t-s);
  color: var(--tinta-suave);
}

.campo-app__boton {
  margin: 0;
  padding: 12px;
  background: var(--marino);
  color: var(--blanco);
  border-radius: var(--r-m);
  font-size: var(--t-m);
  font-weight: var(--peso-semi);
  text-align: center;
}

/* EL TELÉFONO DE ESTA ESCENA ES MÁS ESTRECHO, y tiene motivo. A 380 px la
   pantalla de campo —tres puntos, dos botones y el envío— llenaba poco más de
   la mitad del cristal y el resto quedaba en blanco: leído se veía como un
   fallo de recorte, no como una pantalla real. A 330 px la misma proporción
   9:19 queda casi llena, los rótulos siguen cabiendo en una línea y, de paso,
   la etiqueta al lado gana peso en la composición. El de la escena de la
   inspección larga se queda en 380: ahí sí hay contenido que lo llene. */
.escena-qr .telefono { width: 330px; }

/* A partir de aquí no caben lado a lado. La etiqueta va PRIMERO también en
   vertical: es lo que el conductor ve antes de sacar el teléfono. */
@media (max-width: 460px) {
  .escena-qr { gap: 1.5rem; }
  .escena-qr__pie { max-width: none; }
  .escena-qr .telefono { width: 100%; }
}
