/*
 * La hoja común de Signing Flows — el paso A del sistema de diseño.
 *
 * ═══ QUÉ ES ═══
 *
 * La especificación está en `docs/diseno/sistema-de-diseno.md`. Esta hoja es
 * su primera entrega: los tokens (§3) y los componentes que la interfaz
 * necesitaba repetir igual en todas las pantallas (§4), empezando por los que
 * pidió Walter el 24-09-2026 para el refinamiento general:
 *
 *   · el menú (`sf-menu`): el «⋯» con las acciones de una fila, y el selector
 *     de idioma, que es el mismo control;
 *   · la celda de acciones de una fila (`sf-acciones`): una acción a la vista y
 *     el resto en el menú, para que una fila no crezca con una nube de botones;
 *   · el acordeón (`sf-acordeon`) y las pestañas (`sf-tabs`), para ordenar las
 *     páginas largas;
 *   · el texto largo con «más» (`sf-mas`), para que una explicación no ocupe
 *     la pantalla;
 *   · el globo con el motivo del ● de la vidriera (`sf-pop`).
 *
 * El comportamiento vive en `componentes.js`, que carga cada página.
 *
 * ═══ LAS DOS REGLAS DE ESTA HOJA ═══
 *
 * ⚠ **Sólo clases `sf-` y tokens `--sf-`** (y las `@font-face` de la
 * tipografía, que no seleccionan nada). No hay acá ni un selector de
 * elemento suelto (`button`, `table`, `body`): cada pantalla tiene su propio
 * vocabulario de clases, y mezclar vocabularios ya produjo tres veces un
 * elemento invisible. Una clase `sf-` no pisa ninguna vieja. La única
 * excepción es `.vd-punto`, el ● de la vidriera, que ya se llamaba igual en
 * las tres consolas y se define acá una sola vez.
 *
 * ⚠ **La marca que se pinta es `--brand`, no `--sf-brand`.** El tema de la
 * instalación y la marca de cada cuenta escriben `--brand` en tiempo de
 * ejecución; `--sf-brand` es sólo la omisión del producto. Por eso cada
 * componente dice `var(--brand, var(--sf-brand))`.
 *
 * ⚠ Se carga ANTES del `<style>` de cada página: lo común primero, lo propio
 * después. Donde un componente tiene que ganarle a una regla vieja de igual
 * peso (los botones de un menú contra `.btn.chico`, por ejemplo), lo hace con
 * un selector más específico y no con `!important`.
 */

/* ═══ La tipografía, empaquetada (§3 y decisión 3 del §6) ═══
   Figtree para todo y JetBrains Mono para el código, servidas desde
   `public/fuentes/` (ver `FUENTES_PUBLICAS` en `src/server.ts`), con su
   licencia SIL OFL 1.1 al lado. Son los mismos archivos que las páginas le
   pedían a Google hasta el 25-09-2026 —fuentes variables, subconjuntos latin y
   latin-ext, con los mismos `unicode-range`—, así que nada cambia a la vista;
   lo que cambia es que ninguna página sale a internet a buscar su letra. Los
   pesos declarados son los que se pedían: 400 a 800 de Figtree, 400 y 500 de
   JetBrains Mono. El árabe y el japonés no están en estas fuentes: caen en la
   letra del sistema, como antes. */
@font-face{font-family:'Figtree';font-style:normal;font-weight:400 800;font-display:swap;
  src:url(/fuentes/figtree-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Figtree';font-style:normal;font-weight:400 800;font-display:swap;
  src:url(/fuentes/figtree-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:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;
  src:url(/fuentes/jetbrains-mono-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 500;font-display:swap;
  src:url(/fuentes/jetbrains-mono-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}

/* ═══ Tokens (§3 de la especificación) ═══ */
:root{
  --sf-ink:#241B2E;
  --sf-mut:#6B6478;
  --sf-line:#E0E3EB;
  --sf-paper:#FFFFFF;
  --sf-soft:#F5F5F7; /* v7cw (Walter 17-10 21:0x): el gris de las bandas, un paso más claro, el de Apple; antes #F2F2F5 */
  --sf-brand:#723988; --sf-brand-600:#8A4BA4; --sf-brand-700:#4E2760; --sf-brand-50:#F3EFF7;
  --sf-acc:#C6168D; --sf-acc-700:#9E1171; --sf-acc-50:#FCE9F5;
  --sf-ok:#067647;
  --sf-bad:#b3261e;
  --sf-warn:#8a5a00;
  /* Los fondos suaves de estado (paso A, §4 de la especificación): el texto de
     arriba pasa AA sobre cada uno (medido en la prueba, y al revés: bajarlo a
     mano lo hace caer). `--sf-ok-50`/`--sf-bad-50`/`--sf-warn-50` son
     `--ok-soft`/`--bad-soft`/`--warn-soft` de validar.html: con el verde de
     ESA página (`#1d7f4f`) el par no llegaba a AA (4,43 medido); con el
     `--sf-ok` único de la decisión 1 del §6 (`#067647`) sí (5,04). Ninguna de
     las diez páginas tiene hoy un color «informativo»: `--sf-info` y
     `--sf-info-50` son nuevos —no hay de dónde extraerlos—, elegidos para no
     confundirse ni con la marca ni con el acento y para pasar AA igual. La
     VARIANTE que los usa se llama `.sf-nota`, no `.sf-info`: `.sf-info` es el
     botón «i» de la ayuda plegada, y un modificador con su nombre heredaba sus
     20 × 20 px (la guarda «ningún modificador se llama como un componente»). */
  --sf-ok-50:#e5f5ec;
  --sf-bad-50:#fbe9e7;
  --sf-warn-50:#fff4dc;
  --sf-info:#0b5fae; --sf-info-50:#eaf2fb;
  /* ⚠ El ● de la vidriera NO es `--sf-warn`: uno es un estado del documento,
     el otro una función que este entorno no tiene (decisión J). */
  --sf-dot:#F5B544;
  --sf-r-s:8px; --sf-r:11px; --sf-r-l:16px; --sf-r-pill:999px;
  --sf-font:'Figtree',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --sf-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --sf-sombra-1:0 2px 4px #0b2b4a08;
  --sf-sombra-2:0 12px 28px #0b2b4a0c;
  /* Las dos sombras de la portada, que hasta el 26-09-2026 eran `--s2` y
     `--s3` de su propio `<style>`: acá para que el recorrido dibuje con las
     mismas y no con una copia. La de lo que flota (una tarjeta que se levanta,
     el globo sobre una maqueta) y la de la maqueta entera (el documento del
     hero, el registro de evidencia, el bloque de la API del recorrido). */
  --sf-sombra-flota:0 2px 4px rgba(11,43,74,.04), 0 12px 28px rgba(11,43,74,.08);
  --sf-sombra-maqueta:0 4px 8px rgba(11,43,74,.05), 0 24px 60px rgba(11,43,74,.14);
  --sf-sombra-menu:0 12px 32px rgba(36,27,46,.16),0 2px 6px rgba(36,27,46,.08);

  /* ═══ Encargo 191 · FASE 0 · L2: un solo juego de tokens (07-10-2026) ═══
     Los colores y las letras que la portada (`sitio.html`) traía sueltos en su
     `<style>`, con el MISMO valor que tenían: acá se nombran y la portada los
     pide por nombre. Nada cambia a la vista (huella antes/después, en el PR).
     El tour (`product-tour/`) y la guía (`guia/guide.css`) mapean sus propios
     nombres (`--brand`, `--ink`, `--font`…) a estos `--sf-*`. La guarda es
     `test/un_solo_juego_de_tokens.test.ts`: en una página migrada no queda un
     color ni una letra escritos a mano fuera de esta hoja. */
  --sf-negro:#000;
  --sf-hero-azul:#f0f6fd; --sf-hero-tope:#fbfdff;
  --sf-trazo:#eef2f7;
  --sf-neutro-50:#f2f5f9; --sf-neutro-400:#9aa8b8;
  --sf-ambar-50:#fef6e7; --sf-ambar-700:#8a5c05; --sf-ambar-900:#4a3200;
  --sf-marca-azul:#12578a;
  --sf-evid-texto:#DED3E8; --sf-cierre-texto:#b7cfe3;
  --sf-avatar-gris:#8fa3b8; --sf-avatar-suave:#dde5ee; --sf-avatar-suave-texto:#5a6878;
  --sf-blanco-82:rgba(255,255,255,.82); --sf-blanco-14:rgba(255,255,255,.14);
  --sf-turquesa-34:rgba(10,162,176,.34);
  /* Los dos que el tour traía y la portada no tiene: el valor es el SUYO (si se
     unificaran con `--sf-soft` y `--sf-blanco-14` se vería distinto: pregunta 1 del PR). */
  --sf-superficie:#f7f8fa;
  --sf-blanco-34:rgba(255,255,255,.34);
  /* La escala tipográfica: los tamaños que la portada usa, con su valor exacto
     (el nombre es el tamaño en px, con guion por punto). No es una escala
     «redonda»: llevarla a una (13/14/15/16…) movería textos a la vista y se
     decide aparte (pregunta 2 del PR). */
  --sf-fs-10:10px; --sf-fs-10-5:10.5px; --sf-fs-11:11px; --sf-fs-12:12px; --sf-fs-12-5:12.5px;
  --sf-fs-13:13px; --sf-fs-13-5:13.5px; --sf-fs-14:14px; --sf-fs-14-5:14.5px; --sf-fs-15:15px;
  --sf-fs-15-5:15.5px; --sf-fs-16-5:16.5px; --sf-fs-17:17px; --sf-fs-17-5:17.5px; --sf-fs-19:19px;
  --sf-fs-19-5:19.5px; --sf-fs-52:52px;
  --sf-fs-hero:clamp(35px,4.9vw,57px); --sf-fs-h2:clamp(27px,3.4vw,39px);
  --sf-fs-cierre:clamp(26px,3.3vw,37px); --sf-fs-h2-split:clamp(25px,3vw,34px);
  --sf-fs-lead:clamp(17px,1.6vw,19.5px);
  /* La letra de código de la portada (la del sistema, sin JetBrains Mono). */
  --sf-mono-sistema:ui-monospace,'SF Mono',Menlo,monospace;

  /* ═══ Encargo 214 · FASE 0 · L4: familias C y G del portal ═══
     Los colores y los tamaños que /validar, /demo, /api y /trust traían escritos en su
     `<style>`, con el MISMO valor: acá se nombran y las reglas los piden por nombre.
     Tienen nombre de FUNCIÓN (`--sf-verbo-get`, `--sf-log-borde`, `--sf-erp`…), no de valor (manual, §9):
     unificarlos con la escala de arriba movería colores a la vista y se decide aparte (pregunta del PR). */
  --sf-drop-borde:#c9bfdc;
  --sf-fs-clamp-32px-5vw-48px:clamp(32px,5vw,48px);
  --sf-fs-18:18px;
  --sf-fs-26:26px;
  --sf-verbo-get:#2563eb;
  --sf-verbo-patch-texto:#4a3708;
  --sf-verbo-delete:#dc2626;
  --sf-curl-texto:#e8e4ee;
  --sf-codigo-cadena:#8fd6a8;
  --sf-noche:#1b1522;
  --sf-noche-2:#2a2135;
  --sf-erp:#0f5c8c;
  --sf-erp-50:#eaf3f9;
  --sf-erp-cab-fondo:#fafcfe;
  --sf-medalla-borde:#bbe6cc;
  --sf-medalla-texto:#0b6b35;
  --sf-log-borde:#332941;
  --sf-log-cab-texto:#b9afc7;
  --sf-log-cab-borde:#3a2f47;
  --sf-log-tenue:#8a7f99;
  --sf-llamada-borde:#372c46;
  --sf-llamada-fondo:#221a2c;
  --sf-verbo-post:#12a150;
  --sf-verbo-patch:#b7860b;
  --sf-camino-texto:#e4ddec;
  --sf-fs-11-5:11.5px;
  --sf-cod-ok-fondo:#0e3e24;
  --sf-cod-ok-texto:#6fdca0;
  --sf-cod-mal-fondo:#4a1220;
  --sf-cod-mal-texto:#f5a3b5;
  --sf-llamada-texto:#cfc6da;
  --sf-codigo-clave:#c3a6d6;
  --sf-codigo-numero:#f0b76b;
  --sf-log-vacio:#7e7290;
  --sf-humano-borde:#4a3c5c;
  --sf-humano-fondo:#241c2e;
  --sf-humano-enlace:#c9a6e0;
  --sf-falla-borde:#f3c3e0;
  --sf-fs-16:16px;
  --sf-fs-20:20px;
  /* Encargo 215, tokens nombrados por función, no por valor (ver el final de la hoja). */
  --sf-fs-evaluar-puerta-titulo:22px;
  --sf-fs-codigo-en-linea:.88em;
  --sf-r-resumen:6px;
}

/* ═══ El botón (`sf-btn`) ═══
   Por omisión es el SECUNDARIO —fondo `--sf-paper`, borde `--sf-line`, texto
   `--sf-ink`—, de `.btn-s` de index.html/operador.html/firmar.html. El tamaño
   normal —min-height 40px, 14px, peso 600, padding 9.5px 16px— es `.btn` de
   index.html/operador.html; `.sf-chico` es `.btn.chico` de esas mismas dos
   (32px, 13px, padding 6px 11px); `.sf-grande` es el botón de sitio.html y
   validar.html (44px, 15px, padding 11px 20px): «44 px como mínimo en el
   firmante, que se usa en un teléfono» (§4).
   `.sf-principal` NO fija blanco sobre violeta a mano: `--brand`, `--brand-600`
   y `--brand-text` las escribe `tema.js` en tiempo de ejecución con la marca de
   la instalación (o `consola.js`/`firmar.js` con la de una empresa), y
   `--brand-text` es el color —blanco u oscuro— que MÁS CONTRASTA con esa
   marca: puede no ser blanco. `--sf-*` es sólo la omisión del producto, la que
   mide la prueba de contraste. `.sf-peligro` es `.btn-d`, rellena en rojo.
   `.sf-fantasma` no tiene una única página de origen: junta el patrón «sin
   fondo ni borde» que ya usaban sueltos `aside .pie button` y `.mas-boton` de
   index.html, con el hover en `--sf-soft` que ya usa `.sf-menu-boton`. */
.sf-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:40px;margin:0;padding:9.5px 16px;
  border:1px solid var(--sf-line);border-radius:var(--sf-r);
  background:var(--sf-paper);color:var(--sf-ink);
  font:inherit;font-size:14px;font-weight:600;line-height:1.2;white-space:nowrap;
  text-decoration:none;cursor:pointer;transition:border-color .15s,color .15s,background-color .15s}
.sf-btn:hover{border-color:var(--brand,var(--sf-brand))}
.sf-btn:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-btn:disabled,.sf-btn[aria-disabled="true"]{opacity:.5;cursor:default}

.sf-btn.sf-principal{border-color:transparent;background:var(--brand,var(--sf-brand));color:var(--brand-text,#fff)}
.sf-btn.sf-principal:hover{background:var(--brand-600,var(--sf-brand-600))}

.sf-btn.sf-fantasma{border-color:transparent;background:none;color:var(--sf-ink)}
.sf-btn.sf-fantasma:hover{background:var(--sf-soft)}

.sf-btn.sf-peligro{border-color:transparent;background:var(--sf-bad);color:#fff}
.sf-btn.sf-peligro:hover{filter:brightness(1.08)}

.sf-btn.sf-chico{min-height:32px;padding:6px 11px;font-size:13px}
.sf-btn.sf-grande{min-height:44px;padding:11px 20px;font-size:15px}

/* ═══ El campo (`sf-field`) ═══
   El rótulo es `label.campo` de index.html (13px, peso 600); el control
   —`input`, `select`, `textarea`, DENTRO de `.sf-field`— es
   `input,select,textarea` de operador.html (padding 10px 12px, borde
   `--sf-line`, radio `--sf-r`), con el foco de esa misma consola
   (`input:focus,select:focus{outline:2px solid var(--brand-600);
   outline-offset:-1px}`, acá en `:focus-visible`). `.sf-ayuda` y `.sf-fallo`
   son el texto de abajo; un control con `aria-invalid="true"` lleva el borde
   de `--sf-bad`, y eso alcanza como marca de error sin repetir el color en el
   fondo. */
.sf-field{display:block}
.sf-field + .sf-field{margin-block-start:16px}
.sf-field > label{display:block;margin-block-end:6px;color:var(--sf-ink);font-size:13px;font-weight:600}
.sf-field input,.sf-field select,.sf-field textarea{
  box-sizing:border-box;width:100%;margin:0;padding:10px 12px;
  border:1px solid var(--sf-line);border-radius:var(--sf-r);
  background:var(--sf-paper);color:var(--sf-ink);font:inherit;font-size:14px}
.sf-field textarea{resize:vertical}
.sf-field input:focus-visible,.sf-field select:focus-visible,.sf-field textarea:focus-visible{
  outline:2px solid var(--brand-600,var(--sf-brand-600));outline-offset:-1px}
.sf-field input[aria-invalid="true"],.sf-field select[aria-invalid="true"],.sf-field textarea[aria-invalid="true"]{
  border-color:var(--sf-bad)}
.sf-field input:disabled,.sf-field select:disabled,.sf-field textarea:disabled{opacity:.6;cursor:default}
/* En el teléfono, 16px: con menos, Safari de iOS agranda la página al tocar
   el campo. El acceso y la demo se usan en un teléfono (medido el 25-09 al
   migrar entrar.html, cuyos campos ya estaban en 16px). */
@media (max-width:640px){.sf-field input,.sf-field select,.sf-field textarea{font-size:16px}}
.sf-ayuda{margin-block-start:6px;color:var(--sf-mut);font-size:13px}
.sf-fallo{margin-block-start:6px;color:var(--sf-bad);font-size:13px}

/* ═══ La tarjeta (`sf-card`) ═══
   Fondo, borde y radio grande, como el `section` del laboratorio (16px) y
   `.card` de validar.html (padding 18px 20px) y de sitio.html (que ya
   arrancaba en `var(--r)`). Ninguna de las tres traía sombra en reposo —
   sitio.html sólo le pone una al pasar el mouse—: la de acá es una decisión
   nueva, con la sombra que ya existe en la hoja (`--sf-sombra-1`, la del
   menú) y no una inventada. */
.sf-card{box-sizing:border-box;background:var(--sf-paper);border:1px solid var(--sf-line);
  border-radius:var(--sf-r-l);padding:20px 24px;box-shadow:var(--sf-sombra-1)}
/* Una PILA de tarjetas: dos seguidas no se tocan. Las tres páginas de donde
   sale el componente las separaban a mano (el laboratorio 20px, confianza
   16px, validar 12px), y al pasar a `sf-card` quedaron pegadas —0 px medido
   en el laboratorio el 25-09—. La separación va en el CONTENEDOR que apila
   (`class="sf-pila"`) y no en `.sf-card + .sf-card` suelto: en una grilla
   —las tres tarjetas de api.html, las de la portada— ese margen bajaba 16px a
   todas menos la primera y las desalineaba. */
.sf-pila > .sf-card + .sf-card{margin-block-start:16px}
/* La tarjeta que se levanta al pasar el mouse (`sf-card sf-levanta`): la de
   la portada, que era `.cols .sf-card:hover` en su `<style>` hasta el
   26-09-2026, acá para que las tarjetas de recursos del recorrido reaccionen
   igual. Con el teclado, lo mismo: `:focus-within`, cuando se enfoca el
   enlace de adentro (en la portada ninguna tiene algo enfocable).
   ⚠ En la portada el `transform` lo pisa `.js .rev.on{transform:none}`, de su
   propio `<style>`: mismo peso y declarado después. Ahí la tarjeta cambia
   sombra y borde pero no sube, desde antes de esta mudanza; la mudanza no lo
   cambia. */
.sf-card.sf-levanta{transition:.18s}
.sf-card.sf-levanta:hover,.sf-card.sf-levanta:focus-within{transform:translateY(-3px);box-shadow:var(--sf-sombra-flota);border-color:#d6e2ee}

/* ═══ La pastilla (`sf-ico`) ═══
   El cuadrado de 46 px con el radio de la casa que encabeza una tarjeta, con
   un ícono o con un número: `.ico` de la portada, mudada acá el 26-09-2026
   para que el recorrido numere sus tarjetas con la MISMA regla y no con una
   copia (pedido de Walter, con capturas). Por omisión lleva el tinte de la
   marca; `.sf-acento`, el del acento —los números de «Deployment context» y
   los del recorrido—; `.sf-ambar`, el ámbar del campo que se completa.
   El número va en tinta: en la portada es el color que ya heredaba, y en una
   maqueta con otro color de texto (el recorrido del hero del tour) lo fija;
   la letra es la de donde está puesta. Los 18 px de abajo son el aire hasta el
   título de la tarjeta; puesta en una fila, quien la pone los anula. */
.sf-ico{width:46px;height:46px;border-radius:var(--sf-r);display:grid;place-items:center;margin-bottom:18px;
  background:var(--brand-50,var(--sf-brand-50));color:var(--sf-ink)}
.sf-ico.sf-acento{background:var(--acc-50,var(--sf-acc-50))}
.sf-ico.sf-ambar{background:#fef6e7}
.sf-ico svg{width:23px;height:23px;stroke:var(--brand,var(--sf-brand));fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.sf-ico.sf-acento svg{stroke:var(--acc-700,var(--sf-acc-700))}
.sf-ico.sf-ambar svg{stroke:#b07d0a}

/* ═══ La maqueta: el producto dibujado en HTML ═══
   Las piezas con que la portada dibuja el producto en su hero —la barra de la
   ventana, el globo que flota encima, el evento del registro de evidencia—,
   mudadas acá el 26-09-2026 para que el recorrido dibuje su bloque de la API
   con las mismas. Lo que es de cada página —dónde flota un globo, cuánto se
   inclina el documento— sigue en la página. */

/* La barra de la ventana (`sf-ventana`): tres puntos y el título. Es
   `.doc-top` de la portada, con su `.dot`; la regla de su título alcanzaba
   también a los puntos (6 px de margen a cada uno), y así se siguen dibujando. */
.sf-ventana{display:flex;align-items:center;gap:9px;padding-bottom:16px;border-bottom:1px solid var(--sf-line);margin-bottom:20px}
.sf-ventana-punto{width:9px;height:9px;border-radius:50%;background:var(--sf-line)}
.sf-ventana span{margin-left:6px;font-size:12.5px;color:var(--sf-mut);font-weight:600}

/* El globo que flota sobre una maqueta (`sf-card sf-flota`): `.flot` de la
   portada sin su posición, que es de la página. Su título va en
   `sf-flota-titulo` (era `.flot h4`, con el interlineado y el margen que le
   daba el `h4` de la portada, escritos acá para que valgan en cualquier
   etiqueta). */
.sf-card.sf-flota{padding:14px 16px;box-shadow:var(--sf-sombra-flota);font-size:13px}
.sf-flota-titulo{margin:0 0 11px;color:var(--sf-mut);font-size:11px;font-weight:700;line-height:1.12;letter-spacing:.1em;text-transform:uppercase}

/* Un evento del registro de evidencia (`sf-evento`): el punto del acento
   (`sf-evento-punto`), el hecho en tinta y su detalle debajo. Es `.ev` de la
   portada. */
.sf-evento{display:flex;gap:9px;padding:5px 0;font-size:12px;color:var(--sf-mut);align-items:flex-start}
.sf-evento b{color:var(--sf-ink);font-weight:600;display:block;font-size:12.5px}
.sf-evento-punto{width:7px;height:7px;border-radius:50%;background:var(--acc,var(--sf-acc));margin-top:6px;flex:none}

/* ═══ La tabla (`sf-table`) ═══
   Ancho completo y el padding/borde de operador.html (th y td, 12px 18px); el
   th hereda además su mayúscula y su `--sf-mut` (11,5px: la especificación
   habla de «12–12.5px», pero lo medido en operador.html es 11,5px, y se usa
   lo medido). `.sf-table-envoltura` hace lo que el
   `@media(max-width:760px){main table{display:block;overflow-x:auto}}` de esa
   página, pero sin seleccionar `table` suelto —la guarda de esta hoja lo
   prohíbe—: un `<div class="sf-table-envoltura">` alrededor, que además no
   depende de un ancho de pantalla fijo: se activa apenas la tabla no entra,
   en cualquier columna angosta. */
.sf-table-envoltura{width:100%;overflow-x:auto}
/* Fila apagada (webhook en pausa, token vencido o revocado): se distingue por el fondo, no por `opacity`,
   que bajaba el texto a 2,3:1 (A2). */
.sf-fila-apagada td{background:var(--sf-soft)}
.sf-table{width:100%;border-collapse:collapse}
.sf-table th{padding:12px 18px;border-bottom:1px solid var(--sf-line);background:var(--sf-soft);
  color:var(--sf-mut);font-size:11.5px;font-weight:700;text-align:start;text-transform:uppercase;letter-spacing:.07em}
.sf-table td{padding:12px 18px;border-bottom:1px solid var(--sf-line);font-size:14.5px;vertical-align:middle}
.sf-table tr:last-child td{border-bottom:0}
/* La tabla PLANA (`sf-table-plana`), dentro de una tarjeta con relleno propio
   (01-10-2026, encargo 64: «Ways you prove who you are» en «Who you are»): sin
   el fondo del encabezado ni el relleno de los costados, que ya pone la
   tarjeta; la última columna (las acciones) contra el borde derecho, salvo
   donde la tabla ya es una pila de tarjetas (899 px, el quiebre de
   `sf-solo-ancho`), donde las acciones van a la izquierda como en las demás. */
.sf-table-plana th{background:none;padding:10px 12px 8px 0;white-space:nowrap}
.sf-table-plana td{padding:12px 12px 12px 0}
.sf-table-plana th:last-child,.sf-table-plana td:last-child{padding-inline-end:0;text-align:end}
@media (max-width:899px){.sf-table-plana td:last-child{text-align:start}}

/* ═══ La píldora (`sf-pill`) ═══
   12px, peso 600, padding 3px 10px, radio de píldora: `.pill` de index.html/
   operador.html. Neutra por omisión: ninguna de las dos páginas usa `.pill`
   sin un modificador semántico, así que el aspecto neutro sale del más
   parecido, `.pill.org` de index.html (fondo `--sf-soft`, texto `--sf-ink`).
   El margen entre píldoras vecinas (`margin-right:5px` en el original) queda
   afuera: es cosa de quien las use (`gap`), no del componente. */
.sf-pill{box-sizing:border-box;display:inline-flex;align-items:center;
  padding:3px 10px;border-radius:var(--sf-r-pill);
  background:var(--sf-soft);color:var(--sf-ink);font-size:12px;font-weight:600;line-height:1.4;white-space:nowrap}
.sf-pill.sf-ok{background:var(--sf-ok-50);color:var(--sf-ok)}
.sf-pill.sf-bad{background:var(--sf-bad-50);color:var(--sf-bad)}
.sf-pill.sf-warn{background:var(--sf-warn-50);color:var(--sf-warn)}
.sf-pill.sf-nota{background:var(--sf-info-50);color:var(--sf-info)}
/* La grande: el resumen del validador (14px, padding 5px 12px), donde la
   píldora ES el resultado y no una etiqueta de fila. Lleva un borde de 1px
   —transparente en las de estado— para que todas midan lo mismo; toma el
   interlineado de donde está (34px en la fila del resumen, 30px en el
   encabezado de un acordeón, como antes de migrar); se parte en renglones,
   porque en el validador es una oración entera («Every signature verifies and
   nothing changed after signing», 397px) y con el `nowrap` de la chica la
   página medía 417px de ancho en un teléfono de 375; y la neutra
   va blanca con contorno: se apoya sobre el fondo suave de la página, donde una
   neutra sin borde no se distingue (25-09, al migrar validar.html). */
.sf-pill.sf-grande{padding:5px 12px;font-size:14px;line-height:inherit;white-space:normal;border:1px solid transparent}
.sf-pill.sf-grande:not(.sf-ok):not(.sf-bad):not(.sf-warn):not(.sf-nota){background:var(--sf-paper);border-color:var(--sf-line)}
/* La que envuelve (`sf-envuelve`): una píldora cuyo texto lleva datos de largo
   libre —la del aviso de Documents, «The notice did not reach Ivan Petrov, Julia
   Nakamura, …», con el nombre de cada destinatario sin aviso—. `.sf-pill` va en
   `nowrap` a propósito (es una etiqueta corta), y con cuatro nombres esa píldora
   medía 459 px dentro de una tarjeta de 312 y sobresalía 132 px (medido a 375,
   29-09-2026, la vista de teléfono de la lista de Documents). Con esta clase
   envuelve en renglones, parte un nombre sin espacios antes que salirse, y su
   tope es el ancho de donde está (`100%`, la tarjeta). Es un modificador propio
   de la píldora y no una regla de `.sf-docs`: esa hoja sólo puede tener reglas
   de `sf-docs` desde 900 px (test/la_lista_de_documents_entra.test.ts), y desde
   900 px la píldora del aviso ya tiene su tope (`min(16rem,100%)`, más
   específico, en el bloque de `.sf-docs`). Radio de 14 px: con el de píldora
   entera, una de dos renglones queda como una cápsula gorda.
   Guarda: test/el_titulo_de_documents_no_se_aprieta.test.ts. */
.sf-pill.sf-envuelve{white-space:normal;max-width:100%;overflow-wrap:anywhere;border-radius:14px}
/* La chica (`sf-chica`): una etiqueta al lado de un nombre en una fila de tabla —las
   etiquetas del conector en la pestaña Catalog de Providers, encargo 119b—, donde la de
   12px compite con el nombre. La misma medida que ya usan la matriz y «fuera». */
.sf-pill.sf-chica{padding:1px 8px;font-size:11.5px}

/* ═══ El mensaje (`sf-msg`) ═══
   13.5px, padding 11px 13px, radio `--sf-r`: `.msg` de entrar.html,
   firmar.html, index.html y operador.html, igual en las cuatro. Las cuatro
   suman además un borde de un tercer tono (p.ej. `#abefc6` en `.msg.ok`) que
   no tiene un token propio en esta escala —el §3 no lo pide— y se dejó
   afuera: fondo y texto ya pasan AA (medido en la prueba de esta hoja). */
.sf-msg{margin-block-start:16px;padding:11px 13px;border-radius:var(--sf-r);font-size:13.5px}
.sf-msg.sf-ok{background:var(--sf-ok-50);color:var(--sf-ok)}
.sf-msg.sf-bad{background:var(--sf-bad-50);color:var(--sf-bad)}
.sf-msg.sf-warn{background:var(--sf-warn-50);color:var(--sf-warn)}
.sf-msg.sf-nota{background:var(--sf-info-50);color:var(--sf-info)}
/* ENV-1 (#6): el aviso de la lista de documentos lleva su «×» de 44 px (el texto, a la izquierda). */
.sf-msg.sf-con-cierre{display:flex;align-items:center;justify-content:space-between;gap:8px}
.sf-msg-texto{flex:1 1 auto;min-width:0}
.sf-msg-cierre{flex:none;box-sizing:border-box;min-width:44px;min-height:44px;margin:-11px -13px -11px 0;padding:0;border:0;background:none;color:inherit;font:inherit;font-size:22px;line-height:1;cursor:pointer}

/* ═══ El archivo (`sf-archivo`) ═══
   La tarjeta de UN archivo que se está revisando: en una fila el ícono
   (`sf-ico`, sin su margen de abajo), el nombre con el tamaño debajo y el
   estado a la derecha (una píldora, o el `sf-spinner` con su texto); debajo,
   separado por una línea, el pie con la huella y las acciones. Va sobre
   `sf-card` (`class="sf-card sf-archivo"`). En un teléfono el estado baja a
   su propia línea, para que un nombre largo no lo empuje afuera. Nació el
   29-09-2026 en el validador, donde reemplaza al recuadro de subida. */
.sf-archivo{padding:16px 20px}
.sf-archivo-fila{display:flex;align-items:center;gap:14px}
.sf-archivo .sf-ico{margin:0;flex:none}
.sf-archivo-datos{flex:1;min-width:0}
.sf-archivo-nombre{display:block;font-weight:700;overflow-wrap:anywhere}
.sf-archivo-estado{flex:none;display:inline-flex;align-items:center;gap:9px;max-width:100%;color:var(--sf-mut);font-size:14px;font-weight:600}
.sf-archivo-pie{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin-top:14px;padding-top:12px;
  border-top:1px solid var(--sf-line);font-size:13px;color:var(--sf-mut)}
.sf-archivo-pie code{color:var(--sf-ink)}
.sf-archivo-pie .sf-archivo-otro{margin-inline-start:auto}
@media (max-width:640px){
  .sf-archivo-fila{flex-wrap:wrap}
  .sf-archivo-estado{flex-basis:100%}
  .sf-archivo-pie .sf-archivo-otro{margin-inline-start:0}
}

/* ═══ Las filas (`sf-filas`) ═══
   Una lista de renglones de una línea —el nombre a la izquierda, una píldora
   o un valor a la derecha— separados por un hilo. Es lo que el validador
   muestra por proveedor, justo debajo de la tarjeta del archivo. */
.sf-filas{list-style:none;margin:0;padding:0;font-size:14.5px}
.sf-filas > li{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 0;border-top:1px solid var(--sf-line)}
.sf-filas > li:first-child{border-top:0}
.sf-filas-nombre{min-width:0;overflow-wrap:anywhere}

/* ═══ Las dos cajas de alcance (`sf-alcance`) ═══
   «Qué comprueba» (verde) y «qué no» (rojo), una al lado de la otra y apiladas
   en un teléfono. Cada caja es un `div` con su rótulo en `b`; `sf-si` y
   `sf-no` le dan el color al rótulo. Es la letra chica del validador. */
.sf-alcance{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.sf-alcance > div{border:1px solid var(--sf-line);border-radius:var(--sf-r);padding:14px 16px;background:var(--sf-paper);font-size:14px}
.sf-alcance b{display:block;margin-bottom:4px;font-size:13px;letter-spacing:.04em;text-transform:uppercase}
.sf-alcance .sf-si b{color:var(--sf-ok)}
.sf-alcance .sf-no b{color:var(--sf-bad)}
@media (max-width:640px){.sf-alcance{grid-template-columns:1fr}}

/* ═══ El giro (`sf-spinner`) ═══
   El aro de 16 px que acompaña a un «Checking…»: lo que se está haciendo
   ahora y no tiene una cifra de avance (el validador, mientras analiza el
   archivo). Corre con la marca de la instalación (`--brand`). Con
   `prefers-reduced-motion` no gira —queda el aro quieto, y el texto de al
   lado dice lo mismo—. Nació el 29-09-2026 en el validador. */
@keyframes sf-gira{to{transform:rotate(360deg)}}
.sf-spinner{flex:none;display:inline-block;box-sizing:border-box;width:16px;height:16px;border-radius:50%;
  border:2px solid var(--sf-line);border-top-color:var(--brand,var(--sf-brand));animation:sf-gira .8s linear infinite}

/* ═══ Los estados (`sf-estado`) ═══
   El bloque vacío/cargando/error de una lista: centrado, `--sf-mut`, de
   `.vacio` de operador.html (padding 44px 24px, 14.5px). `.sf-vacio` y
   `.sf-cargando` se dibujan igual —«el mismo dibujo en las tres consolas»,
   §4—; `.sf-error` es la única que cambia, a `--sf-bad`. `.sf-cargando` no
   anima por omisión: el pulso de acá es opcional y se apaga solo con
   `prefers-reduced-motion` (al final de esta hoja). */
.sf-estado{box-sizing:border-box;padding:44px 24px;text-align:center;color:var(--sf-mut);font-size:14.5px}
.sf-estado.sf-vacio{color:var(--sf-mut)}
.sf-estado.sf-error{color:var(--sf-bad)}
@keyframes sf-pulso{0%,100%{opacity:1}50%{opacity:.6}}
.sf-estado.sf-cargando{animation:sf-pulso 1.4s ease-in-out infinite}

/* ═══ La barra de búsqueda de una lista (`sf-barra-busqueda`) ═══
   Los campos que filtran una lista larga —texto, menús, fechas— en una grilla
   de cuatro columnas que baja a dos en una pantalla angosta; el buscador
   (`.sf-ancho`) ocupa dos columnas (toda la fila en el teléfono) y los
   botones (`.sf-botones`) van abajo a la derecha. `.sf-pie-lista` es lo que
   va debajo de la tabla: cuántos renglones hay y «Load more». La estrenó el
   Audit log del operador (encargo 107); vive acá y no en el <style> de la
   página para que el trinquete de CSS propio no crezca. */
.sf-barra-busqueda{display:grid;gap:12px 14px;grid-template-columns:repeat(4,minmax(0,1fr));align-items:start}
.sf-barra-busqueda label{margin:0 0 6px}
.sf-barra-busqueda .sf-ancho{grid-column:span 2;min-width:0}
.sf-barra-busqueda .sf-botones{align-self:end;display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end}
.sf-pie-lista{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;padding:12px 18px}
.sf-pie-lista:empty{display:none}
@media (max-width:760px){
  .sf-barra-busqueda{grid-template-columns:repeat(2,minmax(0,1fr))}
  .sf-barra-busqueda .sf-ancho{grid-column:1/-1}
}
@media (max-width:420px){
  .sf-barra-busqueda .sf-botones{grid-column:1/-1;justify-content:flex-start}
}

/* ═══ El ● de la vidriera ═══
   Lo que este entorno no tiene va gris, con este punto y su motivo. El motivo
   lo lleva el punto en `data-porque` (y en `aria-label`); `componentes.js` lo
   muestra en un globo al pasar el ratón, al enfocarlo con Tab y al tocarlo
   con el dedo. */
.vd-punto{display:inline-block;flex:none;width:8px;height:8px;border-radius:50%;
  background:var(--amber,var(--sf-dot));vertical-align:middle}
.vd-punto[data-porque]{cursor:help}
/* Con `componentes.js` andando, el globo de CSS de cada página se apaga: el
   globo común es uno solo, no se corta contra el borde de una tabla con
   desplazamiento y se abre también con el dedo. Sin el script, el de CSS sigue
   siendo el respaldo. */
.sf-js .vd-punto[data-porque]:hover::after,
.sf-js .vd-punto[data-porque]:focus-visible::after{content:none;display:none}

/* ⚠ El globo y la lista del menú se muestran en la capa de arriba del
   navegador (`popover`, ver componentes.js): `inset:auto` y `margin:0` le sacan
   el centrado que el navegador le pone por omisión a un popover. */
.sf-pop{position:fixed;z-index:1001;inset:auto;top:0;left:0;margin:0;border:0;box-sizing:border-box;overflow:visible;
  max-width:min(300px,calc(100vw - 24px));padding:8px 11px;border-radius:var(--sf-r-s);
  background:var(--sf-ink);color:#fff;box-shadow:var(--sf-sombra-menu);
  font-family:var(--sf-font);font-size:12.5px;font-weight:500;line-height:1.45;
  text-align:start;white-space:normal;pointer-events:none}
.sf-pop[hidden]{display:none}

/* ═══ El menú (`sf-menu`) ═══
   Un botón y una lista. La lista se dibuja `position:fixed` y la ubica
   `componentes.js` junto al botón: así no la recorta una tabla con
   desplazamiento horizontal, que es donde vive el «⋯» de cada fila. */
.sf-menu{position:relative;display:inline-flex;vertical-align:middle}
.sf-menu-boton{display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;
  min-width:32px;height:32px;margin:0;padding:0 8px;
  font:inherit;font-size:13px;font-weight:600;line-height:1;
  color:var(--sf-mut);background:var(--sf-paper);border:1px solid var(--sf-line);border-radius:var(--sf-r-s);
  cursor:pointer;transition:border-color .15s,color .15s,background-color .15s}
.sf-menu-boton:hover{color:var(--sf-ink);border-color:var(--brand,var(--sf-brand))}
.sf-menu-boton[aria-expanded="true"]{color:var(--sf-ink);background:var(--sf-soft);border-color:var(--sf-line)}
.sf-menu-boton:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-menu-boton svg{flex:none;display:block}

.sf-menu-lista{position:fixed;z-index:1000;inset:auto;top:0;left:0;box-sizing:border-box;
  min-width:200px;max-width:min(340px,calc(100vw - 16px));max-height:min(440px,calc(100vh - 16px));overflow:auto;
  margin:0;padding:6px;background:var(--sf-paper);color:var(--sf-ink);
  border:1px solid var(--sf-line);border-radius:var(--sf-r);box-shadow:var(--sf-sombra-menu);
  font-family:var(--sf-font);font-size:14px;font-weight:500;line-height:1.35;text-align:start;
  text-transform:none;letter-spacing:normal;white-space:normal}
.sf-menu-lista[hidden]{display:none}
/* ⚠ Las opciones del menú llevan `:not(#sf-x)`, que les suma el peso de un id.
   Adentro del menú van LOS MISMOS botones que la fila tenía (`btn btn-s chico`,
   con sus `data-` y sus manejadores), y cada pantalla tiene reglas para esos
   botones: `.btn.chico` pesa dos clases, y en el teléfono la consola de empresa
   estira todo `.btn` de la última celda de una tarjeta
   (`.tarjetas tr td:last-child .btn`, tres clases y dos elementos). Con menos
   peso que ésa, las opciones se dibujaban una al lado de la otra y centradas.
   Una opción de menú se ve igual en todas las pantallas: ése es el punto. */
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > *{display:flex;align-items:center;justify-content:flex-start;gap:10px;
  box-sizing:border-box;flex:none;width:100%;min-width:0;min-height:36px;margin:0;padding:8px 10px;
  border:0;border-radius:var(--sf-r-s);background:none;box-shadow:none;
  color:var(--sf-ink);font:inherit;font-size:14px;font-weight:500;line-height:1.35;
  text-align:start;text-decoration:none;text-transform:none;letter-spacing:normal;white-space:normal;
  opacity:1;cursor:pointer}
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > *:hover,
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > *:focus-visible{background:var(--sf-soft);color:var(--sf-ink);text-decoration:none;outline:none}
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > *:focus-visible{box-shadow:inset 0 0 0 2px var(--brand,var(--sf-brand))}
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > [hidden]{display:none}
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > :disabled,
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > [aria-disabled="true"]{color:var(--sf-mut);background:none;cursor:default}
/* Lo que borra o corta va en rojo también adentro del menú. */
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > .btn-d,
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > .sf-peligro{color:var(--danger,var(--sf-bad))}
/* ENV-1 (#2): por dónde se invita a un firmante, en su fila (consola.js, `lineaDelCanalDeAviso`). */
.sf-canal-aviso{font-size:12px;color:var(--sf-mut)}

/* ⚠ `width:auto` (ENV-1 #3): la raya heredaba `width:100%` de la regla de arriba
   y sumaba sus 4 px de margen a cada lado: 100% + 8 px dentro de una lista con
   `overflow:auto` es una barra de desplazamiento horizontal en cada menú con
   raya (medido en el «⋯» del firmante a 1336 y a 375). */
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > .sf-menu-sep{min-height:0;height:1px;width:auto;margin:6px 4px;padding:0;
  background:var(--sf-line);cursor:default;pointer-events:none}
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > * svg{flex:none;width:16px;height:16px}
/* Un rótulo adentro de un menú (`sf-menu-rotulo`, 28-09-2026): el título de la
   lista o el nombre de un grupo de opciones. No es una opción —el teclado lo
   saltea y tocarlo no cierra el menú (componentes.js)—, así que no se resalta
   al pasar el ratón. En la pantalla lleva `role="none"`. */
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > .sf-menu-rotulo{display:block;min-height:0;margin:0;padding:10px 10px 4px;
  background:none;color:var(--sf-mut);font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  cursor:default}
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > .sf-menu-rotulo:hover{background:none;color:var(--sf-mut)}
/* La cabecera de un menú (`sf-menu-cabeza`, con `sf-menu-rotulo`): un título y,
   debajo, la línea que lo sitúa —«Your accounts» y «Signed in as …» en el
   selector de cuenta de la consola—. Va después del rótulo y le cambia la letra. */
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > .sf-menu-cabeza{padding:8px 10px 6px;color:var(--sf-ink);
  font-size:13.5px;font-weight:700;letter-spacing:normal;text-transform:none}
.sf-menu-cabeza > b{display:block;font-weight:700}
.sf-menu-cabeza > span{display:block;margin-top:2px;color:var(--sf-mut);font-size:12.5px;font-weight:500;overflow-wrap:anywhere}
/* Una opción con su marca y sus renglones (28-09-2026): la ✓ de la vigente a la
   izquierda (`sf-menu-marca`), el nombre (`sf-menu-texto > b`) y, debajo, lo que
   conviene saber antes de elegirla (`sf-menu-nota`). La vigente lleva
   `aria-current` y `aria-disabled` —no se elige—, pero no se apaga: se lee como
   la de ahora. */
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > [aria-current="true"][aria-disabled="true"]{color:var(--sf-ink);background:none;cursor:default}
.sf-menu-lista .sf-menu-marca{flex:none;align-self:flex-start;width:16px;color:var(--brand,var(--sf-brand));font-weight:700;visibility:hidden}
.sf-menu-lista [aria-current="true"] > .sf-menu-marca{visibility:visible}
.sf-menu-lista .sf-menu-texto{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.sf-menu-lista .sf-menu-texto > b{font-weight:600;overflow-wrap:anywhere}
.sf-menu-lista [aria-current="true"] .sf-menu-texto > b{font-weight:700}
.sf-menu-lista .sf-menu-nota{display:block;color:var(--sf-mut);font-size:12.5px;font-weight:500;overflow-wrap:anywhere}
/* El dibujo de una nota (el candado): más chico que el de una opción, que pesa un id. */
.sf-menu > .sf-menu-lista[role="menu"]:not(#sf-x) > * .sf-menu-nota > svg{display:inline;width:12px;height:12px;
  margin-inline-end:5px;vertical-align:-1px}

/* ═══ El bloque que abre un menú (`sf-bloque-menu`, 28-09-2026) ═══
   Un bloque de texto —la clase y el nombre de la cuenta, arriba del lateral de
   la consola— que, cuando hay algo que elegir, es entero el botón de un menú:
   el `sf-menu` va adentro, del tamaño del bloque y DEBAJO del texto, y el texto
   deja pasar el clic (`sf-con-menu`, que pone la pantalla cuando muestra el
   menú, y que además le hace lugar a la flecha). Así el texto sigue siendo el
   nodo que pinta quien lo pinta, y el botón toma de él su nombre accesible
   (`aria-labelledby`). Sin menú, el bloque es texto. La flecha y el resaltado
   salen de `currentColor`: sirven igual sobre el lateral oscuro que sobre una
   hoja clara. El radio lo pone la pantalla, y el botón lo hereda. */
.sf-bloque-menu{position:relative}
.sf-bloque-menu > *{position:relative;z-index:1}
.sf-bloque-menu > .sf-menu{position:absolute;inset:0;z-index:0;display:block;border-radius:inherit}
.sf-bloque-menu > .sf-menu[hidden]{display:none}
.sf-bloque-menu.sf-con-menu > :not(.sf-menu){pointer-events:none;padding-inline-end:28px}
.sf-bloque-menu > .sf-menu > .sf-menu-boton{width:100%;height:100%;min-width:0;justify-content:flex-end;padding:0 12px;
  color:inherit;background:transparent;border:0;border-radius:inherit}
.sf-bloque-menu > .sf-menu > .sf-menu-boton:hover,
.sf-bloque-menu > .sf-menu > .sf-menu-boton[aria-expanded="true"]{color:inherit;border-color:transparent;
  background:color-mix(in srgb,currentColor 11%,transparent)}
.sf-bloque-menu > .sf-menu > .sf-menu-boton:focus-visible{outline:2px solid currentColor;outline-offset:1px}
.sf-bloque-menu .sf-menu-flecha{width:16px;height:16px;opacity:.85;transition:transform .15s}
.sf-bloque-menu [aria-expanded="true"] .sf-menu-flecha{transform:rotate(180deg)}

/* ═══ Las acciones de una fila (`sf-acciones`) ═══
   Una acción a la vista y el resto en el «⋯». Nunca se parte en dos
   renglones: una fila tiene el alto de su contenido, no el de sus botones. */
.sf-acciones{display:flex;align-items:center;justify-content:flex-end;gap:6px;flex-wrap:nowrap;white-space:nowrap}
.sf-acciones > *{flex:none;margin-top:0;margin-bottom:0}

/* ═══ El selector de idioma (`sf-idioma`) ═══
   El idioma que se está mostrando y un menú con los demás. Hereda el color de
   donde está puesto, así que sirve igual en la barra clara del sitio y en el
   lateral oscuro de la consola. */
.sf-idioma .sf-idioma-boton{height:30px;padding:0 9px 0 8px;gap:5px;border-radius:var(--sf-r-pill);
  color:inherit;background:transparent;border:1px solid var(--sf-line);
  border-color:color-mix(in srgb,currentColor 24%,transparent);font-size:12.5px;font-weight:700;letter-spacing:.02em}
.sf-idioma .sf-idioma-boton:hover{color:inherit;border-color:currentColor;text-decoration:none}
.sf-idioma .sf-idioma-actual{color:inherit;font-size:inherit;font-weight:inherit}
.sf-idioma .sf-idioma-boton[aria-expanded="true"]{color:inherit;border-color:currentColor;
  background:color-mix(in srgb,currentColor 10%,transparent)}
.sf-idioma .sf-idioma-boton .sf-idioma-globo{width:15px;height:15px;opacity:.85}
.sf-idioma .sf-idioma-boton .sf-idioma-flecha{width:10px;height:10px;opacity:.7;transition:transform .15s}
.sf-idioma .sf-idioma-boton[aria-expanded="true"] .sf-idioma-flecha{transform:rotate(180deg)}
.sf-idioma-lista{min-width:220px}
.sf-idioma-lista .sf-idioma-marca{flex:none;width:16px;color:var(--brand,var(--sf-brand));font-size:14px;font-weight:700;visibility:hidden}
.sf-idioma-lista [aria-checked="true"] .sf-idioma-marca{visibility:visible}
.sf-idioma-lista .sf-idioma-texto{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;color:inherit;font-size:inherit}
.sf-idioma-lista .sf-idioma-nombre{color:inherit;font-size:14px;font-weight:500}
.sf-idioma-lista [aria-checked="true"] .sf-idioma-nombre{font-weight:700}
.sf-idioma-lista .sf-idioma-cod{flex:none;color:var(--sf-mut);font-size:11.5px;font-weight:700;letter-spacing:.04em}
.sf-idioma-lista .vd-punto{margin-right:2px}

/* ═══ El acordeón (`sf-acordeon`) ═══
   Un `<details>` de verdad: se abre sin script, con el teclado y con el
   lector de pantalla. El título va en `.sf-acordeon-titulo` y, si hace falta,
   un resumen de una línea en `.sf-acordeon-resumen`, para saber qué hay
   adentro sin abrirlo. */
.sf-acordeon{margin:0 0 12px;border:1px solid var(--sf-line);border-radius:var(--sf-r);background:var(--sf-paper)}
.sf-acordeon > summary{display:flex;align-items:center;gap:12px;padding:14px 18px;border-radius:var(--sf-r);
  list-style:none;cursor:pointer;color:var(--sf-ink);font-size:15px;font-weight:650;line-height:1.3}
.sf-acordeon > summary::-webkit-details-marker{display:none}
.sf-acordeon > summary::after{content:"";flex:none;width:7px;height:7px;margin-inline-start:4px;
  border:solid var(--sf-mut);border-width:0 2px 2px 0;transform:translateY(-2px) rotate(45deg);transition:transform .15s}
.sf-acordeon[open] > summary::after{transform:translateY(2px) rotate(-135deg)}
.sf-acordeon > summary:hover{background:var(--sf-soft)}
.sf-acordeon > summary:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-acordeon[open] > summary{border-radius:var(--sf-r) var(--sf-r) 0 0}
.sf-acordeon-titulo{flex:1;min-width:0}
.sf-acordeon-resumen{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--sf-mut);font-size:13px;font-weight:400}
.sf-acordeon-cuerpo{padding:4px 18px 18px}
/* Adentro de una tarjeta: sin borde propio, sólo la línea que separa. */
.sf-acordeon.sf-plano{margin:0;border:0;border-top:1px solid var(--sf-line);border-radius:0;background:none}
.sf-acordeon.sf-plano > summary{padding:13px 2px;border-radius:0}
.sf-acordeon.sf-plano > .sf-acordeon-cuerpo{padding:2px 2px 16px}
@media (max-width:640px){
  .sf-acordeon > summary{padding:13px 14px}
  .sf-acordeon-cuerpo{padding:2px 14px 14px}
  .sf-acordeon-resumen{display:none}
}

/* ═══ Las pestañas (`sf-tabs`) ═══
   `role="tablist"` con botones `.sf-tab[role="tab"]` y paneles `.sf-panel`.
   En un teléfono la fila se desplaza de costado en vez de partirse. */
.sf-tabs{display:flex;gap:2px;margin:0 0 18px;border-bottom:1px solid var(--sf-line);overflow-x:auto;scrollbar-width:none}
.sf-tabs::-webkit-scrollbar{display:none}
/* Si la fila no entra (un teléfono), se desvanece del lado que sigue: se ve que
   hay más. La clase la pone componentes.js mirando el desborde. */
.sf-tabs.sf-tabs-sigue{-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent);
  mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent)}
[dir="rtl"] .sf-tabs.sf-tabs-sigue{-webkit-mask-image:linear-gradient(to left,#000 calc(100% - 32px),transparent);
  mask-image:linear-gradient(to left,#000 calc(100% - 32px),transparent)}
.sf-tab{flex:none;display:inline-flex;align-items:center;gap:6px;margin:0 0 -1px;padding:10px 14px;
  border:0;border-bottom:2px solid transparent;border-radius:var(--sf-r-s) var(--sf-r-s) 0 0;background:none;
  color:var(--sf-mut);font:inherit;font-size:14px;font-weight:600;white-space:nowrap;cursor:pointer}
.sf-tab:hover{color:var(--sf-ink);background:var(--sf-soft)}
.sf-tab[aria-selected="true"]{color:var(--sf-ink);border-bottom-color:var(--brand,var(--sf-brand))}
.sf-tab:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:-2px}
.sf-tab .sf-cuenta{padding:1px 7px;border-radius:var(--sf-r-pill);background:var(--sf-soft);color:var(--sf-mut);font-size:12px;font-weight:600}
.sf-panel[hidden]{display:none}
/* ⚠ FM1-D1 · `hidden` SIEMPRE esconde (excepción justificada a «todo selector cuelga de .sf-», con su lugar en
   `una_hoja_comun_para_todas_las_pantallas`). El `hidden` del navegador es un `display:none` de hoja de usuario y
   cualquier `display` propio de una clase le gana: `.firma-espera{display:flex}` dejó a la vista, sin esperar nada,
   el isotipo con «Stop waiting» del paso 3 de /firmar. Quien muestra algo lo hace quitando el atributo. */
[hidden]{display:none!important}
/* ⚠ Todo componente que fija su propio `display` le gana al `[hidden]` del
   navegador, que es sólo un `display:none` de hoja de usuario: una pestaña con
   `hidden` seguía a la vista. Lo vio el constructor de las vistas largas de la
   consola de empresa (25-09): Account esconde la pestaña cuyas secciones
   quedan todas ocultas. Cada componente con `display` propio respeta
   `hidden` acá. */
.sf-tab[hidden],.sf-tabs[hidden],.sf-acciones[hidden],.sf-menu[hidden],
.sf-menu-boton[hidden],.sf-info[hidden]{display:none}

/* ═══ El texto largo con «más» (`data-sf-mas`) ═══
   Una explicación se ve en un renglón (dos en un teléfono) y el resto se abre
   con «más». El botón lo pone `componentes.js`, y sólo si el texto de verdad
   no entra: un «más» que no abre nada es peor que no tenerlo.
   `data-sf-mas="2"` pide dos renglones. Si el fondo no es blanco, la página
   pone `--sf-mas-fondo` para que el «más» tape bien el final del renglón. */
.sf-mas{position:relative}
.sf-mas:not(.sf-mas-abierto){display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--sf-mas-lineas,1);overflow:hidden}
@media (max-width:640px){ .sf-mas:not([data-sf-mas="1"]){--sf-mas-lineas:2} }
.sf-mas-boton{margin:0;padding:0;border:0;background:none;font:inherit;font-weight:600;
  color:var(--brand,var(--sf-brand));text-decoration:underline;text-underline-offset:2px;cursor:pointer}
.sf-mas-boton:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px;border-radius:3px}
.sf-mas-boton[hidden]{display:none}
.sf-mas:not(.sf-mas-abierto) > .sf-mas-boton{position:absolute;bottom:0;inset-inline-end:0;padding-inline-start:30px;
  background:linear-gradient(to right,transparent,var(--sf-mas-fondo,var(--sf-paper)) 26px)}
[dir="rtl"] .sf-mas:not(.sf-mas-abierto) > .sf-mas-boton{background:linear-gradient(to left,transparent,var(--sf-mas-fondo,var(--sf-paper)) 26px)}
.sf-mas.sf-mas-abierto > .sf-mas-boton{margin-inline-start:6px}

/* ═══ Sólo para quien lee con lector de pantalla (`sf-solo-lector`) ═══
   La tabla equivalente de un gráfico a mano (§4, el tablero de la consola de
   empresa, 27-09-2026): visible para un lector de pantalla, invisible para
   quien ve. La receta estándar —1×1px, recortado, sin desbordar— y no
   `display:none`, que un lector de pantalla también se salta.
   ⚠ `table-layout:fixed`: sin esto, una TABLA ignora el `width:1px` —una
   tabla con `table-layout:auto` (el valor de fábrica) se dibuja tan ancha como
   pida su contenido aunque el CSS le pida 1px— y de este lado del recorte
   quedaba una barra de scroll horizontal en toda la pantalla. Medido al
   apretar la maqueta a 375px: `document.documentElement.scrollWidth` daba
   450px por esta única tabla. */
.sf-solo-lector{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;table-layout:fixed}

/* ═══ El selector de archivo (`sf-selector-archivo`) ═══
   Reemplaza el control nativo («Choose File | nombre.pdf») del modal de
   subida de la consola (renglón CD, 29-09-2026): un `<input type="file">`
   con `sf-solo-lector`, seguido de un `<label for class="sf-btn">` que lo
   abre y de un `<span>` con el nombre y el tamaño elegidos. El input oculto
   sigue recibiendo el foco del teclado, así que el anillo se le dibuja al
   botón hermano. `flex-wrap` y `min-width:0`: un nombre largo baja de
   línea en un teléfono en vez de ensanchar el modal. */
.sf-selector-archivo{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px}
.sf-selector-archivo .sf-solo-lector:focus-visible + .sf-btn{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-selector-archivo-nombre{min-width:0;color:var(--sf-mut);font-size:13px;overflow-wrap:anywhere}
/* ═══ La fila de fuentes del diálogo «Upload document» (U1) ═══
   Un botón por fuente en UNA fila que envuelve (nada de ancho fijo: a 375 px los botones bajan de renglón), de 44 px.
   El selector de archivo entra a la fila y su nombre queda debajo, a todo el ancho. */
.sf-fuentes{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin:0}
.sf-fuentes .sf-selector-archivo,.sf-fuentes .sf-fuentes-botones{display:contents}
.sf-fuentes .sf-selector-archivo-nombre{order:2;flex:1 1 100%}
.sf-fuentes .sf-fuentes-porque{order:3;flex:1 1 100%;font-size:13px}
.sf-fuentes .sf-btn{min-height:44px;white-space:normal}
.sf-fuente{flex:0 1 auto}
.sf-fuente-ico{flex:none}
.sf-fuente[aria-disabled="true"]{color:var(--sf-mut);background:var(--sf-soft);border-color:var(--sf-line);cursor:not-allowed}
.sf-orig-causa{margin:8px 0 0;font-size:13px}
.sf-lista-eleccion{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:8px}
.sf-lista-eleccion .sf-btn{width:100%;min-height:44px;justify-content:flex-start;text-align:start;white-space:normal}
/* «From a link» (U3): el campo de una línea con «Fetch»; en el teléfono el botón pasa abajo. */
.sf-enlace{margin:10px 0 0}
.sf-enlace[hidden]{display:none}
.sf-enlace-fila{display:flex;flex-wrap:wrap;gap:8px}
.sf-enlace-fila input{flex:1 1 14rem;min-width:0;min-height:44px}
.sf-enlace-fila .sf-btn{min-height:44px}
/* Arrastrar un archivo sobre el diálogo: borde de trazos (no sólo color) y el renglón dice «Drop it here». */
.modal.sf-soltando{outline:3px dashed var(--brand,var(--sf-brand));outline-offset:-8px}

/* ═══ Las cifras (`sf-stats`) ═══
   Una fila de números grandes con su rótulo abajo —«typical time to sign»,
   arriba de la lista de *Documents* desde el 21-09, generalizado acá para
   cualquier pantalla que necesite lo mismo—. Se envuelve en un teléfono en vez
   de achicarse hasta ilegible. */
.sf-stats{display:flex;flex-wrap:wrap;gap:20px 32px}
.sf-stat{display:flex;flex-direction:column;gap:2px;min-width:0}
.sf-stat > b{color:var(--sf-ink);font-size:22px;font-weight:700;line-height:1.2}
.sf-stat > span{color:var(--sf-mut);font-size:13px}

/* ═══ La ayuda plegada (`sf-info`) ═══
   Para una explicación que no hace falta leer siempre: un «ⓘ» junto al título
   que abre el párrafo debajo, sin globo que tape nada. */
.sf-info{display:inline-flex;align-items:center;justify-content:center;flex:none;width:20px;height:20px;margin:0 0 0 4px;padding:0;
  border:1px solid var(--sf-line);border-radius:50%;background:var(--sf-paper);color:var(--sf-mut);
  font:inherit;font-size:12px;font-weight:700;line-height:1;vertical-align:middle;cursor:pointer}
.sf-info:hover,.sf-info[aria-expanded="true"]{color:var(--brand,var(--sf-brand));border-color:var(--brand,var(--sf-brand))}
.sf-info:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}

/* ═══ Ocultar en tarjetas (`sf-solo-ancho`) ═══ (#7, 26-09-2026)
   Una columna que se ve en el escritorio y se esconde donde una tabla ya pasa
   a tarjetas apiladas (899 px: el punto de quiebre de index.html y
   operador.html para `.tarjetas`). La lista de Documents la usa en Recipients
   y Last action: en el teléfono, siete columnas en una tarjeta angosta son
   más ruido que dato, y la ficha del documento cuenta lo mismo con lugar de
   sobra.
   ⚠⚠ `[class].sf-solo-ancho` y no `.sf-solo-ancho` a secas: al mismo ancho,
   `.tarjetas td{display:block}` (el `<style>` propio de la página, que carga
   DESPUÉS de esta hoja) pesa `.tarjetas` + el elemento —specificity (0,1,1)—
   y le ganaba a un `.sf-solo-ancho` suelto —(0,1,0)—, medido dibujando la
   maqueta a 375 px: los puntos y la última acción seguían a la vista adentro
   de la tarjeta. El atributo `[class]` sube a (0,2,0) sin nombrar `.tarjetas`
   —que es vocabulario de esa página y no de esta hoja— ni usar `!important`. */
@media (max-width:899px){[class].sf-solo-ancho{display:none}}

/* ═══ Los puntos de los destinatarios (`sf-recip`) ═══ (#7, 26-09-2026)
   Un punto de 8 px por firmante, en el orden del circuito, con los mismos
   tres colores de estado que ya definen `.sf-pill`/`.sf-msg`
   (`sf-ok`/`sf-bad`/`sf-warn`); «+N» cuando hay más de cuatro. */
/* ═══ Del tamaño de un dedo (`sf-dedo`) ═══ (01-10-2026, R54-P1)
   Un botón chico (`sf-chico`, 32 px) que con un puntero grueso —un dedo—
   llega a los 44 px que pide la regla de toque. Se pide botón por botón y no
   se le aplica a todo `sf-chico`: hay chicos que viven en filas densas de
   otras pantallas, y agrandarlos todos cambiaría pantallas que nadie midió.
   Lo usan los de «Who you are» (Copy, Switch, Unlink y los de la tabla). */
@media (pointer:coarse){.sf-btn.sf-chico.sf-dedo{min-height:44px;min-width:44px}}

/* ═══ Sólo en tarjetas (`sf-solo-tarjeta`) ═══ (01-10-2026, encargo 64)
   Lo contrario de `sf-solo-ancho`: el rótulo de un dato («Level:», «Can
   sign:») que en la tabla ancha sobra —está en el encabezado— y en la pila de
   tarjetas del teléfono, donde el encabezado se esconde, hace falta. Mismo
   quiebre y mismo `[class]` para ganarle al `<style>` propio de la página. */
.sf-solo-tarjeta{display:none}
@media (max-width:899px){[class].sf-solo-tarjeta{display:inline;color:var(--sf-mut);font-size:13px}}

.sf-recip{display:inline-flex;align-items:center;flex-wrap:wrap;gap:4px}
.sf-recip-punto{flex:none;width:8px;height:8px;border-radius:50%;background:var(--sf-mut)}
.sf-recip-punto.sf-ok{background:var(--sf-ok)}
.sf-recip-punto.sf-bad{background:var(--sf-bad)}
.sf-recip-punto.sf-warn{background:var(--sf-warn)}
.sf-recip-mas{font-size:11.5px;font-weight:700;color:var(--sf-mut)}

/* ═══ La lista de Documents entra en su caja (`sf-docs`) ═══ (28-09-2026)
   Medido en `main`, en la maqueta de la consola de empresa: a 1336 px, con el
   lateral y el árbol de carpetas abiertos, la tabla medía 785–818 px dentro
   de una caja de 671 px con `overflow:hidden`, y «View»/«Signers» y el «⋯» de
   TODAS las filas quedaban afuera; a 1024 px, 785 px en 359. Recién a 1600
   entraba. Los culpables: 36 px de relleno por columna en siete columnas, los
   rótulos en mayúscula que fijan el mínimo de las columnas angostas, y el
   título del documento —la única columna que se puede partir— apretado a
   110 px, con filas de 160 a 210 px de alto.

   En este orden, y sólo desde 900 px (abajo la tabla ya es una pila de
   tarjetas —`.tarjetas` de index.html— y esto no la toca):
   1. Achicar lo que sobra: 8 px de relleno entre columnas (18 en los bordes,
      alineado con la cabecera del panel); Status, Recipients, Uploaded y la
      de acciones a lo justo de su contenido (`width:1%`); Signatures y Last
      action con un ancho fijo; la píldora del estado sin partirse; la fecha,
      corta y en un renglón (`fechaCorta` en consola.js); el título que parta
      una palabra larga antes que empujar la tabla. Lo que sobra queda para
      el título.
   2. Plegar columnas enteras por orden de valor —Uploaded, Signatures,
      Recipients y, sólo entre 1000 y 1199 px, Last action—, con los cortes
      puestos para que el título conserve ~150 px en cada escalón. Los cortes
      son del ANCHO DE LA VENTANA y valen para esta consola: la caja mide la
      ventana menos el lateral (250), el relleno de main (56) y, desde 1000
      px, el árbol (hasta 320 px; `.doscol` de index.html lo achica al 24 %
      entre 1000 y 1333) y su hueco (22); entre 900 y 999 el árbol va arriba
      y la lista tiene todo el ancho, por eso ahí Last action se ve.
      Lo plegado sigue en la ficha que abre View (`lineaDeLaFicha` y la línea
      de tiempo, en consola.js).
   3. Si igual no entra —otro idioma, un botón principal más largo—, la
      envoltura se desplaza de costado y la columna de acciones queda pegada
      a la derecha (`position:sticky`): nunca se va de la caja.
   ⚠ `.sf-docs th`/`td` pesan una clase y un elemento: le ganan a `th`/`td`
   del `<style>` de index.html aunque esta hoja cargue antes. */
@media (min-width:900px){
  .sf-docs-envoltura{overflow-x:auto}
  .sf-docs th,.sf-docs td{padding-inline:8px}
  .sf-docs th:first-child,.sf-docs td:first-child{padding-inline-start:18px}
  .sf-docs th:last-child,.sf-docs td:last-child{padding-inline-end:18px}
  /* El título no baja de 7.5rem (120 px): sin piso, `overflow-wrap:anywhere` le deja
     un mínimo de UNA letra y el reparto de la tabla se lo da todo al estado (42 px
     medidos a 1336 con la píldora del aviso de cuatro nombres). Es un piso contra
     el colapso, no la meta de ~150: con la píldora envuelta el título reparte solo
     a 120–230 px de 1100 a 1920, y un piso de 10rem (160) obligaba a desplazar la
     tabla a 1000 y a 1200 px de ventana (medido). */
  .sf-docs .sf-docs-documento{overflow-wrap:anywhere;min-width:7.5rem}
  .sf-docs .sf-docs-estado,.sf-docs .sf-docs-destinatarios,.sf-docs .sf-docs-subido,.sf-docs .sf-docs-acciones{width:1%}
  .sf-docs .sf-docs-estado > :first-child,.sf-docs .sf-docs-subido{white-space:nowrap}
  /* La píldora del aviso («The notice did not reach …», con el nombre de cada
     destinatario) y las otras que se apilan bajo el estado envuelven en renglones
     con un tope de ancho, en vez de estirar la columna Status a lo que mida la
     frase entera —475 px a 1336 y a 1920 con cuatro nombres—. Sólo la primera
     (el estado mismo) sigue en un renglón (`white-space:nowrap` de `.sf-pill` y
     la regla `> :first-child` de arriba). Guarda:
     test/el_titulo_de_documents_no_se_aprieta.test.ts. */
  .sf-docs .sf-docs-estado > .sf-pill:not(:first-child){white-space:normal;max-width:min(16rem,100%);
    border-radius:14px;overflow-wrap:anywhere}
  .sf-docs .sf-docs-firmas{width:7.5rem}
  .sf-docs .sf-docs-ultima{width:8rem}
  .sf-docs .sf-docs-acciones{position:sticky;inset-inline-end:0;z-index:1}
  .sf-docs td.sf-docs-acciones{background:var(--sf-paper)}
}
/* Desde 1700 px sobra lugar para todo: los anchos fijos dejaban al título con
   más de 330 px y partían en tres renglones el estado y la última acción
   (filas de 119 px a 1920, contra 99 antes de este cambio). Ahí vuelven a
   repartirse solos: 81 px medidos a 1920. */
@media (min-width:1700px){.sf-docs .sf-docs-estado,.sf-docs .sf-docs-firmas,.sf-docs .sf-docs-ultima{width:auto}}
@media (min-width:900px) and (max-width:1519px){.sf-docs .sf-docs-subido{display:none}}
@media (min-width:900px) and (max-width:1439px){.sf-docs .sf-docs-firmas{display:none}}
@media (min-width:900px) and (max-width:1319px){.sf-docs .sf-docs-destinatarios{display:none}}
@media (min-width:1000px) and (max-width:1199px){.sf-docs .sf-docs-ultima{display:none}}

/* ═══ La línea de tiempo del documento (`sf-timeline`) ═══ (#7, 26-09-2026)
   Enviado → cada persona → sellado → completado (o cancelado/vencido), a
   partir de los mismos eventos que ya pinta Evidence record. Un punto por
   paso, unidos por una línea vertical; `sf-actual` marca el paso que se está
   esperando (con la próxima acción abajo, en `--brand`); `sf-futuro` apaga
   los que todavía no llegaron —es un estado, no una función que falte, así
   que no lleva el punto ámbar de la vidriera (`.vd-punto`)—. */
.sf-timeline{display:flex;flex-direction:column}
.sf-timeline-paso{position:relative;display:flex;gap:12px;padding-bottom:20px}
.sf-timeline-paso:last-child{padding-bottom:0}
.sf-timeline-paso:not(:last-child)::before{content:"";position:absolute;left:4px;top:14px;bottom:-6px;
  width:2px;background:var(--sf-line)}
.sf-timeline-punto{position:relative;z-index:1;flex:none;width:10px;height:10px;margin-top:4px;
  border-radius:50%;background:var(--brand,var(--sf-brand))}
.sf-timeline-cuerpo{flex:1;min-width:0}
.sf-timeline-rotulo{font-size:14px;font-weight:650;color:var(--sf-ink)}
.sf-timeline-meta{margin-top:2px;font-size:12.5px;color:var(--sf-mut)}
.sf-timeline-proxima{margin-top:3px;font-size:12.5px;font-weight:650;color:var(--brand,var(--sf-brand))}
.sf-timeline-paso.sf-futuro .sf-timeline-punto{background:var(--sf-line)}
.sf-timeline-paso.sf-futuro .sf-timeline-rotulo{color:var(--sf-mut);font-weight:500}
.sf-timeline-paso.sf-actual .sf-timeline-punto{box-shadow:0 0 0 3px var(--sf-brand-50)}

/* UP-1: las filas que una subida acaba de agregar a Documents. Sin animación (nada que apagar con
   `prefers-reduced-motion`) y con el rótulo «New» al lado del título: el color solo no alcanza. En la lista de
   tarjetas (teléfono) la fila es la tarjeta, y `tbody` le gana a `.tarjetas tr` de index.html; la celda de acciones
   (pegada a la derecha desde 900 px, con fondo propio) se pinta igual. */
tbody tr.sf-recien-subida{background:var(--sf-acc-50);outline:2px solid var(--sf-acc);outline-offset:-2px}
tbody tr.sf-recien-subida > td:last-child{background:var(--sf-acc-50)}

@media (prefers-reduced-motion:reduce){
  .sf-menu-boton,.sf-idioma .sf-idioma-boton .sf-idioma-flecha,.sf-acordeon > summary::after,
  .sf-btn,.sf-card.sf-levanta,.sf-bloque-menu .sf-menu-flecha{transition:none}
  .sf-estado.sf-cargando{animation:none}
  .sf-spinner{animation:none}
}

/* ═══ El fondo de marca (`sf-fondo-marca`) — encargo #19, 27-09-2026 ═══
   La imagen de fondo que sube una cuenta (Account → Brand) o la instalación
   (el tema general, 131/210): una capa detrás de todo, con un velo claro para
   que lo que está encima siga pasando AA. La pone `tema.js` (la de la
   instalación, en /entrar) o `firmar.js` (la de la cuenta que manda el
   documento, con la de la instalación de respaldo) escribiendo
   `--sf-fondo-marca-img` y agregando esta clase a `<body>`: SIN esas dos
   cosas, la regla no hace nada — es la manera de que "sin fondo, todo sigue
   como hoy" sea literal, no una promesa.

   ⚠ El velo es un 60 % de blanco ENCIMA de la imagen (el primer fondo de la
   lista es el de más arriba). Con la peor imagen posible —negra entera— la
   superficie que queda todavía contrasta 5,8:1 contra `--sf-ink`: se mide
   en `test/el_velo_del_fondo_de_marca_pasa_aa.test.ts`, con la MISMA
   `contraste()` de `services/tema.ts`, y esa prueba se saboteó bajando el
   número para verla caer. No es la única defensa —el texto de verdad vive
   en tarjetas opacas (`sf-card`, `aside`, `header`) que el fondo nunca toca—
   pero así la promesa vale también si algún día algo se dibuja directo
   encima. */
.sf-fondo-marca{
  background-image:
    linear-gradient(rgba(255,255,255,.6),rgba(255,255,255,.6)),
    var(--sf-fondo-marca-img);
  background-size:cover;
  background-position:center;
  background-repeat:no-repeat;
  background-attachment:fixed;
}
@media (max-width:640px){
  /* `fixed` en el teléfono hace que algunos navegadores repinten el fondo en
     cada scroll del teclado virtual. Con `scroll` alcanza: la imagen cubre
     igual, sólo que se mueve con la página. */
  .sf-fondo-marca{background-attachment:scroll}
}

/* ── Sin permiso de imprimir (215, 230) ──────────────────────────────────────
   Nada de la pantalla sale por una impresora mientras la marca esté puesta:
   la pantalla de firma se la pone al `<body>` (firmar.js) y el visor de la
   consola a sí mismo (consola.js), así que al cerrarlo —o al abrir otro modal
   encima— la impresión vuelve sola. Una sola regla para las dos pantallas:
   hasta el 27-09 vivía copiada en el `<style>` de firmar.html, y el visor
   (H1 de la revisión R14) la habría copiado otra vez. No es la única defensa
   (E11): el atajo Ctrl+P lo intercepta cada pantalla aparte. */
@media print{
  body.sf-sin-impresion *,
  body:has(.sf-sin-impresion) *{ display:none !important }
}
/* VIS-1: «Print» del visor de la consola. Las hojas que dibuja pdf.js se pasan a `.sf-impresion` (todas, no sólo las que entran en
   pantalla), que no se ve en pantalla y es lo único que sale al papel; el visor se deshace de la clase al terminar (`afterprint`). */
.sf-impresion{display:none}
@media print{
  body.sf-imprimiendo-visor > *:not(.sf-impresion){display:none !important}
  body.sf-imprimiendo-visor .sf-impresion{display:block}
  .sf-impresion canvas{display:block;width:100% !important;height:auto !important;break-after:page;page-break-after:always}
}

/* ═══ El portal de documentación (`sf-portal`, `sf-camino`) — pieza 1, 29-09-2026 ═══
   Lo que dibuja `/docs`, `/docs/product`, `/docs/api`, `/docs/trust` y
   `/docs/status` (`src/docs_portal/paginas.ts`): la cabecera con su navegación,
   la columna de lectura, el pie con la versión medida, y la grilla de tarjetas
   «elegí tu camino». Todo con tokens `--sf-`; la marca que se pinta es `--brand`
   (la escribe `tema.js`), con la omisión del producto de respaldo.

   ⚠ Una tarjeta es VIVA (`sf-card sf-levanta`: un enlace, se levanta al pasar el
   mouse) o GRIS (`sf-card sf-apagada`: sin enlace principal, con su ● y su
   porqué escrito, que es la regla de la vidriera). El texto gris de la tarjeta
   apagada es `--sf-mut` sobre `--sf-soft`: el par lo mide la prueba de contraste
   de la hoja (`sf-estado sobre --sf-soft`), no se elige a ojo. */
.sf-portal{margin:0;font-family:var(--sf-font);color:var(--sf-ink);background:var(--sf-soft);line-height:1.55;-webkit-font-smoothing:antialiased}
.sf-portal-in{box-sizing:border-box;max-width:1040px;margin:0 auto;padding-inline:20px}
.sf-portal-cab{background:var(--sf-paper);border-bottom:1px solid var(--sf-line)}
.sf-portal-cab .sf-portal-in{display:flex;align-items:center;justify-content:space-between;gap:12px 24px;flex-wrap:wrap;padding-block:14px}
.sf-portal-marca{color:var(--sf-ink);font-weight:700;text-decoration:none}
.sf-portal-nav{display:flex;gap:4px;flex-wrap:wrap}
.sf-portal-nav a{padding:8px 12px;border-radius:var(--sf-r-s);color:var(--sf-ink);font-size:14.5px;font-weight:600;text-decoration:none}
.sf-portal-nav a:hover{background:var(--sf-soft)}
.sf-portal-nav a[aria-current]{background:var(--brand-50,var(--sf-brand-50))}
.sf-portal-nav a:focus-visible,.sf-portal-marca:focus-visible,.sf-camino-enlace:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-portal-main{padding-block:36px 60px}
.sf-portal-main h1{font-size:clamp(26px,4vw,34px);line-height:1.15;margin:0 0 10px}
.sf-portal-main h2{font-size:20px;line-height:1.25;margin:32px 0 12px}
.sf-portal-main h3{font-size:16px;margin:0 0 6px}
.sf-portal-main a{color:var(--brand,var(--sf-brand))}
.sf-portal-lead{color:var(--sf-mut);font-size:17px;margin:0 0 28px;max-width:62ch}
.sf-portal-main .sf-portal-sub{margin-block-start:40px}
.sf-portal-pie{border-top:1px solid var(--sf-line);padding-block:24px;color:var(--sf-mut);font-size:14px}
.sf-portal-pie p{margin:0 0 6px}
.sf-portal-pie a{color:var(--sf-mut)}
.sf-portal-pie code{font-family:var(--sf-mono);font-size:13px}
/* La cabecera, el pie y el selector COMUNES (encargo 213, L3; `src/portal/cabecera_y_pie.ts`). El «Powered by»
   va una vez, en el pie, con peso secundario; el selector de idiomas es el menú común `sf-idioma`. */
.sf-portal-pie .sf-portal-pie-poder{margin:10px 0 0;font-size:var(--sf-fs-12);color:var(--sf-mut)}
.sf-portal-cab .sf-portal-idioma{flex:none;color:var(--sf-ink)}
.sf-portal-cab .sf-portal-idioma[hidden]{display:none}
/* NAV-1 (13-10-2026): la cabecera con menú primario fijo, su segunda línea y el pie ÚNICO (`src/portal/cabecera_y_pie.ts`; hojas
   `docs/diseno/la-navegacion-del-sitio-2026-10-13.md` y `el-pie-del-sitio-2026-10-12.md`). Sólo tokens `--sf-*`. */
.sf-portal-cab .sf-portal-nav{flex:1 1 auto;justify-content:center}
.sf-portal-acciones{display:flex;align-items:center;gap:8px 14px;flex:none}
.sf-portal-entrar{padding:8px 6px;border-radius:var(--sf-r-s);color:var(--sf-ink);font-size:var(--sf-fs-14-5);font-weight:600;text-decoration:none}
.sf-portal-entrar:hover{text-decoration:underline}
.sf-portal-entrar:focus-visible,.sf-portal-seccion a:focus-visible,.sf-pie-marca:focus-visible,.sf-pie-estado:focus-visible,.sf-pie-col a:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-portal-seccion{border-top:1px solid var(--sf-line);background:var(--sf-soft)}
.sf-portal-seccion .sf-portal-in{display:flex;justify-content:flex-start;gap:4px;flex-wrap:wrap;padding-block:6px}
.sf-portal-seccion a{padding:6px 10px;border-radius:var(--sf-r-s);color:var(--sf-mut);font-size:var(--sf-fs-13-5);font-weight:600;text-decoration:none}
.sf-portal-seccion a:hover{background:var(--sf-paper);color:var(--sf-ink)}
.sf-portal-seccion a[hidden]{display:none}
.sf-portal-seccion a[aria-current]{background:var(--brand-50,var(--sf-brand-50));color:var(--sf-ink)}
.sf-idioma-lista a{text-decoration:none;color:inherit}
.sf-idioma-lista .sf-idioma-nota{margin:0;white-space:normal;color:var(--sf-mut);font-size:var(--sf-fs-12-5)}
@media (max-width:900px){
  .sf-portal-cab .sf-portal-in{padding-block:8px;gap:4px 12px}
  .sf-portal-cab .sf-portal-nav{order:3;flex:1 0 100%;justify-content:flex-start;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .sf-portal-cab .sf-portal-nav::-webkit-scrollbar,.sf-portal-seccion .sf-portal-in::-webkit-scrollbar{display:none}
  .sf-portal-cab .sf-portal-nav a,.sf-portal-seccion a{white-space:nowrap}
  .sf-portal-seccion .sf-portal-in{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding-block:2px}
}
/* Lo que se toca en la cabecera y el pie únicos mide ≥44 px de alto a ≤640 px (como el resto del portal). */
@media (max-width:640px){
  .sf-portal-entrar,.sf-portal-seccion a,.sf-portal-cab .sf-btn.sf-chico,.sf-pie-marca,.sf-pie-estado,.sf-pie-legal a{display:inline-flex;align-items:center;min-height:44px}
  .sf-portal-entrar,.sf-portal-seccion a{padding-inline:10px}
}
.sf-pie-grid{display:grid;grid-template-columns:2fr repeat(4,minmax(0,1fr));gap:24px 32px;margin-bottom:20px}
.sf-pie-id p{margin:4px 0}
.sf-pie-marca{color:var(--sf-ink);font-size:var(--sf-fs-17);font-weight:700;text-decoration:none}
.sf-pie-socio[hidden]{display:none}
.sf-pie-estado{display:inline-flex;align-items:center;gap:8px;margin-top:8px;color:var(--sf-ink);font-weight:600;text-decoration:none}
.sf-pie-estado[hidden]{display:none}
.sf-pie-punto{flex:none;width:8px;height:8px;border-radius:50%;background:var(--sf-ok)}
.sf-pie-estado[data-estado="otro"] .sf-pie-punto{background:var(--sf-bad)}
.sf-pie-col h2{margin:0 0 8px;color:var(--sf-ink);font-size:var(--sf-fs-12-5);font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.sf-pie-col ul{list-style:none;margin:0;padding:0;display:grid;gap:2px}
.sf-pie-col li[hidden]{display:none}
.sf-pie-col a{display:inline-flex;align-items:center;min-height:32px;color:var(--sf-mut);text-decoration:none}
.sf-pie-col a:hover{color:var(--sf-ink);text-decoration:underline}
.sf-pie-propia{margin:0 0 16px}
.sf-pie-legal{margin:0;padding-top:16px;border-top:1px solid var(--sf-line);font-size:var(--sf-fs-13)}
.sf-pie-minimo .sf-pie-id{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 16px;margin-bottom:12px}
@media (max-width:900px){.sf-pie-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.sf-pie-grid .sf-pie-id{grid-column:1/-1}}
@media (max-width:600px){.sf-pie-grid{grid-template-columns:minmax(0,1fr)}.sf-pie-col a{min-height:44px}}
.sf-camino{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,290px),1fr));gap:16px}
.sf-camino > div{display:flex}
.sf-camino-tarjeta{position:relative;display:flex;flex-direction:column;width:100%}
.sf-camino-quien{margin:0 0 6px;color:var(--sf-mut);font-size:11.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}
.sf-portal-main .sf-camino-titulo{margin:0 0 6px;font-size:18px}
.sf-portal-main .sf-camino-titulo a{color:var(--sf-ink);text-decoration:none}
/* Toda la tarjeta viva es el enlace: el `a` se estira sobre ella. */
.sf-camino-enlace::after{content:"";position:absolute;inset:0;border-radius:var(--sf-r-l)}
.sf-camino-que{margin:0;font-size:14.5px}
.sf-camino-porque{margin:12px 0 0;color:var(--sf-mut);font-size:13.5px}
.sf-camino-mientras{margin-block-start:10px}
.sf-card.sf-apagada{background:var(--sf-soft);box-shadow:none}
.sf-card.sf-apagada .sf-camino-que{color:var(--sf-mut)}
.sf-gris td{color:var(--sf-mut)}
.sf-card.sf-fuera{margin-block-start:12px}
/* Las funciones (`/features`, encargo 163): el estado arriba de cada tarjeta y, abajo, el pedido y la guía. */
.sf-fn-estado{margin:0 0 8px;display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.sf-fn-punto{color:var(--amber,var(--sf-dot));font-size:.8em;line-height:1}
.sf-fn-pie{margin:14px 0 0;display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px}
.sf-portal-main section[aria-labelledby]{margin-block-end:8px}
/* Las integraciones (`/integrations`, encargo 199): las dos puertas de igual peso y las recetas como
   cadena de cajas. La caja es una pastilla `sf-ico` con su etiqueta; entre caja y caja, un trazo del
   color de la línea. Sólo tokens `--sf-`. */
.sf-puerta-lista{margin:0;padding-inline-start:20px;font-size:14.5px}
.sf-puerta-lista li{margin-block-end:8px}
.sf-recetas{margin-block-start:4px}
.sf-cadena{list-style:none;margin:16px 0 0;padding:0}
.sf-caja{position:relative;display:flex;align-items:center;gap:12px;box-sizing:border-box;background:var(--sf-paper);border:1px solid var(--sf-line);border-radius:var(--sf-r);padding:10px 12px;font-size:14px;line-height:1.4}
.sf-caja + .sf-caja{margin-block-start:14px}
.sf-caja + .sf-caja::before{content:"";position:absolute;inset-inline-start:28px;top:-15px;height:14px;border-inline-start:2px solid var(--sf-line)}
.sf-caja .sf-ico{margin:0;flex:none;width:36px;height:36px}
.sf-caja-texto{min-width:0;overflow-wrap:anywhere}
/* Los textos legales (`/legal/privacy`, `/legal/terms`; encargo 56): el texto
   corrido, a una medida de lectura, y el dato que la instalación todavía no
   declaró en el gris de siempre (`--sf-mut` sobre `--sf-soft`, el par medido). */
.sf-legal{max-width:72ch}
.sf-legal p,.sf-legal li{font-size:16px}
.sf-legal li{margin-block-end:6px}
.sf-legal-version{color:var(--sf-mut)}
.sf-legal-falta{color:var(--sf-mut)}
.sf-legal-falta .vd-punto{margin-inline-end:4px}
@media (prefers-reduced-motion:reduce){.sf-card.sf-levanta{transform:none}}

/* ═══ La matriz de capacidades, de un vistazo (`sf-matriz`) — pieza 15 del encargo 53, 30-09-2026 ═══
   La dibujan las tres vistas de la matriz (`src/evaluar/matriz.ts`): las dos de
   `/evaluar/<clave>/capacidades` y `/docs/status`. Cuatro cosas:

   1. LOS NÚMEROS (`sf-stats` con `sf-stat sf-matriz-cifra`): cuántas andan,
      cuántas están grises, cuántas no se construyen, cada una un enlace que
      salta a su grupo. `sf-matriz-areas` es la fila de saltos a cada área.
   2. LA PÍLDORA CON PALABRA: el estado de una fila se dice con texto
      («Working», «Gray», «Not built») dentro de una `sf-pill`; el color y el
      ● ámbar acompañan, no son lo único que lo dice. El porqué de una fila gris
      es texto de la fila (`sf-matriz-que`), nunca `aria-hidden`.
   3. LA FILA COMO TARJETA: en un teléfono (640 px) la tabla deja de ser tabla.
      Medido el 30-09-2026 a 375 px, la matriz del partner eran 17,7 pantallas en
      columnas de 120 / 218 px, con filas de hasta 409 px: el texto largo caía
      en una columna angosta mientras la de al lado quedaba casi vacía. Ahora
      la capacidad y su estado van en un renglón y lo que hace, a todo el ancho,
      debajo. El encabezado se oculta sólo a la vista (`clip`), no del lector.
   4. `sf-fuera-titulo`: el título de una tarjeta de «Not built» (`h3`), sin el
      margen de arriba que un `h3` suelto trae de la página que lo envuelve. */
.sf-matriz td{vertical-align:top}
.sf-matriz .sf-matriz-cap{width:27%;font-weight:600}
.sf-matriz .sf-matriz-estado{width:1%;white-space:nowrap}
.sf-matriz-estado .vd-punto{margin-inline-end:6px}
.sf-matriz-que{color:var(--sf-ink)}
.sf-gris .sf-matriz-que{color:var(--sf-mut)}

.sf-matriz-resumen{margin:18px 0 6px}
.sf-stat.sf-matriz-cifra{color:inherit;text-decoration:none;min-height:44px;justify-content:center}
.sf-stat.sf-matriz-cifra > b{font-size:28px}
.sf-stat.sf-matriz-cifra:hover > span,.sf-stat.sf-matriz-cifra:focus-visible > span{color:var(--brand,var(--sf-brand));text-decoration:underline}
.sf-stat.sf-matriz-cifra:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:3px;border-radius:var(--sf-r-s)}
.sf-matriz-areas{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0;padding:0;list-style:none}
.sf-matriz-areas a{display:inline-flex;align-items:center;gap:6px;min-height:32px;box-sizing:border-box;padding:4px 12px;
  border:1px solid var(--sf-line);border-radius:var(--sf-r-pill);background:var(--sf-paper);
  color:var(--sf-ink);font-size:13.5px;font-weight:600;text-decoration:none}
.sf-matriz-areas a:hover{border-color:var(--brand,var(--sf-brand))}
.sf-matriz-areas a:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-matriz-areas span{color:var(--sf-mut);font-weight:700}
/* Galería de conectores y portal en pantalla angosta: lo que se toca mide ≥44 px de alto (encargo galería, 10-10-2026). Sólo ≤640 px; a 1336 no cambia nada. */
@media (max-width:640px){
  .sf-portal-marca,.sf-portal-nav a,.sf-matriz-areas a,.sf-portal-pie a,.sf-ayuda[data-idiomas] a,.sf-ayuda a[data-funciones],.sf-fn-pie .sf-btn{display:inline-flex;align-items:center;min-height:44px;box-sizing:border-box}
  .sf-portal-nav a,.sf-ayuda[data-idiomas] a,.sf-portal-pie a{padding-inline:8px}
  .sf-fn-pie .sf-btn{padding-inline:16px}
}

/* ═══ «What is set up here» (`sf-estado-*`) — pieza 17 del encargo 53, 30-09-2026 ═══
   Lo que ESTA instalación tiene configurado (`src/evaluar/estado_del_sandbox.ts`), en la vista
   «This sandbox» de la matriz. Cada elemento es un renglón de dos partes —el nombre, y lo que
   tiene— que en un teléfono pasan a apilarse. `sf-estado-medida` es la única línea con fecha. */
.sf-estado-medida{margin:6px 0 0;color:var(--sf-mut);font-size:13.5px}
.sf-estado-lista{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:8px}
.sf-estado-lista li{display:grid;grid-template-columns:minmax(0,13rem) minmax(0,1fr);gap:2px 16px;padding:10px 14px;
  border:1px solid var(--sf-line);border-radius:var(--sf-r);background:var(--sf-paper)}
.sf-estado-lista b{font-weight:600}
.sf-estado-que{display:grid;gap:2px;min-width:0;overflow-wrap:anywhere}
@media (max-width:640px){
  .sf-estado-lista li{grid-template-columns:minmax(0,1fr);padding:8px 12px}
  .sf-estado-que{font-size:13.5px;line-height:1.4}
}

.sf-fuera-titulo{display:flex;flex-wrap:wrap;align-items:center;gap:4px 10px;margin:0 0 6px;font-size:16px;line-height:1.3}

@media (max-width:640px){
  .sf-matriz thead{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
  .sf-matriz,.sf-matriz tbody{display:block}
  .sf-matriz tr{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:3px 10px;
    margin-block-end:5px;padding:7px 12px;border:1px solid var(--sf-line);border-radius:var(--sf-r);background:var(--sf-paper)}
  .sf-matriz tr.sf-gris{background:var(--sf-soft)}
  .sf-matriz td{display:block;padding:0;border:0}
  .sf-matriz .sf-matriz-cap{width:auto;font-size:14px;line-height:1.3}
  .sf-matriz .sf-pill{padding:1px 8px;font-size:11.5px}
  .sf-matriz .sf-matriz-estado{grid-column:2;grid-row:1;width:auto}
  .sf-matriz .sf-matriz-que{grid-column:1 / -1;font-size:13.5px;line-height:1.4}
  .sf-card.sf-fuera{padding:10px 14px;border-radius:var(--sf-r)}
  .sf-fuera-titulo{font-size:14.5px}
  .sf-fuera-titulo .sf-pill{padding:1px 8px;font-size:11.5px}
  h2.sf-matriz-area{margin-block:20px 8px}
  .sf-card.sf-fuera > p{margin:0;font-size:13.5px;line-height:1.4}
}

/* El «more» de la matriz (`data-sf-mas`, arriba) es cosa del teléfono: desde 641 px
   la tabla tiene el ancho para leer cada fila entera, y el texto se ve completo sin
   botón (`componentes.js` oculta solo el «more» de lo que entra). */
@media (min-width:641px){
  .sf-matriz .sf-mas:not(.sf-mas-abierto),
  .sf-card.sf-fuera .sf-mas:not(.sf-mas-abierto),
  .sf-estado-lista .sf-mas:not(.sf-mas-abierto){display:block;overflow:visible;-webkit-line-clamp:unset}
}

/* ═══ La hoja del evaluador (`sf-evaluar`, `sf-saltar`, `sf-indice`) — pieza 19 del encargo 53, 30-09-2026 ═══
   Lo que dibuja `envolverPagina` (`src/evaluar/pagina.ts`) en las guías y en las
   dos vistas de la matriz de `/evaluar/<clave>/…`, y el índice que genera el
   render de `src/compartir/html.ts` (también en el HTML de `docs/compartir/`).
   Reutiliza la cabecera, el menú y el pie del portal (`sf-portal-*`); lo propio
   es lo que el portal no tenía:

   1. LA MARCA: el nombre de la instalación y, si hay, su logo
      (`sf-evaluar-logo`). Los colores los escribe `tema.js` en `--brand`.
   2. EL TELÉFONO: medido el 29-09-2026 a 375 px, el menú eran seis enlaces
      apilados de 226 px que empujaban el título a 389 px de altura. Hasta 760
      px el menú es UNA fila con desplazamiento propio: la página no crece a lo
      ancho (el desplazamiento es del menú) y el título queda a la vista.
   3. EL TECLADO: `sf-saltar` es el primer foco de la página y lleva al `main`;
      sólo se ve cuando recibe el foco.
   4. LA LECTURA: el texto corrido tiene una columna de 48 `ch` como máximo.
      El `ch` es el ancho de un «0», y una letra de texto corrido mide unos dos
      tercios de eso: 48 `ch` son unos 70 a 75 caracteres por línea (medido el
      30-09-2026 contra las guías; antes eran 94 a 121).
      Las tablas, las tarjetas y las puertas conservan el ancho de la página.
   5. EL PAPEL: la impresión esconde el menú y el enlace de salto y CONSERVA el
      nombre de la instalación (la cabecera) y la línea de medición (el pie). */
.sf-evaluar{margin:0;font-family:var(--sf-font);font-size:17px;line-height:1.6;color:var(--sf-ink);background:var(--sf-paper);-webkit-font-smoothing:antialiased}
.sf-saltar{position:absolute;left:8px;top:-120px;z-index:1000;padding:10px 16px;border-radius:var(--sf-r-s);background:var(--brand,var(--sf-brand));color:var(--brand-text,#fff);font-weight:700;text-decoration:none}
.sf-saltar:focus{top:8px;outline:3px solid var(--sf-ink);outline-offset:2px}
.sf-evaluar-main:focus{outline:none}

/* La franja de la guía (encargo 215): debajo de la cabecera común; lleva el logo, «Evaluation guide», «Download PDF» y el menú de la guía. */
.sf-evaluar-sub{background:var(--sf-paper);border-bottom:1px solid var(--sf-line)}
.sf-evaluar-sub .sf-evaluar-marca-fila{display:flex;align-items:center;gap:12px 24px;flex-wrap:wrap;padding-block:12px 4px}
.sf-evaluar-marca{display:inline-flex;align-items:center;gap:10px;font-size:18px}
.sf-evaluar-logo{display:block;height:28px;width:auto;max-width:160px;object-fit:contain}
.sf-evaluar-inicio{padding:8px 12px;border-radius:var(--sf-r-s);color:var(--sf-mut);font-size:14.5px;font-weight:600;text-decoration:none}
.sf-evaluar-inicio:hover{background:var(--sf-soft)}
.sf-evaluar-inicio:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
/* «Download PDF» (pieza 20): sólo en las cuatro guías, junto a «Evaluation guide»; la impresión lo esconde (el papel ya es el documento). */
.sf-evaluar-inicio{margin-inline-start:auto}
.sf-evaluar-pdf{padding:8px 12px;border-radius:var(--sf-r-s);border:1px solid var(--brand,var(--sf-brand));color:var(--brand,var(--sf-brand));font-size:14.5px;font-weight:600;text-decoration:none}
.sf-evaluar-pdf:hover{background:var(--brand-50,var(--sf-brand-50))}
.sf-evaluar-pdf:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-evaluar-sub .sf-evaluar-nav{padding-block:4px 10px;justify-content:flex-start}

/* Las clases de un lector, no de una máquina: el texto corrido, en una columna de lectura. */
.sf-evaluar-main > h1,.sf-evaluar-main > h2,.sf-evaluar-main > h3,.sf-evaluar-main > h4,.sf-evaluar-main > p,.sf-evaluar-main > ul,.sf-evaluar-main > ol,.sf-evaluar-main > blockquote,.sf-evaluar-main > .sf-indice{max-width:48ch}

.sf-indice{margin:18px 0 24px;padding:12px 16px;border:1px solid var(--sf-line);border-radius:var(--sf-r-s);background:var(--brand-50,var(--sf-brand-50));font-size:15px}
.sf-indice summary{cursor:pointer;font-weight:700}
.sf-indice summary:focus-visible,.sf-indice a:focus-visible{outline:2px solid var(--brand,var(--sf-brand));outline-offset:2px}
.sf-indice ol{margin:8px 0 0;padding-inline-start:1.4em}
.sf-indice li{margin:3px 0}
.sf-indice a{color:var(--brand,var(--sf-brand))}

@media (max-width:760px){
  .sf-evaluar-sub .sf-evaluar-marca-fila{padding-block:8px 0}
  .sf-evaluar-sub .sf-evaluar-nav{flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:thin;padding-block:2px 8px}
  .sf-evaluar-nav a{flex:0 0 auto;white-space:nowrap}
  .sf-evaluar-main{padding-block:22px 48px}
  /* El menú del portal (siete enlaces) se esconde en el teléfono: el de la guía, en una fila que se desplaza, ya alcanza (encargo 224) */
  .sf-evaluar .sf-portal-cab .sf-portal-nav{display:none}
}

@media print{
  .sf-saltar,.sf-evaluar-nav,.sf-evaluar-inicio,.sf-evaluar-pdf{display:none}
  .sf-evaluar{font-size:12pt;background:#fff}
  .sf-evaluar .sf-portal-nav,.sf-evaluar .sf-portal-idioma{display:none}
  .sf-evaluar-sub{border-bottom:0}
  .sf-evaluar-sub .sf-evaluar-marca-fila{padding-block:0 8px}
  .sf-evaluar-main{padding-block:12px 0}
  .sf-evaluar-main h1,.sf-evaluar-main h2,.sf-evaluar-main h3{break-after:avoid}
  .sf-evaluar-main tr,.sf-evaluar-main .sf-card{break-inside:avoid}
  .sf-evaluar .sf-portal-pie{padding-block:12px 0}
}

/* ═══ Los planes (`sf-planes`, encargo 128; la maqueta de L-PLAN, PLAN-1a) ═══
   Un párrafo por plan con su botón, SIN precios: lo dibuja `sitio.js` en la portada con lo que contesta
   `GET /publico/planes`, y `src/docs_portal/paginas.ts` en `/planes`, que suma las dos tablas recortadas («In every plan»
   y «What makes the difference») y la cotización. Viven acá y no en el `<style>` de la portada porque ese techo sólo baja
   (`una_hoja_comun…`). */
section.sf-planes-banda{padding-block:64px}
.sf-planes-banda .sechead{max-width:80ch;margin-bottom:32px}
.sf-planes-basicos{margin:0 0 22px;font-size:15px;color:var(--sf-mut);max-width:80ch}
.sf-planes,.sf-planes-resumen{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(236px,1fr));margin-bottom:38px}
.sf-planes{margin-bottom:0}
.sf-plan,.sf-plan-resumen{position:relative;display:flex;flex-direction:column;padding:22px 22px 20px}
.sf-plan.sf-destacado,.sf-plan-resumen.sf-destacado{border-color:var(--brand,var(--sf-brand))}
.sf-plan h3,.sf-plan-resumen h2{font-size:22px;font-weight:700;letter-spacing:-.02em;margin:0 0 6px}
.sf-plan p,.sf-plan-resumen p{color:var(--sf-mut);font-size:15px;line-height:1.5}
.sf-plan p.sf-plan-para,.sf-plan-resumen p.sf-plan-para{margin:0 0 10px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--brand,var(--sf-brand));font-weight:700}
.sf-plan > p:not(.sf-plan-para),.sf-plan-resumen > p:not(.sf-plan-para){flex:1;margin:0 0 16px}
.sf-plan .sf-btn,.sf-plan-resumen .sf-btn{align-self:flex-start}
.sf-planes-mas{display:flex;justify-content:center;margin-top:26px}
.sf-planes-bloque{margin-block:0 40px}
.sf-planes-bloque h2{font-size:22px;letter-spacing:-.02em;margin:0 0 4px}
.sf-planes-bloque > .sf-ayuda{margin:0 0 14px}
.sf-planes-etapa th[scope=colgroup]{text-align:start;background:var(--sf-soft);color:var(--brand,var(--sf-brand));font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.sf-tip{border-bottom:1px dotted var(--sf-mut);cursor:help}
.sf-planes-dif{width:100%}
.sf-planes-dif thead th{vertical-align:bottom;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--sf-mut)}
.sf-planes-dif th.c,.sf-planes-dif td.c,.sf-planes-dif td.q{text-align:center;width:150px}
.sf-planes-dif td.q{color:var(--sf-mut);font-size:13px}
.sf-planes-dif tbody th[scope=row]{text-align:start;font-size:14.5px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--sf-ink)}
.sf-planes-leyenda{display:flex;flex-wrap:wrap;gap:6px 22px;margin:0 0 14px;padding:0;list-style:none;font-size:13px;color:var(--sf-mut)}
.sf-planes-leyenda li{display:flex;gap:8px;align-items:center}
.sf-planes-causas{margin:14px 0 0;padding-inline-start:18px;font-size:13px;color:var(--sf-mut)}
/* Un bloque que se lee recortado, con difuminado y «See all N» (`componentes.js`: `data-sf-recorte`). Sin JavaScript se lee entero. */
.sf-recorte{position:relative}
.sf-recorte.sf-recortado{max-height:330px;overflow:hidden;transition:max-height .35s ease}
.sf-recorte.sf-recortado::after{content:"";position:absolute;inset-inline:0;bottom:0;height:120px;background:linear-gradient(to bottom,transparent,var(--sf-soft) 85%);pointer-events:none}
.sf-recorte.sf-recortado.sf-abierto{max-height:none}
.sf-recorte.sf-recortado.sf-abierto::after{display:none}
.sf-recorte-ver{display:flex;justify-content:center;margin:-26px 0 0;position:relative;z-index:2}
.sf-recorte-ver[hidden]{display:none}
.sf-recorte-ver button,.sf-plan-resumen .sf-btn,.sf-planes-botones .sf-btn,.sf-planes-mas .sf-btn{min-height:44px;min-width:44px;display:inline-flex;align-items:center;justify-content:center}
.sf-recorte-ver button::after{content:" \25BE"}
.sf-recorte-ver button[aria-expanded="true"]::after{content:" \25B4"}
.sf-planes-cotizar{display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:space-between;padding:30px 28px}
.sf-planes-cotizar h2{margin:0 0 4px;font-size:22px;letter-spacing:-.02em}
.sf-planes-cotizar p{margin:0;color:var(--sf-mut);font-size:15px;max-width:620px}
.sf-planes-botones{display:flex;flex-wrap:wrap;gap:10px}
.sf-punto{display:inline-block;width:14px;height:14px;border-radius:50%;border:2px solid var(--brand,var(--sf-brand));vertical-align:middle}
.sf-punto.sf-incluida{background:var(--brand,var(--sf-brand))}
/* «limitada»: el anillo con un punto adentro (nunca el círculo lleno de «incluida»); lleva siempre su cifra al lado. */
.sf-punto.sf-limitada{background:radial-gradient(circle,var(--brand,var(--sf-brand)) 0 3px,transparent 3.5px)}
.sf-cifra{font-size:12.5px;color:var(--sf-ink);white-space:nowrap}
.sf-planes-iguales{margin-top:14px}
.sf-planes-comunes a,.sf-planes-iguales a{text-decoration:underline}   /* un enlace dentro de una frase no se distingue sólo por el color (axe: link-in-text-block) */
.sf-punto.sf-basica,.sf-punto.sf-politica{background:linear-gradient(90deg,var(--brand,var(--sf-brand)) 50%,transparent 50%)}
.sf-punto.sf-no_incluida{border-color:var(--sf-warn)}   /* ≥ 3:1 contra el fondo (el gris anterior daba 2,2:1) */
.sf-solo-lectores{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.sf-punto.sf-a_pedido{border-style:dashed}
@media (max-width:820px){
  .sf-planes-dif th.c,.sf-planes-dif td.c,.sf-planes-dif td.q{width:76px;padding-inline:6px}
  .sf-planes-dif td.q{font-size:12px}
  .sf-planes-dif thead th{font-size:11px;letter-spacing:.02em}
  .sf-planes-cotizar{padding:22px 18px}
}
.sf-punto.sf-no_habilitada{background:#9aa8b8;border-color:#9aa8b8}

/* ═══ Tres lenguas en una pieza y la tarjeta de una afirmación (`sf-l3`, `sf-afirmacion`, encargo 173) ═══
   El centro de confianza arma cada texto con sus tres lenguas a la vez
   (`<span data-l="en|es|pt">`); la que se ve es la del `<html lang>` que fija
   `idioma.js`, y sin JavaScript sale el inglés. Las pestañas de esa página son
   el componente común de arriba (`sf-tabs`). */
.sf-l3 [data-l]{display:none}
html:not([lang^="es"]):not([lang^="pt"]) .sf-l3 [data-l="en"],
html[lang^="es"] .sf-l3 [data-l="es"],
html[lang^="pt"] .sf-l3 [data-l="pt"]{display:inline}
.sf-afirmacion h3{margin:4px 0 8px;font-size:16.5px;line-height:1.3}
.sf-afirmacion p{margin:0 0 10px;font-size:14.5px}
.sf-afirmacion p.sf-afirmacion-estado{margin:0}
.sf-afirmacion p.sf-afirmacion-cond{color:var(--sf-mut);font-size:14px}
.sf-afirmacion details{font-size:13px;color:var(--sf-mut)}
.sf-afirmacion summary{cursor:pointer}
.sf-afirmacion details ul{margin:6px 0 0}
.sf-afirmacion code{overflow-wrap:anywhere;font-size:12.5px}

/* ═══ La tarjeta «Waiting for your wallet» (BIL-UX1): public/billetera_tarjeta.js, en /entrar, «Connect your wallet» y la firma ═══ */
.sf-bt h2{font-size:17px;margin:0 0 8px}
.sf-bt-estado{display:flex;align-items:flex-start;gap:10px;margin:0 0 8px}
.sf-bt-spin{width:18px;height:18px;flex:none;box-sizing:border-box;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;margin-top:3px;animation:sfbtgira .9s linear infinite}
@keyframes sfbtgira{to{transform:rotate(1turn)}}
@media (prefers-reduced-motion:reduce){.sf-bt-spin{animation:none;border-right-color:currentColor;opacity:.6}}
.sf-bt-qr{width:100%;margin:8px 0;background:#fff;line-height:0}
.sf-bt-qr svg{display:block;width:100%;height:auto}
.sf-bt-qr.sf-bt-vencido{opacity:.3;filter:grayscale(1)}
.sf-bt-tiempo{margin:4px 0 8px}
.sf-bt-pista{height:6px;border-radius:3px;background:rgba(127,127,127,.28);overflow:hidden}
.sf-bt-pista>span{display:block;height:100%;width:100%;background:currentColor;opacity:.75;transition:width 1s linear}
.sf-bt-restan{font-size:.9em;margin:4px 0 0}
.sf-bt-nota{font-size:.9em;margin:0;flex:1 1 100%}

/* ═══ Encargo 214 · FASE 0 · L4: familias C y G del portal (08-10-2026) ═══
   Lo propio de cada página que ya no vive en su `<style>`: /validar, /docs/changelog, /status,
   /demo, /api y /trust (que sólo se viste: su texto es el #689). La cabecera, el pie y el
   selector son los comunes (`sf-portal-*`, `src/portal/cabecera_y_pie.ts`); acá queda sólo
   el cuerpo de cada página, acotado por la clase de su `<body>` (`sf-pag-*`) para que una regla
   de una no toque a otra. */

/* ── validar.html → .sf-pag-validar ── */
  .sf-pag-validar{margin:0;font-family:var(--sf-font);color:var(--sf-ink);background:var(--sf-soft);line-height:1.55;-webkit-font-smoothing:antialiased}
  .sf-pag-validar .lead{color:var(--sf-mut);font-size:var(--sf-fs-17);margin:0 0 22px;max-width:62ch}
  .sf-pag-validar .drop{border:2px dashed var(--sf-drop-borde);border-radius:var(--sf-r-l);padding:34px 20px;text-align:center;background:var(--sf-paper);transition:border-color .15s,background .15s}
  .sf-pag-validar .drop.over{border-color:var(--brand,var(--sf-brand));background:var(--brand-50,var(--sf-brand-50))}
  .sf-pag-validar .drop p{margin:0 0 12px;color:var(--sf-mut)}
  .sf-pag-validar main input[type=file]{display:none}
  .sf-pag-validar .note{font-size:var(--sf-fs-13);color:var(--sf-mut);margin-top:10px}
  .sf-pag-validar .result{margin-top:20px}
  .sf-pag-validar .letra-chica{margin-top:22px}
  .sf-pag-validar .prov-resumen{margin-bottom:16px}
  .sf-pag-validar .detalle-prov{font-size:var(--sf-fs-17);margin:22px 0 10px}
  .sf-pag-validar .summary{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:16px}
  /* El ámbar del VEREDICTO (23-09): todas las firmas verifican y el archivo cambió
     después de la última. `.sf-pill.sf-warn` ya pinta el fondo y el texto; esto
     suma el borde que distingue este estado de una advertencia suelta —que no lo
     lleva—, y sigue sin ser el ● ámbar de la vidriera: aquél marca una función
     que falta, esto es un estado del documento. */
  .sf-pag-validar .sf-pill.changed{border-color:var(--sf-warn)}
  /* El título de cada tarjeta en fila, con su píldora a la derecha: la regla
     era `.card h3` y se había caído al pasar a `sf-card` (el título quedaba en
     18,72px, el de un h3 sin estilo, con la píldora abajo). */
  .sf-pag-validar .sf-card h3{margin:0 0 10px;font-size:var(--sf-fs-17);display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap}
  .sf-pag-validar .cambios{margin:0 0 14px;padding-left:22px;font-size:var(--sf-fs-14);color:var(--sf-warn)}
  .sf-pag-validar .cambios li{margin:2px 0}
  .sf-pag-validar main dl{display:grid;grid-template-columns:max-content 1fr;gap:6px 16px;margin:0;font-size:var(--sf-fs-14-5)}
  .sf-pag-validar main dt{color:var(--sf-mut)}
  .sf-pag-validar main dd{margin:0;overflow-wrap:anywhere}
  .sf-pag-validar main ul{margin:6px 0 0;padding-left:18px;font-size:var(--sf-fs-14-5)}
  .sf-pag-validar .fine{font-size:var(--sf-fs-13);color:var(--sf-mut)}
  /* 175: la línea discreta de qué validador respondió, pegada bajo el veredicto. */
  .sf-pag-validar .validado-por{margin:0 0 6px}
  /* ⚠ Clases propias de ESTA página: no las de operador.js ni las de consola.js
     (dos-consolas-dos-vocabularios-de-css). */
  .sf-pag-validar .proveedores{margin:14px 0 0}
  .sf-pag-validar .consentir-fila{display:flex;align-items:center;gap:6px}
  .sf-pag-validar .consentir{display:flex;align-items:flex-start;gap:9px;cursor:pointer;font-size:var(--sf-fs-14-5)}
  .sf-pag-validar .sf-btn.info{min-height:28px;width:28px;padding:0;border-radius:50%;font-size:var(--sf-fs-13);font-weight:700;color:var(--sf-mut)}
  .sf-pag-validar .consentir input{width:16px;height:16px;margin-top:3px;accent-color:var(--brand,var(--sf-brand));flex:none}
  .sf-pag-validar .aviso{margin-inline-start:25px}
  .sf-pag-validar main code{font-family:var(--sf-mono);font-size:var(--sf-fs-13);background:var(--brand-50,var(--sf-brand-50));padding:1px 5px;border-radius:var(--sf-r-s);overflow-wrap:anywhere}
  @media (max-width:640px){
    .sf-pag-validar main dl{grid-template-columns:1fr}
    .sf-pag-validar main dt{margin-top:6px}
  }

/* ── confianza.html → .sf-pag-trust ── */
  .sf-pag-trust [hidden]{display:none!important}
  .sf-pag-trust{margin:0;font-family:var(--sf-font);color:var(--sf-ink);background:var(--sf-soft);line-height:1.55;-webkit-font-smoothing:antialiased}
  .sf-pag-trust .lead{color:var(--sf-mut);font-size:var(--sf-fs-17);margin:0 0 32px;max-width:62ch}
  .sf-pag-trust .sf-card h2{margin:0 0 6px;font-size:var(--sf-fs-17)}
  .sf-pag-trust .sf-card .que_es{color:var(--sf-mut);font-size:var(--sf-fs-14);margin:0 0 14px}
  .sf-pag-trust main dl{display:grid;grid-template-columns:max-content 1fr;gap:8px 16px;margin:0 0 6px;font-size:var(--sf-fs-14-5)}
  .sf-pag-trust main dt{color:var(--sf-mut)}
  .sf-pag-trust main dd{margin:0;overflow-wrap:anywhere}
  .sf-pag-trust main ul{margin:6px 0 0;padding-left:18px;font-size:var(--sf-fs-14-5)}
  .sf-pag-trust main ul li{margin-bottom:6px}
  .sf-pag-trust .fine{font-size:var(--sf-fs-13);color:var(--sf-mut);margin-top:10px}
  .sf-pag-trust .gris{color:var(--sf-mut)}
  .sf-pag-trust main a{color:var(--brand,var(--sf-brand))}
  /* El punto de la vidriera: el tamaño, el color y su globo ya vienen de
     design-system.css (.vd-punto, cargada antes que este <style>) — esta
     página ya no dibuja su propio span a mano (25-09-2026: antes no podía
     llamar a la función de la consola que arma ese span, porque acá no se
     carga consola.js; ahora componentes.js trae el mismo mecanismo para
     todas). Acá sólo queda lo que la hoja común no define: el espacio antes
     del punto —el texto no trae uno propio— y el foco visible al llegar con
     Tab, en el acento (con su respaldo), no en la marca. */
  .sf-pag-trust .vd-punto{margin-inline-start:7px}
  .sf-pag-trust .vd-punto:focus-visible{outline:2px solid var(--acc,var(--sf-acc));outline-offset:3px}
  .sf-pag-trust .bajo-pestanas{margin-top:28px}
  @media (max-width:640px){
    .sf-pag-trust main dl{grid-template-columns:1fr}
    .sf-pag-trust main dt{margin-top:6px}
  }

/* ── api.html → .sf-pag-api ── */
  /* Sin :root propio: mismos valores en design-system.css (--sf-ink/mut/line/
     paper/font/mono, exactos) o cambiados por decisión del §6: --sf-ok (el
     verde de esta página no llegaba a AA) y --sf-soft. --brand/--acc los
     sigue escribiendo tema.js: cada uso lleva su respaldo `var(--brand,
     var(--sf-brand))`. Radios 12/10px sin equivalente pasan al más cercano
     de la escala (11px), como pide la decisión 2. */
  html:has(.sf-pag-api){scroll-behavior:smooth}
  .sf-pag-api{margin:0;font-family:var(--sf-font);color:var(--sf-ink);background:var(--sf-paper);
       -webkit-font-smoothing:antialiased;line-height:1.55}
  .sf-pag-api main a,.sf-pag-api .portada a{color:var(--brand,var(--sf-brand));text-decoration:none}
  .sf-pag-api main a:hover,.sf-pag-api .portada a:hover{text-decoration:underline}
  .sf-pag-api main code,.sf-pag-api main pre,.sf-pag-api .portada pre{font-family:var(--sf-mono);font-size:var(--sf-fs-13)}
  .sf-pag-api .envoltura{max-width:1120px;margin:0 auto;padding:0 24px}
  /* ── Barra ───────────────────────────────────────────────────────────── */
  /* ── Portada ─────────────────────────────────────────────────────────── */
  .sf-pag-api .portada{padding:64px 0 40px;border-bottom:1px solid var(--sf-line);
           background:linear-gradient(180deg,var(--brand-50,var(--sf-brand-50)),transparent)}
  .sf-pag-api .kicker{font-size:var(--sf-fs-12);font-weight:700;letter-spacing:.14em;text-transform:uppercase;
          color:var(--brand,var(--sf-brand));margin:0 0 12px}
  .sf-pag-api .portada h1{margin:0 0 14px;font-size:var(--sf-fs-clamp-32px-5vw-48px);line-height:1.08;
              letter-spacing:-.03em;text-wrap:balance}
  .sf-pag-api .portada p.bajada{margin:0;font-size:var(--sf-fs-18);color:var(--sf-mut);max-width:62ch}
  /* Las tres tarjetas son sf-card (ver el HTML): sólo queda la grilla y el
     `code` inline, que sf-card no cubre. */
  .sf-pag-api .tres{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;
        margin:32px 0 0}
  .sf-pag-api .tres h3{margin:0 0 6px;font-size:var(--sf-fs-14);letter-spacing:-.01em}
  .sf-pag-api .tres p{margin:0;font-size:var(--sf-fs-14);color:var(--sf-mut)}
  .sf-pag-api .tres code{background:var(--sf-soft);border:1px solid var(--sf-line);border-radius:var(--sf-r-s);
             padding:1px 6px;color:var(--sf-ink)}
  /* ── Familias ────────────────────────────────────────────────────────── */
  .sf-pag-api main main{padding:48px 0 80px}
  .sf-pag-api .familia{margin:0 0 48px}
  .sf-pag-api .familia > h2{margin:0 0 6px;font-size:var(--sf-fs-26);letter-spacing:-.02em}
  .sf-pag-api .familia > p{margin:0 0 20px;color:var(--sf-mut);max-width:72ch}
  /* El acordeón verbo+camino+resumen no es sf-acordeon (su cabecera de tres
     columnas no entra en ese molde): clases propias, sólo con tokens. */
  .sf-pag-api .rutas{border:1px solid var(--sf-line);border-radius:var(--sf-r-l);overflow:hidden}
  .sf-pag-api main details.ruta{border-top:1px solid var(--sf-line)}
  .sf-pag-api main details.ruta:first-child{border-top:0}
  .sf-pag-api main details.ruta[open]{background:var(--sf-soft)}
  .sf-pag-api main summary.cabeza{display:flex;align-items:center;gap:14px;padding:14px 18px;cursor:pointer;
                 list-style:none;user-select:none}
  .sf-pag-api main summary.cabeza::-webkit-details-marker{display:none}
  .sf-pag-api main summary.cabeza:hover{background:var(--brand-50,var(--sf-brand-50))}
  /* Verbo GET/POST/PATCH/DELETE: badge decorativo sin equivalente en la
     escala (no hay azul ni ámbar/rojo de fondo sólido); sólo el verde pasa a
     --sf-ok (decisión 1). */
  .sf-pag-api .verbo{flex:none;min-width:64px;text-align:center;font-family:var(--sf-mono);font-size:var(--sf-fs-11);
         font-weight:500;letter-spacing:.06em;padding:4px 8px;border-radius:var(--sf-r-s);color:var(--sf-paper)}
  .sf-pag-api .verbo.get{background:var(--sf-verbo-get)}
  .sf-pag-api .verbo.post{background:var(--sf-ok)}
  .sf-pag-api .verbo.patch{background:var(--sf-dot);color:var(--sf-verbo-patch-texto)}
  .sf-pag-api .verbo.delete{background:var(--sf-verbo-delete)}
  .sf-pag-api .camino{font-family:var(--sf-mono);font-size:var(--sf-fs-13-5);font-weight:500;flex:none}
  .sf-pag-api .resumen{color:var(--sf-mut);font-size:var(--sf-fs-14);margin-left:auto;text-align:right;
           overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:48%}
  .sf-pag-api .cuerpo{padding:4px 18px 22px 96px;border-top:1px solid var(--sf-line);background:var(--sf-paper)}
  .sf-pag-api .cuerpo p{margin:14px 0 0;color:var(--sf-mut);font-size:var(--sf-fs-14-5);max-width:76ch}
  .sf-pag-api .cuerpo p strong{color:var(--sf-ink)}
  .sf-pag-api .cuerpo p code{background:var(--sf-soft);border:1px solid var(--sf-line);border-radius:var(--sf-r-s);
                 padding:1px 6px;color:var(--sf-ink);font-size:var(--sf-fs-12-5)}
  .sf-pag-api .cuerpo h4{margin:20px 0 8px;font-size:var(--sf-fs-12);letter-spacing:.1em;text-transform:uppercase;
             color:var(--sf-mut)}
  .sf-pag-api .params{display:grid;gap:6px;font-size:var(--sf-fs-14)}
  .sf-pag-api .params > div{display:flex;gap:10px;align-items:baseline}
  .sf-pag-api .params code{flex:none;background:var(--sf-soft);border:1px solid var(--sf-line);border-radius:var(--sf-r-s);
               padding:1px 6px}
  .sf-pag-api .params span{color:var(--sf-mut)}
  .sf-pag-api main pre.curl{margin:8px 0 0;background:var(--sf-ink);color:var(--sf-curl-texto);border-radius:var(--sf-r);
           padding:14px 16px;overflow-x:auto;font-size:var(--sf-fs-12-5);line-height:1.7}
  .sf-pag-api main pre.curl .st{color:var(--sf-codigo-cadena)}
  /* Avisos: marca y acento, no sf-msg (sf-nota es azul informativo; acá el
     color ES el mensaje: la marca en uno, el acento de Entrust en el otro). */
  .sf-pag-api .aviso{border:1px solid var(--sf-line);border-left:3px solid var(--brand,var(--sf-brand));
         background:var(--brand-50,var(--sf-brand-50));border-radius:var(--sf-r);padding:16px 20px;margin:0 0 28px}
  .sf-pag-api .aviso strong{display:block;margin-bottom:4px}
  .sf-pag-api .aviso p{margin:0;font-size:var(--sf-fs-14-5);color:var(--sf-mut)}
  /* La tabla de eventos usa sf-table (ver el HTML); .desliza sólo pone el
     borde/radio exterior y el scroll lateral, que sf-table no trae. */
  .sf-pag-api .desliza{overflow-x:auto;border:1px solid var(--sf-line);border-radius:var(--sf-r-l)}
  .sf-pag-api #eventos code{background:var(--sf-soft);border:1px solid var(--sf-line);border-radius:var(--sf-r-s);
                padding:1px 6px;white-space:nowrap}
  .sf-pag-api #eventos td.que{color:var(--sf-mut)}
  .sf-pag-api .cargando{color:var(--sf-mut);padding:40px 0}
  .sf-pag-api .falla{border:1px solid var(--sf-line);border-left:3px solid var(--acc,var(--sf-acc));
         background:var(--acc-50,var(--sf-acc-50));border-radius:var(--sf-r);padding:16px 20px}
  @media (max-width:760px){
    .sf-pag-api .resumen{display:none}
    .sf-pag-api .cuerpo{padding-left:18px}
    /* ⚠ Los cuatro enlaces no entraban en 375 px al lado de la marca: la página
       medía 517 de ancho (24-09-2026). La barra baja a dos renglones y deja de
       ser pegajosa. */
  }

/* ── demo.html → .sf-pag-demo ── */
  /* --noche/--noche-2 (el registro de llamadas, SIEMPRE oscuro) no tienen
     equivalente en la escala común (el modo oscuro es la decisión 4 del §6,
     todavía sin hacer): quedan como únicas variables propias, sin el
     prefijo --sf- (la guarda sólo prohíbe ese prefijo y --brand). El resto
     del :root se borra: mismos valores en design-system.css (--sf-ink/mut/
     line/paper/font/mono) o cambiados por decisión: --sf-ok (este verde no
     llegaba a AA) y --sf-soft. --brand/--acc los sigue escribiendo tema.js:
     cada uso lleva su respaldo var(--brand, var(--sf-brand)). */
  .sf-pag-demo{--noche:var(--sf-noche); --noche-2:var(--sf-noche-2)}
  /* ⚠ `[hidden]` es un selector de ATRIBUTO y `.escenario{display:grid}` es de
     clase: misma especificidad, gana el que va después. Sin esto, `hidden`
     no esconde nada y la demostración se ve entera debajo de la puerta. */
  .sf-pag-demo [hidden]{display:none!important}
  .sf-pag-demo{margin:0;font-family:var(--sf-font);color:var(--sf-ink);background:var(--sf-soft);
       -webkit-font-smoothing:antialiased;line-height:1.5}
  .sf-pag-demo main a,.sf-pag-demo .puerta a{color:var(--brand,var(--sf-brand))}
  .sf-pag-demo main code,.sf-pag-demo .puerta code{font-family:var(--sf-mono)}
  .sf-pag-demo main button,.sf-pag-demo .puerta button{font-family:inherit}
  /* ⚠ En 375 px los tres enlaces no entraban al lado de la marca: la página medía
     464 de ancho (24-09-2026). La barra baja a dos renglones. */
  /* ── El acceso: sf-card (HTML) pone el marco; acá sólo el ancho y el input
       de token, monoespaciado, que el componente no cubre. ── */
  .sf-pag-demo .puerta{max-width:660px;margin:56px auto}
  .sf-pag-demo .puerta h1{margin:0 0 8px;font-size:var(--sf-fs-26);letter-spacing:-.02em}
  .sf-pag-demo .puerta p{margin:0 0 18px;color:var(--sf-mut);font-size:var(--sf-fs-15)}
  .sf-pag-demo #tok{font-family:var(--sf-mono)}
  .sf-pag-demo .puerta .como{margin:14px 0 0;font-size:var(--sf-fs-13-5);color:var(--sf-mut);background:var(--brand-50,var(--sf-brand-50));
                border-radius:var(--sf-r);padding:12px 14px}
  /* ── El escenario ────────────────────────────────────────────────────── */
  .sf-pag-demo .escenario{max-width:1480px;margin:0 auto;padding:22px 24px 60px;
             display:grid;grid-template-columns:1.15fr 1fr;gap:22px;align-items:start}
  @media (max-width:1100px){
    .sf-pag-demo .escenario{grid-template-columns:1fr}
  }
  .sf-pag-demo .panel{background:var(--sf-paper);border:1px solid var(--sf-line);border-radius:var(--sf-r-l);
         overflow:hidden}
  .sf-pag-demo .panel > h2{margin:0;padding:16px 20px;font-size:var(--sf-fs-13);letter-spacing:.1em;
              text-transform:uppercase;color:var(--sf-mut);border-bottom:1px solid var(--sf-line);
              display:flex;align-items:center;gap:10px}
  .sf-pag-demo .panel > h2 .quien{margin-left:auto;text-transform:none;letter-spacing:0;font-size:var(--sf-fs-13);
                     color:var(--sf-mut);font-weight:500}
  /* El sistema de al lado — deliberadamente NO se parece a Signing Flows: su
     azul y su logo son SU identidad y quedan sin token a propósito (sólo lo
     neutro —línea, texto secundario— se comparte). */
  .sf-pag-demo .erp{--erp:var(--sf-erp);--erp-50:var(--sf-erp-50)}
  .sf-pag-demo .erp > h2{background:var(--erp-50);color:var(--sf-erp)}
  .sf-pag-demo .erp .app{padding:0}
  .sf-pag-demo .erp .cinta{display:flex;align-items:center;gap:12px;padding:14px 20px;
              border-bottom:1px solid var(--sf-line);background:var(--sf-erp-cab-fondo)}
  .sf-pag-demo .erp .logo{width:26px;height:26px;border-radius:7px;background:var(--sf-erp);color:var(--sf-paper);
             display:grid;place-items:center;font-weight:800;font-size:var(--sf-fs-13)}
  .sf-pag-demo .erp .nombre{font-weight:700;letter-spacing:-.01em}
  .sf-pag-demo .erp .ruta{color:var(--sf-mut);font-size:var(--sf-fs-13)}
  .sf-pag-demo main table.docs{width:100%;border-collapse:collapse;font-size:var(--sf-fs-14)}
  .sf-pag-demo main table.docs th{text-align:left;font-size:var(--sf-fs-11);letter-spacing:.08em;text-transform:uppercase;
                color:var(--sf-mut);padding:11px 20px;border-bottom:1px solid var(--sf-line)}
  .sf-pag-demo main table.docs td{padding:13px 20px;border-bottom:1px solid var(--sf-line);vertical-align:middle}
  .sf-pag-demo main table.docs tr:last-child td{border-bottom:0}
  .sf-pag-demo main table.docs tr.foco{background:var(--brand-50,var(--sf-brand-50))}
  .sf-pag-demo .doc-nom{font-weight:600}
  .sf-pag-demo .doc-sub{color:var(--sf-mut);font-size:var(--sf-fs-12-5)}
  /* El chip de estado usa sf-pill (HTML y demo.js): acá sólo su punto, que
     sf-pill no define, y el latido cuando está "trabajando". */
  .sf-pag-demo .sf-pill .punto{width:7px;height:7px;border-radius:50%;background:currentColor}
  .sf-pag-demo .sf-pill.sf-warn .punto{animation:latido 1.4s ease-in-out infinite}
  .sf-pag-demo @keyframes latido{0%,100%{opacity:1}50%{opacity:.25}}
  @media (prefers-reduced-motion:reduce){
    .sf-pag-demo .sf-pill.sf-warn .punto{animation:none}
  }
  .sf-pag-demo .acciones{padding:16px 20px;border-top:1px solid var(--sf-line);display:flex;gap:10px;
            flex-wrap:wrap;align-items:center}
  .sf-pag-demo .acciones .nota{color:var(--sf-mut);font-size:var(--sf-fs-13);flex:1 1 240px}
  /* Los ajustes, plegados: <details> propio (su grilla no es sf-acordeon);
     sus campos sí son sf-field (ver el HTML). */
  .sf-pag-demo .ajustes{border-top:1px solid var(--sf-line);padding:0 20px}
  .sf-pag-demo .ajustes summary{padding:14px 0;cursor:pointer;font-size:var(--sf-fs-13-5);font-weight:600;
                   color:var(--brand,var(--sf-brand));list-style:none;user-select:none}
  .sf-pag-demo .ajustes summary::-webkit-details-marker{display:none}
  .sf-pag-demo .ajustes summary::before{content:'▸ ';font-size:var(--sf-fs-11)}
  .sf-pag-demo .ajustes[open] summary::before{content:'▾ '}
  /* ⚠ DOS columnas fijas, no `auto-fit`. Con auto-fit entran tres y el par
     «First signer / Their name» queda partido entre el final de un renglón y el
     principio del siguiente: se lee como si el nombre fuera de otra persona. */
  .sf-pag-demo .ajustes .rejilla{display:grid;grid-template-columns:repeat(2,1fr);
                    gap:12px;padding:0 0 6px}
  @media (max-width:520px){
    .sf-pag-demo .ajustes .rejilla{grid-template-columns:1fr}
  }
  /* El gap de la grilla ya separa los campos: sin esto, el margen que
     sf-field agrega entre hermanos duplicaría el espacio entre filas. */
  .sf-pag-demo .ajustes .rejilla > .sf-field{margin-block-start:0}
  .sf-pag-demo .ajustes .pista{margin:8px 0 16px;font-size:var(--sf-fs-12-5);color:var(--sf-mut)}
  /* El resultado */
  .sf-pag-demo .resultado{padding:18px 20px;border-top:1px solid var(--sf-line);display:none}
  .sf-pag-demo .resultado.visible{display:block}
  .sf-pag-demo .resultado h3{margin:0 0 12px;font-size:var(--sf-fs-15);letter-spacing:-.01em}
  .sf-pag-demo .medallas{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 14px}
  .sf-pag-demo .medalla{border:1px solid var(--sf-line);border-radius:var(--sf-r);padding:10px 14px;min-width:150px}
  .sf-pag-demo .medalla .t{font-size:var(--sf-fs-11);letter-spacing:.08em;text-transform:uppercase;color:var(--sf-mut)}
  .sf-pag-demo .medalla .v{font-size:var(--sf-fs-17);font-weight:800;letter-spacing:-.02em;margin-top:2px}
  .sf-pag-demo .medalla.ok{background:var(--sf-ok-50);border-color:var(--sf-medalla-borde)}
  .sf-pag-demo .medalla.ok .v{color:var(--sf-medalla-texto)}
  .sf-pag-demo .enlaces{display:flex;gap:10px;flex-wrap:wrap}
  /* ── El registro de llamadas: consola SIEMPRE oscura, sin equivalente en
       la escala (modo oscuro: decisión 4, sin hacer). Colores a mano; sólo
       radios y --sf-mono pasan a la escala. ── */
  .sf-pag-demo .log{background:var(--noche);border-color:var(--sf-log-borde)}
  .sf-pag-demo .log > h2{background:var(--noche-2);color:var(--sf-log-cab-texto);border-bottom-color:var(--sf-log-cab-borde)}
  .sf-pag-demo .log > h2 .quien{color:var(--sf-log-tenue)}
  .sf-pag-demo .tira{max-height:min(70vh,760px);overflow-y:auto;padding:12px}
  .sf-pag-demo .llamada{border:1px solid var(--sf-llamada-borde);border-radius:var(--sf-r);margin:0 0 10px;overflow:hidden;
           background:var(--sf-llamada-fondo)}
  .sf-pag-demo .llamada .cab{display:flex;align-items:center;gap:10px;padding:10px 12px;cursor:pointer}
  .sf-pag-demo .llamada .cab:hover{background:var(--sf-noche-2)}
  .sf-pag-demo .verbo{flex:none;min-width:56px;text-align:center;font-family:var(--sf-mono);font-size:var(--sf-fs-10-5);
         font-weight:500;letter-spacing:.06em;padding:3px 7px;border-radius:var(--sf-r-s);color:var(--sf-paper)}
  .sf-pag-demo .verbo.get{background:var(--sf-verbo-get)}
  .sf-pag-demo .verbo.post{background:var(--sf-verbo-post)}
  .sf-pag-demo .verbo.patch{background:var(--sf-verbo-patch)}
  .sf-pag-demo .camino{font-family:var(--sf-mono);font-size:var(--sf-fs-12-5);color:var(--sf-camino-texto);overflow:hidden;
          text-overflow:ellipsis;white-space:nowrap}
  .sf-pag-demo .estado{margin-left:auto;display:flex;align-items:center;gap:8px;flex:none}
  .sf-pag-demo .cod{font-family:var(--sf-mono);font-size:var(--sf-fs-11-5);padding:2px 7px;border-radius:var(--sf-r-s)}
  .sf-pag-demo .cod.ok{background:var(--sf-cod-ok-fondo);color:var(--sf-cod-ok-texto)}
  .sf-pag-demo .cod.mal{background:var(--sf-cod-mal-fondo);color:var(--sf-cod-mal-texto)}
  .sf-pag-demo .ms{font-family:var(--sf-mono);font-size:var(--sf-fs-11);color:var(--sf-log-tenue)}
  .sf-pag-demo .llamada pre{margin:0;padding:10px 12px;border-top:1px solid var(--sf-llamada-borde);background:var(--sf-noche);
               color:var(--sf-llamada-texto);font-size:var(--sf-fs-11-5);line-height:1.65;overflow-x:auto;
               white-space:pre-wrap;word-break:break-word}
  .sf-pag-demo .llamada pre .k{color:var(--sf-codigo-clave)}
  .sf-pag-demo .llamada pre .s{color:var(--sf-codigo-cadena)}
  .sf-pag-demo .llamada pre .n{color:var(--sf-codigo-numero)}
  .sf-pag-demo .llamada .etiqueta{font-size:var(--sf-fs-10-5);letter-spacing:.08em;text-transform:uppercase;
                     color:var(--sf-log-vacio);padding:8px 12px 0}
  .sf-pag-demo .llamada[data-abierto="no"] pre,.sf-pag-demo .llamada[data-abierto="no"] .etiqueta{display:none}
  .sf-pag-demo .latido{display:flex;align-items:center;gap:10px;padding:9px 12px;margin:0 0 10px;
          border:1px solid var(--sf-llamada-borde);border-radius:var(--sf-r);background:var(--sf-llamada-fondo);
          color:var(--sf-log-tenue);font-size:var(--sf-fs-12-5);font-family:var(--sf-mono)}
  .sf-pag-demo .paso-humano{border:1px dashed var(--sf-humano-borde);border-radius:var(--sf-r);padding:14px;margin:0 0 10px;
               background:var(--sf-humano-fondo);color:var(--sf-llamada-texto);font-size:var(--sf-fs-13-5)}
  .sf-pag-demo .paso-humano strong{color:var(--sf-paper);display:block;margin-bottom:4px}
  .sf-pag-demo .paso-humano a{color:var(--sf-humano-enlace);word-break:break-all;font-family:var(--sf-mono);font-size:var(--sf-fs-12)}
  .sf-pag-demo .vacio{color:var(--sf-log-vacio);font-size:var(--sf-fs-13-5);padding:24px 12px;text-align:center}
  .sf-pag-demo .falla{background:var(--acc-50,var(--sf-acc-50));border:1px solid var(--sf-falla-borde);border-left:3px solid var(--acc,var(--sf-acc));
         border-radius:var(--sf-r);padding:14px 16px;margin:14px 20px;font-size:var(--sf-fs-14)}

/* api: el índice de la página (antes iba en su barra propia; la cabecera común ya no la lleva) */
  .sf-pag-api .indice{display:flex;flex-wrap:wrap;gap:6px 22px;margin:18px 0 0;font-weight:600;font-size:var(--sf-fs-14)}
  .sf-pag-api .indice a{color:var(--sf-mut)}

/* ── /status: lo de la VISTA (la barra, los cuadros, la línea). Cuelga de .sf-pag-estado como el resto: si la consola del operador la reutiliza, que envuelva el dibujo en esa clase ── */
  .sf-pag-estado .st-barra{position:relative;display:flex;gap:2px;height:30px}
  .sf-pag-estado .st-dia{flex:1 1 0;min-width:0;border-radius:2px;background:var(--sf-line)}
  .sf-pag-estado .st-cuadro{position:relative;width:16px;height:16px;border-radius:4px;background:var(--sf-line);flex:none}
  .sf-pag-estado .st-verde{background:var(--sf-ok)}
  .sf-pag-estado .st-ambar{background:var(--sf-dot)}
  .sf-pag-estado .st-rojo{background:var(--sf-bad)}
  .sf-pag-estado .st-gris{background:var(--sf-line)}
  .sf-pag-estado .st-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
  .sf-pag-estado .st-elementos{position:relative;margin:0 0 10px}
  .sf-pag-estado .st-cuadros{display:flex;flex-wrap:wrap;gap:4px}
  .sf-pag-estado .st-spark{position:relative;display:inline-block;width:120px;height:24px;flex:none;line-height:0}
  .sf-pag-estado .st-spark svg{width:100%;height:100%;display:block;overflow:visible}
  .sf-pag-estado .st-spark-linea{fill:none;stroke:var(--sf-mut);stroke-width:1.5;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke}
  .sf-pag-estado .st-spark-pico{fill:var(--sf-dot);stroke:var(--sf-paper);stroke-width:1}
  .sf-pag-estado .st-spark-gris{stroke:var(--sf-line);stroke-width:2;stroke-dasharray:3 3;vector-effect:non-scaling-stroke}
  @media (max-width:640px){
    .sf-pag-estado .st-spark{width:72px;height:22px}
    .sf-pag-estado .st-cuadro{width:14px;height:14px}
  }

/* ── /status → .sf-pag-estado ── */
  .sf-pag-estado{margin:0;font-family:var(--sf-font);color:var(--sf-ink);background:var(--sf-soft);line-height:1.55;-webkit-font-smoothing:antialiased}
  .sf-pag-estado main h2{font-size:var(--sf-fs-18);margin:36px 0 12px}
  .sf-pag-estado .st-lead{color:var(--sf-mut);font-size:var(--sf-fs-16);margin:0 0 24px;max-width:62ch}
  .sf-pag-estado .st-global{display:flex;align-items:center;flex-wrap:wrap;gap:8px 14px;padding:18px 20px;border-radius:var(--sf-r-l);border:1px solid var(--sf-line);background:var(--sf-paper)}
  .sf-pag-estado .st-global b{font-size:var(--sf-fs-20)}
  .sf-pag-estado .st-global .st-cuando{color:var(--sf-mut);font-size:var(--sf-fs-13-5);margin-inline-start:auto}
  .sf-pag-estado .st-global-ok{background:var(--sf-ok-50);border-color:transparent}
  .sf-pag-estado .st-global-ok b{color:var(--sf-ok)}
  .sf-pag-estado .st-global-warn{background:var(--sf-warn-50);border-color:transparent}
  .sf-pag-estado .st-global-warn b{color:var(--sf-warn)}
  .sf-pag-estado .st-global-bad{background:var(--sf-bad-50);border-color:transparent}
  .sf-pag-estado .st-global-bad b{color:var(--sf-bad)}
  .sf-pag-estado .st-global-gris b{color:var(--sf-mut)}
  .sf-pag-estado .st-luz{width:12px;height:12px;border-radius:50%;flex:none;background:var(--sf-line)}
  .sf-pag-estado .st-global-ok .st-luz{background:var(--sf-ok)}
  .sf-pag-estado .st-global-warn .st-luz{background:var(--sf-dot)}
  .sf-pag-estado .st-global-bad .st-luz{background:var(--sf-bad)}
  .sf-pag-estado .st-lista{list-style:none;margin:0;padding:0;background:var(--sf-paper);border:1px solid var(--sf-line);border-radius:var(--sf-r-l)}
  .sf-pag-estado .st-comp{position:relative;padding:16px 20px}
  .sf-pag-estado .st-comp + .st-comp{border-top:1px solid var(--sf-line)}
  .sf-pag-estado .st-comp-cab{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;margin-bottom:10px}
  .sf-pag-estado .st-comp-cab b{margin-inline-end:auto;overflow-wrap:anywhere}
  .sf-pag-estado .st-comp-cab .sf-pill{gap:6px}
  .sf-pag-estado .st-lat{color:var(--sf-mut);font-size:var(--sf-fs-13);font-family:var(--sf-mono)}
  .sf-pag-estado .st-nota{display:flex;align-items:center;gap:6px;margin:-4px 0 10px;color:var(--sf-mut);font-size:var(--sf-fs-13-5)}
  .sf-pag-estado .st-nota-ambar{color:var(--sf-warn)}
  .sf-pag-estado .st-barra-pie{display:flex;justify-content:space-between;gap:10px;margin-top:6px;color:var(--sf-mut);font-size:var(--sf-fs-12-5)}
  .sf-pag-estado .st-disp{text-align:center}
  .sf-pag-estado .st-disp b{color:var(--sf-ink);font-weight:600}
  .sf-pag-estado .st-leyenda{display:flex;flex-wrap:wrap;gap:6px 16px;margin:12px 0 0;padding:0;list-style:none;color:var(--sf-mut);font-size:var(--sf-fs-13)}
  .sf-pag-estado .st-leyenda li{display:flex;align-items:center;gap:6px}
  .sf-pag-estado .st-leyenda .st-dia{flex:none;width:10px;height:14px}
  .sf-pag-estado .st-nada{color:var(--sf-mut);margin:0}
  .sf-pag-estado .st-inc h3{margin:0 0 6px;font-size:var(--sf-fs-16);display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;overflow-wrap:anywhere}
  .sf-pag-estado .st-afecta{margin:0 0 8px;color:var(--sf-mut);font-size:var(--sf-fs-14)}
  .sf-pag-estado .st-act{margin:0;padding-inline-start:18px;font-size:var(--sf-fs-14-5)}
  .sf-pag-estado .st-act li{margin-bottom:6px;overflow-wrap:anywhere}
  .sf-pag-estado .st-act time{color:var(--sf-mut);font-family:var(--sf-mono);font-size:var(--sf-fs-12-5)}
  .sf-pag-estado main a{color:var(--brand,var(--sf-brand))}
  .sf-pag-estado .vd-punto:focus-visible{outline:2px solid var(--acc,var(--sf-acc));outline-offset:3px}
  @media (max-width:640px){
    .sf-pag-estado .st-global .st-cuando{margin-inline-start:0;flex-basis:100%}
    .sf-pag-estado .st-comp{padding:14px 16px}
    .sf-pag-estado .st-barra{gap:1px;height:26px}
    .sf-pag-estado .st-barra-pie{flex-wrap:wrap}
    .sf-pag-estado .st-disp{order:3;flex-basis:100%;text-align:start}
  }

/* El changelog, el validador en marco y lo que sobra del cuerpo propio de cada página. */
.sf-portal-linea-propia{margin:0;padding-block:12px;color:var(--sf-mut);font-size:var(--sf-fs-14)}

/* ── /docs/changelog → .sf-pag-novedades ── */
  .sf-pag-novedades .cl-dia{margin-block-end:34px}
  .sf-pag-novedades .cl-dia h2{font-size:var(--sf-fs-18);margin:0 0 12px;color:var(--sf-mut)}
  .sf-pag-novedades .cl-entrada h3{margin:0 0 6px;font-size:var(--sf-fs-18);line-height:1.3}
  .sf-pag-novedades .cl-entrada h3 a{color:var(--sf-ink);text-decoration:none}
  .sf-pag-novedades .cl-entrada h3 a:hover{text-decoration:underline}
  .sf-pag-novedades .cl-entrada p{margin:0 0 8px}
  .sf-pag-novedades .cl-area{font-size:var(--sf-fs-12);letter-spacing:.06em;text-transform:uppercase;color:var(--sf-mut);margin:0 0 6px}
  .sf-pag-novedades .cl-imagen{margin:12px 0 0}
  .sf-pag-novedades .cl-imagen img{max-width:100%;height:auto;border:1px solid var(--sf-line);border-radius:var(--sf-r-s)}

/* ── lo que eran `style=""` sueltos en /demo y /api ── */
  .sf-pag-demo .puerta-fila{margin-top:18px;display:flex;gap:10px;align-items:center}
  .sf-pag-demo .puerta-msg{color:var(--acc,var(--sf-acc));font-size:var(--sf-fs-14)}
  .sf-pag-demo .col-estado{width:180px}
  .sf-pag-api .eventos{margin-top:8px}
  .sf-pag-api .eventos-titulo{margin:0 0 6px;font-size:var(--sf-fs-26);letter-spacing:-.02em}
  .sf-pag-api .eventos-intro{margin:0 0 20px;color:var(--sf-mut);max-width:72ch}
  .sf-pag-api .aviso-acc{border-left-color:var(--acc,var(--sf-acc));background:var(--acc-50,var(--sf-acc-50))}
  .sf-pag-api .col-evento{width:230px}
  .sf-pag-api .eventos-pie{margin:16px 0 0;color:var(--sf-mut);font-size:var(--sf-fs-14)}

/* ═══ Encargo 215 · FASE 0 · L4 (resto): las herramientas con la cabecera y el pie comunes (08-10-2026) ═══
   Lo propio de /evaluar, de la página que no existe y del laboratorio, que ya no viven en un `<style>`.
   La cabecera, el pie y el selector son los comunes (`sf-portal-*`, `src/portal/cabecera_y_pie.ts`);
   acá queda sólo el cuerpo, acotado por la clase de cada página. Sólo tokens `--sf-*`: ni colores ni
   tamaños de letra sueltos (la guarda `la_cabecera_y_el_pie_son_comunes` lo vigila, punto 10). */

/* ── /evaluar → .sf-evaluar-main (las clases sin prefijo que emite el render de `src/compartir/`) ── */
  .sf-evaluar-main p{margin:12px 0}
  .sf-evaluar-main pre{overflow:auto;padding:18px;background:var(--sf-soft);border-radius:var(--sf-r-s)}
  .sf-evaluar-main code{font-family:var(--sf-mono);font-size:var(--sf-fs-codigo-en-linea);overflow-wrap:anywhere}
  .sf-evaluar-main table{border-collapse:collapse;width:100%;font-size:var(--sf-fs-15)}
  .sf-evaluar-main th,.sf-evaluar-main td{border-bottom:1px solid var(--sf-line);padding:12px;text-align:left;vertical-align:top}
  .sf-evaluar-main th{background:var(--brand-50,var(--sf-brand-50))}
  .sf-evaluar-main blockquote{margin:16px 0;padding:8px 16px;border-left:4px solid var(--brand,var(--sf-brand));background:var(--brand-50,var(--sf-brand-50))}
  .sf-evaluar-main hr{border:0;border-top:1px solid var(--sf-line);margin:24px 0}
  .sf-evaluar-main .tabla{overflow:auto;margin:14px 0}
  .sf-evaluar-main .punto{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--sf-dot);margin-right:8px;vertical-align:middle}
  .sf-evaluar-main .gris td{color:var(--sf-mut)}
  .sf-evaluar-main .puertas{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin:22px 0}
  .sf-evaluar-main .puerta{border:1px solid var(--sf-line);border-left:4px solid var(--brand,var(--sf-brand));border-radius:var(--sf-r-s);padding:4px 20px 16px}
  .sf-evaluar-main .puerta h3{margin:16px 0 8px;font-size:var(--sf-fs-evaluar-puerta-titulo)}
  .sf-evaluar-main .puerta dl{margin:0}
  .sf-evaluar-main .puerta dt{font-size:var(--sf-fs-13);font-weight:bold;text-transform:uppercase;letter-spacing:.04em;color:var(--sf-mut);margin-top:12px}
  .sf-evaluar-main .puerta dd{margin:2px 0 0}
  .sf-evaluar-main .fuera{border-left:4px solid var(--sf-mut);padding:14px 18px;background:var(--sf-soft);margin:14px 0}
  .sf-evaluar-main .fuera h3{margin-top:0}
  .sf-evaluar-main .resumen{margin:16px 0 24px;padding:4px 18px 14px;border-left:4px solid var(--brand,var(--sf-brand));background:var(--sf-brand-50);border-radius:0 var(--sf-r-resumen) var(--sf-r-resumen) 0}
  .sf-evaluar-main .resumen dt{font-size:var(--sf-fs-12);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--sf-mut);margin:12px 0 2px}
  .sf-evaluar-main .resumen dd{margin:0}
  @media(max-width:760px){.sf-evaluar-main .puertas{grid-template-columns:minmax(0,1fr)}}
  @media(min-width:700px){.sf-evaluar-main .resumen{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 20px;padding:14px 18px}.sf-evaluar-main .resumen dt{margin:0;padding-top:3px}}
  @media print{.sf-evaluar-main pre{white-space:pre-wrap}.sf-evaluar-main .resumen{break-inside:avoid}}

/* ── la página que no existe → .sf-pag-no-encontrada (el título y el enlace son los del portal) ── */
  .sf-pag-no-encontrada .sf-portal-main{padding-block:60px}

/* ── laboratorio.html → .sf-pag-laboratorio ── */
  .sf-pag-laboratorio .sf-btn{margin-block-start:12px;margin-inline-end:8px}
  .sf-pag-laboratorio .sf-portal-main p{color:var(--sf-mut)}
  .sf-pag-laboratorio :focus-visible{outline:3px solid var(--brand,var(--sf-brand));outline-offset:3px}
  .sf-pag-laboratorio .lab-estado{white-space:pre-wrap}
  .sf-pag-laboratorio .lab-insignia{color:var(--brand,var(--sf-brand));font-weight:700;font-size:var(--sf-fs-13);letter-spacing:1px;text-transform:uppercase}
  .sf-pag-laboratorio .lab-salida{white-space:pre-wrap;overflow-wrap:anywhere}
  .sf-pag-laboratorio .lab-secreto{white-space:pre-wrap;overflow-wrap:anywhere;user-select:all}

/* ═══ SEG1 · El seguimiento del emisor (a quién se espera) ═══
   Arriba de la lista de Documents: una caja plegable con una fila por persona.
   En el teléfono la fila se apila (quién, estado, acción); desde 768 px, en una
   línea. Los 44 px del toque están en el bloque `pointer: coarse` de arriba. */
.sf-espera{margin:0 0 14px;border:1px solid var(--sf-line);border-radius:var(--sf-r);background:var(--sf-paper)}
.sf-espera>summary{display:flex;align-items:center;padding:8px 14px;font-weight:600;cursor:pointer}
.sf-espera-lista{list-style:none;margin:0;padding:0}
.sf-espera-fila{display:grid;gap:8px;padding:12px 14px;border-block-start:1px solid var(--sf-line)}
.sf-espera-quien{display:grid;gap:2px;min-width:0;overflow-wrap:anywhere}
.sf-espera-quien span{color:var(--sf-mut);font-size:var(--sf-fs-13)}
.sf-espera-estado{display:grid;gap:4px;justify-items:start}
.sf-espera-estado small{color:var(--sf-mut);font-size:var(--sf-fs-12-5)}
.sf-espera-fila .acc{justify-self:start}
@media (min-width:768px){
  .sf-espera-fila{grid-template-columns:minmax(0,1.2fr) minmax(0,1.6fr) auto;align-items:center}
  .sf-espera-fila .acc{justify-self:end}
}

/* Controles táctiles de /docs/verifier (encargo W0b): a 44 px en pantalla angosta. Sólo lo propio de esa página (`.sf-tactil`);
   el menú y el pie comunes los sube su propia regla. El ● conserva su tamaño visible y agranda el área (relleno + `background-clip`). */
@media (max-width:640px){
  .sf-tactil a,a.sf-tactil{display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px;padding-inline:8px;box-sizing:border-box}
  .sf-tactil .vd-punto{box-sizing:content-box;padding:18px;background-clip:content-box}
}

/* ═══ You → Your wallet: la lista de billeteras conectadas ═══
   Una fila por billetera (hoy una, o cero): los datos a la izquierda, «Disconnect» a la derecha desde 768 px;
   en el teléfono se apila y el botón queda debajo, de 44 px. */
.sf-billeteras{list-style:none;margin:0 0 12px;padding:0;border:1px solid var(--sf-line);border-radius:var(--sf-r);background:var(--sf-paper)}
.sf-billetera-fila{display:grid;gap:8px;padding:12px 14px;border-block-start:1px solid var(--sf-line)}
.sf-billetera-fila:first-child{border-block-start:0}
.sf-billetera-datos{display:grid;gap:2px;min-width:0;overflow-wrap:anywhere}
.sf-billetera-datos span{color:var(--sf-mut);font-size:var(--sf-fs-13)}
.sf-billetera-fila .sf-btn{justify-self:start}
@media (min-width:768px){
  .sf-billetera-fila{grid-template-columns:minmax(0,1fr) auto;align-items:center}
  .sf-billetera-fila .sf-btn{justify-self:end}
}

/* ═══ El dosier en Documents (DOSIER-1) ═══
   Casillas en los borradores, la barra «N selected · Send together as a dossier»,
   la fila del dosier con sus hijos y el diálogo. Sólo existen cuando
   `GET /dosieres/disponible` dice que sí: sin eso, ninguna de estas clases se usa. */
.sf-dosier-marca{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;margin:-12px 2px -12px -12px;vertical-align:middle;cursor:pointer}
.sf-dosier-marca input{width:20px;height:20px;margin:0;cursor:pointer}
.sf-barra-dosier{display:flex;flex-wrap:wrap;align-items:center;gap:10px 12px;margin:0 18px 12px;padding:10px 14px;background:var(--sf-brand-50);border:1px solid var(--sf-line);border-radius:var(--sf-r)}
.sf-barra-dosier-n{font-weight:600;color:var(--sf-ink)}
.sf-barra-dosier-tope{flex-basis:100%;font-size:var(--sf-fs-13);color:var(--sf-mut)}
.sf-barra-dosier .sf-btn{min-height:44px}
@media (max-width:640px){.sf-barra-dosier{margin-inline:12px}.sf-barra-dosier .sf-btn{flex:1 1 100%}}
tr.sf-fila-dosier td{background:var(--sf-soft);border-top:2px solid var(--sf-line)}
tr.sf-hijo-dosier td:first-child{padding-inline-start:1.5rem;border-inline-start:3px solid var(--sf-line)}
.sf-dosier-orden{list-style:none;margin:0 0 12px;padding:0}
.sf-dosier-item{display:flex;align-items:center;gap:10px;padding:8px 10px;margin:0 0 6px;background:var(--sf-paper);border:1px solid var(--sf-line);border-radius:var(--sf-r-s);cursor:grab}
.sf-dosier-n{flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--sf-r-pill);background:var(--sf-brand-50);color:var(--sf-brand-700);font-weight:700}
.sf-dosier-doc{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.sf-dosier-mover{flex:none;display:inline-flex;gap:6px}
.sf-dosier-mover .sf-btn:disabled{opacity:.45}
.sf-dosier-quitar{display:flex;justify-content:flex-end}
.sf-dosier-pers{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 12px;align-items:end;margin:0 0 12px;padding:10px;border:1px solid var(--sf-line);border-radius:var(--sf-r-s)}
.sf-dosier-firma[hidden]{display:none}
.sf-dosier-pers input,.sf-dosier-pers select{width:100%;box-sizing:border-box}
@media (max-width:600px){.sf-dosier-pers{grid-template-columns:minmax(0,1fr)}}
.sf-dosier-recorrido{margin:12px 0;padding:0;border:0}
.sf-dosier-recorrido legend{padding:0;font-weight:600}
.sf-dosier-opcion{display:flex;align-items:center;gap:8px;min-height:44px;margin:0}
.sf-dosier-opcion input{width:20px;height:20px;margin:0}

/* DOSIER-1: la hoja del plan de Account → Plan and usage (#usoHoja). A 390 px la píldora larga («Not enabled in this installation») iba en una celda
   sin cortes y empujaba la tabla más allá del borde derecho: sólo esa tabla, sólo en pantallas angostas. */
@media (max-width:480px){#usoHoja td:has(> .sf-pill){white-space:normal!important}#usoHoja .sf-pill{white-space:normal;max-width:100%}}

/* DOS-FIX-1: dos cortes que escondía lo que se medía mal (la guía de métodos: un desborde se confirma con scrollWidth; un corte, buscando overflow:hidden con contenido más ancho).
   (1) /features, interruptor apagado: la píldora de la tarjeta del dosier lleva la causa entera en una frase y no partía línea: salía de la tarjeta y
   desbordaba la página. Sólo la píldora de la fila de estado de una tarjeta de /features.
   (2) Account → Plan and usage, a 390 px: `main` recorta (overflow-x:hidden) y la tabla de la hoja era más ancha (515 contra 390): la columna de
   precios (y las de uso y precios de al lado) quedaba cortada. Cada tabla de Plan and usage scrollea dentro de SU contenedor; acotado a #usoCuerpo. */
.sf-fn-estado .sf-pill{white-space:normal;max-width:100%;overflow-wrap:anywhere;text-align:start}
.sf-card #usoCuerpo table{display:block;max-width:100%;overflow-x:auto}

/* Z4: tamaños táctiles */
/* ═══ Del tamaño de un dedo, en toda la hoja (`pointer: coarse`) ═══ (09-10-2026, Z4)
   Con un puntero grueso —un dedo— lo que se toca llega a los 44 px que pide la
   regla de toque (medido en Z0, docs/diseno/sobrecarga/telefono.md). TODO lo de
   este bloque vive adentro de la consulta: con un puntero fino (el ratón) la
   hoja es la de siempre, y una prueba lo vigila
   (`test/los_tamanos_tactiles_son_solo_para_el_dedo.test.ts`).
   · Botones (`sf-btn`, también los chicos) y el menú: 44 px de alto como mínimo.
   · Casillas y botones de opción: el control mide 24 px y el área que se toca es
     la de su `label`, que mide 44 de alto. Cuelgan de `.sf-js` (la clase que
     pone `componentes.js` en `<html>`) y no de un elemento suelto: la prueba
     «todo selector cuelga de una clase sf-» no deja otra puerta, y esas
     pantallas no tienen una clase `sf-` propia en sus casillas.
   · El «more»: se ve de 32 px y se toca en 44 (el área de más es transparente).
   · El selector de idioma conserva su aspecto de 30 px: el área de 44 la pone
     un pseudo-elemento. */
@media (pointer: coarse) {
  .sf-btn,.sf-btn.sf-chico,.sf-btn.sf-grande{min-height:44px}
  .sf-btn.sf-chico{min-width:44px}
  .sf-espera>summary{min-height:44px}
  .sf-menu-boton{min-height:44px;min-width:44px}
  .sf-idioma .sf-idioma-boton{position:relative}
  .sf-idioma .sf-idioma-boton::after{content:"";position:absolute;inset-block:-7px;inset-inline:0}
  .sf-js input[type="checkbox"],.sf-js input[type="radio"]{width:24px;height:24px}
  .sf-js label:has(> input[type="checkbox"]),.sf-js label:has(> input[type="radio"]){display:flex;align-items:center;box-sizing:border-box;min-height:44px}
  .sf-mas-boton{display:inline-flex;align-items:flex-end;box-sizing:border-box;min-height:44px;padding-block-end:6px;
    background-repeat:no-repeat;background-position:bottom;background-size:100% 32px}
  .sf-mas:not(.sf-mas-abierto):has(> .sf-mas-boton:not([hidden])){min-height:44px}
}


/* ═══ Las páginas por audiencia de /docs (DOC1b) ═══ */
.sf-audiencia-figura{margin:24px 0}
.sf-audiencia-diagrama{display:block;max-width:100%;height:auto;border-radius:8px}
.sf-audiencia-pasos{list-style:none;padding:0;margin:0}
