/* ============================================================================
   es-vl — Sistema «Expediente»
   ----------------------------------------------------------------------------
   La vida laboral es una CRONOLOGÍA: la lista ordenada de todo lo que has
   trabajado. Todo el sistema sale de esa metáfora: líneas de tiempo, filas de
   registro, cifras alineadas. Sobrio y documental.

   ⭐ POR QUÉ ÍNDIGO Y ÁMBAR, Y NO AZUL. Se midieron las paletas reales de los
   CSS de producción del nicho (2026-08-24):
     · Sede Electrónica SS ......... #3568a4 #3e74b4 #cc0000
     · Sede, tema «grafito» ........ #046080 #034D66 #4EC3CD #CDDFE6
     · vidalaboral.org.es (comp.) .. #0095b6 #08ada7 #ffcc00
   TODO el nicho vive en la misma familia azul-cian-turquesa: el oficial y el
   competidor principal usan casi el mismo color y nadie tiene identidad propia.
   Salir de esa familia resuelve dos cosas a la vez: se nos ve en un SERP donde
   todos los favicon son cian, y no parecemos oficiales — que es la restricción
   dura del portfolio (sitio YMYL no oficial de un trámite oficial).
   ⛔ No volver al azul-cian «porque queda institucional». Es justo lo que no
   podemos parecer.

   Objetivo CWV: el sitio viejo servía 305 KB de HTML para 623 palabras, con
   126 KB de JS inline, jQuery y Bootstrap. Acá: una hoja, cero frameworks,
   iconos SVG en sprite, JS por página y diferido.
   ============================================================================ */

/* ---------- 0. Fuentes ------------------------------------------------------
   Source Sans 3 SELF-HOSTEADA. Humanista, aguanta texto administrativo denso y
   tiene cifras tabulares de verdad, que hacen falta en las siete herramientas y
   en todas las tablas.
   Los @font-face van DENTRO de esta hoja (que ya es bloqueante) a propósito: es
   la condición para que `font-display:optional` funcione — si la fuente no llegó
   a tiempo, el navegador se queda con el fallback para TODO el render y no hace
   swap, así que el CLS por fuente es cero.
   ⛔ NO volver a `swap` ni a un <link> a Google Fonts: las dos variantes se
   midieron en mx-imss y mx-issste y las dos mueven la página.
   Se regeneran con:
     sb-tools/dev/self-host-font.py es-vl "Source+Sans+3:ital,wght@0,400..700;1,400"
   Detalle: sb-docs/conventions/fuentes-self-hosted.md
---------------------------------------------------------------------------- */
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:400 700;font-display:optional;
  src:url(/assets/fonts/source-sans-3-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:'Source Sans 3';font-style:normal;font-weight:400 700;font-display:optional;
  src:url(/assets/fonts/source-sans-3-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:'Source Sans 3';font-style:italic;font-weight:400;font-display:optional;
  src:url(/assets/fonts/source-sans-3-italic-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}
/* Fallback con métricas ajustadas: ocupa el mismo espacio que Source Sans 3, así que si
   la webfont no llega no hay reflow. ⚠️ En Linux y Android `local('Arial')` no resuelve y
   la regla se descarta; la defensa real contra el CLS es `optional`, no esto. */
@font-face{font-family:'SS3 fb';src:local('Arial'),local('Helvetica'),local('sans-serif');
  size-adjust:96.5%;ascent-override:104%;descent-override:29%;line-gap-override:0%}

/* ---------- 1. Tokens ---------------------------------------------------- */
:root{
  /* Marca: índigo-violeta. Fuera de la familia azul-cian de todo el nicho. */
  --brand:#35306B; --brand-d:#262252; --brand-l:#4A4390; --brand-br:#5C54A8;

  /* Acento ámbar: cálido, documental. No colisiona con el #ffcc00 del competidor
     ni con ningún amarillo institucional español.
     --accent-t es el ámbar para TEXTO sobre fondo claro (el --accent no llega a
     contraste AA en 17px); --accent-o es el ámbar sobre fondo oscuro. */
  --accent:#C77B2A; --accent-d:#A9651D; --accent-t:#8F5417; --accent-o:#E8A75A;
  --accent-bg:#FBF2E6; --accent-bg-2:#FDF9F3; --accent-bd:#EBD6B8;

  /* Semánticos. Separados del acento a propósito: el color de estado no puede ser
     el mismo que el de marca o deja de comunicar estado. */
  --ok:#1C7A4B; --info:#2F4E9E; --warn:#8A5C08; --danger:#A3271F;
  --ok-bg:#EAF6EF; --info-bg:#EEF1FA; --warn-bg:#FDF4E3; --danger-bg:#FBECEA;
  --ok-bd:#BFE3CD; --info-bd:#CFD8F0; --warn-bd:#F0DDB0; --danger-bd:#F0CDC8;

  /* Neutros con sesgo hacia el índigo: elegidos, no heredados de un gris puro. */
  --bg:#F5F4F9; --surface:#FFF; --surface-alt:#FAFAFD; --tile:#EEECF6;
  --ink:#1E1B33; --soft:#4A4661; --muted:#6e6a84;
  --border:#E0DDEC; --border-2:#EFEDF5; --track:#E4E1EE;

  /* Forma */
  --r-bar:6px; --r-s:10px; --r:14px; --r-l:16px; --r-xl:18px; --r-cta:20px; --r-pill:999px;

  --sh-1:0 1px 2px rgba(38,34,82,.05);
  --sh-2:0 1px 2px rgba(38,34,82,.05),0 12px 30px -18px rgba(38,34,82,.22);
  --sh-3:0 20px 44px -26px rgba(38,34,82,.85);
  --sh-accent:0 12px 26px -20px rgba(199,123,42,.7);

  --wrap:1120px; --pad:24px;

  /* Tokens que consume la hoja de herramientas de sb-lib. Se mapean UNA vez: la librería no
     conoce la paleta de ningún sitio. sb-docs/conventions/herramientas-ux.md */
  --sb-brand:var(--brand); --sb-brand-d:var(--brand-d); --sb-brand-l:var(--brand-l);
  --sb-brand-bd:var(--brand-bd);
  --sb-accent:var(--accent); --sb-accent-d:var(--accent-d); --sb-accent-o:var(--accent-o);
  --sb-accent-bg:var(--accent-bg); --sb-accent-bd:var(--accent-bd);
  --sb-track:var(--track);
  --font:'Source Sans 3','SS3 fb',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
}

/* ---------- 2. Reset / base ---------------------------------------------- */
*{box-sizing:border-box}
/* El display:none que el navegador da a [hidden] pierde contra cualquier regla de autor
   con display. Se fuerza una vez para todo el sitio en vez de recordarlo por componente. */
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{animation-duration:.01ms!important;transition-duration:.01ms!important}}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);font-size:17px;
  line-height:1.65;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}

h1,h2,h3,h4{margin:0 0 .5em;color:var(--brand-d);text-wrap:balance}
h1{font-weight:700;font-size:clamp(30px,3.8vw,42px);line-height:1.08;letter-spacing:-.022em}
h2{font-weight:700;font-size:31px;line-height:1.15;letter-spacing:-.015em}
h3{font-weight:600;font-size:20px;line-height:1.28}
h4{font-weight:600;font-size:17.5px;line-height:1.3}
@media (max-width:640px){h1{font-size:28px;line-height:1.12}h2{font-size:24px}h3{font-size:19px}}
p{margin:0 0 1em;text-wrap:pretty}
p:last-child,ul:last-child,ol:last-child{margin-bottom:0}
a{color:var(--accent-t);text-underline-offset:2px}
a:hover{color:var(--accent-d)}
strong{font-weight:700}
ul,ol{margin:0 0 1em;padding-left:1.25em}
li{margin-bottom:.4em}
li::marker{color:var(--muted)}
img{max-width:100%;height:auto}
code,kbd{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;
  background:var(--tile);padding:.12em .38em;border-radius:3px;color:var(--soft)}
hr{border:0;border-top:1px solid var(--border);margin:2em 0}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;background:var(--brand-d);color:#fff;padding:10px 16px;z-index:100;border-radius:0 0 var(--r-s) 0}
.skip:focus{left:0}

.container,.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--pad)}
@media (max-width:640px){:root{--pad:18px}}

/* Rótulo en versalitas: el patrón que se repite arriba de cada bloque de dato. */
.eyebrow{font:700 12px/1 var(--font);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0 0 .6em}
.eyebrow--acento{color:var(--accent-t)}
.figure-xl{font-weight:700;letter-spacing:-.025em;font-variant-numeric:tabular-nums;line-height:1}
.muted{color:var(--muted)}
.tnum{font-variant-numeric:tabular-nums}

/* ---------- 3. Header / nav ---------------------------------------------- */
.site-head{background:var(--surface);border-bottom:1px solid var(--border);position:relative;z-index:20}
.site-head__in{display:flex;align-items:center;gap:18px;padding:12px 0;max-width:var(--wrap);margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--brand-d);font-weight:700;font-size:19px;letter-spacing:-.01em;flex:none}
.brand img,.brand svg{height:34px;width:auto;display:block}
.nav{display:flex;gap:4px;margin-left:auto;align-items:center}
.nav a{padding:8px 12px;border-radius:var(--r-s);text-decoration:none;color:var(--soft);font-weight:600;font-size:15px;white-space:nowrap}
.nav a:hover{background:var(--tile);color:var(--brand-d)}
.nav a[aria-current=page]{color:var(--brand-d);background:var(--tile)}
.nav-toggle{display:none;margin-left:auto;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-s);padding:8px 12px;font:600 15px/1 var(--font);color:var(--brand-d);cursor:pointer;align-items:center;gap:8px}
@media (max-width:860px){
  .nav-toggle{display:inline-flex}
  .nav{display:none;position:absolute;top:100%;left:0;right:0;background:var(--surface);
    border-bottom:1px solid var(--border);flex-direction:column;gap:0;padding:8px var(--pad) 14px;box-shadow:var(--sh-2)}
  .nav[data-open]{display:flex}
  .nav a{padding:11px 12px;font-size:16px}
}

/* ---------- 4. Hero / slab ------------------------------------------------
   El .slab es el bloque oscuro del sistema. Las dos capas decorativas dicen algo:
   ::before son los renglones de un registro; ::after es la línea de tiempo que
   recorre el lateral. Es la metáfora del sitio, no adorno genérico. */
.slab{background:var(--brand-d);color:#F2F0FC;position:relative;overflow:hidden}
.slab::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(180deg,transparent 0 38px,rgba(255,255,255,.045) 38px 39px)}
.slab::after{content:"";position:absolute;left:calc(var(--pad) - 2px);top:0;bottom:0;width:2px;pointer-events:none;
  background:linear-gradient(180deg,transparent,rgba(199,123,42,.55) 18%,rgba(199,123,42,.55) 82%,transparent)}
.slab .container{position:relative;z-index:1}
.slab h1,.slab h2,.slab h3{color:#fff}
.slab a{color:var(--accent-o)}

/* OJO: `padding-block`, NO el atajo `padding: X 0 Y`. El atajo fija también el horizontal
   en 0 y pisa el `padding:0 var(--pad)` de .container (misma especificidad, va después),
   con lo que el hero quedaba pegado a los bordes. Sólo se veía por debajo de 1120px, así
   que en un escritorio ancho el fallo era invisible. */
.hero{padding-block:clamp(34px,5.5vw,62px) clamp(28px,4.5vw,48px)}
.hero__lede{font-size:1.13rem;line-height:1.55;color:#CFCAE8;max-width:60ch;margin:0 0 1em}
.hero__lede strong{color:#fff}
.hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:18px}
.updated{display:flex;align-items:center;gap:8px;font-size:13.5px;color:#A9A2CF;margin:14px 0 0}
.updated__dot{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:none;box-shadow:0 0 0 3px rgba(28,122,75,.22)}
/* La banda clara NO añade padding propio: el padding vertical ya lo pone .hero, que va en
   el <div> de dentro. Ponerlo en los dos duplicaba el hueco superior (se vio en la captura
   de /como-leer-el-informe-de-vida-laboral). Aquí sólo se ajusta la escala de .hero. */
/* La variante clara del hero se retiró el 2026-08-24: todas las páginas llevan la banda
   oscura. Si vuelve a hacer falta una clara, se declara aquí y NO se le pone padding
   vertical propio (el de .hero ya lo pone, y ponerlo en los dos duplicaba el hueco). */
.hero--content .hero__lede{color:var(--soft)}
.hero--content .hero__lede strong{color:var(--ink)}
.hero--content .updated{color:var(--muted)}

/* ---------- 5. Migas ------------------------------------------------------ */
.breadcrumbs{font-size:13.5px;margin:0 0 14px;color:var(--muted)}
.breadcrumbs ol{list-style:none;display:flex;flex-wrap:wrap;gap:6px;margin:0;padding:0}
.breadcrumbs li::after{content:"›";margin-left:6px;color:var(--muted)}
.breadcrumbs li:last-child::after{content:""}
.breadcrumbs a{color:var(--muted);text-decoration:none}
.breadcrumbs a:hover{color:var(--accent-t);text-decoration:underline}
.slab .breadcrumbs,.slab .breadcrumbs a,.slab .breadcrumbs li::after{color:#A9A2CF}
.slab .breadcrumbs a:hover{color:var(--accent-o)}

/* ---------- 6. Secciones y paneles --------------------------------------- */
main{display:block}
.secc{margin:clamp(30px,4.4vw,52px) 0}
.secc--corta{margin:clamp(22px,3vw,34px) 0}
.panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-l);
  padding:clamp(18px,2.6vw,26px);box-shadow:var(--sh-1)}
.panel--flat{box-shadow:none}
.section-head{margin:0 0 18px}
.section-head p{color:var(--soft);margin:0}
.prosa > *:last-child{margin-bottom:0}

/* ---------- 7. Botones ---------------------------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  padding:11px 20px;border-radius:var(--r-s);font:600 16px/1.25 var(--font);
  text-decoration:none;cursor:pointer;border:1px solid transparent;transition:background .15s,border-color .15s,color .15s}
.btn--primary{background:var(--brand);color:#fff}
.btn--primary:hover{background:var(--brand-d);color:#fff}
/* ⚠️ `--accent-d`, NO `--accent`. Blanco sobre `--accent` (#C77B2A) da 3,34:1 y AA pide 4,5
   para texto normal: el botón principal del sitio no pasaba. La paleta ya avisa arriba de que
   `--accent` no sirve para texto; el token bueno ya existía y era éste (4,66:1). */
.btn--accent{background:var(--accent-d);color:#fff;box-shadow:var(--sh-accent)}
.btn--accent:hover{background:var(--accent-t);color:#fff}
.btn--ghost{background:transparent;color:var(--brand-d);border-color:var(--border)}
.btn--ghost:hover{background:var(--tile);color:var(--brand-d)}
.slab .btn--ghost{color:#fff;border-color:rgba(255,255,255,.32)}
.slab .btn--ghost:hover{background:rgba(255,255,255,.1);color:#fff}
.btn--xl{padding:14px 26px;font-size:17px}
.btn--block{width:100%}
.btn[disabled]{opacity:.5;cursor:not-allowed}

/* ---------- 8. Tarjetas --------------------------------------------------- */
.cards{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(238px,1fr))}
.card{display:flex;flex-direction:column;gap:7px;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-l);padding:18px 20px;text-decoration:none;color:inherit;box-shadow:var(--sh-1);
  transition:border-color .15s,box-shadow .15s,transform .15s}
a.card:hover{border-color:var(--brand-br);box-shadow:var(--sh-2);transform:translateY(-1px)}
.card__t{font-weight:700;font-size:17px;color:var(--brand-d);line-height:1.3}
.card__d{font-size:14.5px;color:var(--soft);line-height:1.5;margin:0}
.card__meta{margin-top:auto;padding-top:8px;font-size:12.5px;color:var(--muted);
  font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.card--tool{border-color:var(--accent-bd);background:var(--accent-bg-2)}
.card--tool .card__meta{color:var(--accent-t)}

/* ---------- 9. Avisos ----------------------------------------------------- */
.callout{display:grid;grid-template-columns:auto 1fr;gap:0 13px;align-items:start;
  padding:15px 18px;border-radius:var(--r);border:1px solid var(--border);
  border-left-width:3px;background:var(--surface);margin:0 0 1.1em}
.callout__i{flex:none;width:20px;height:20px;margin-top:2px}
.callout p{margin:0;font-size:.97rem}
.callout p+p,.callout ul{margin-top:.6em}
.callout--info{border-color:var(--info-bd);border-left-color:var(--info);background:var(--info-bg)}
.callout--info .callout__i{color:var(--info)}
.callout--ok{border-color:var(--ok-bd);border-left-color:var(--ok);background:var(--ok-bg)}
.callout--ok .callout__i{color:var(--ok)}
.callout--warn{border-color:var(--warn-bd);border-left-color:var(--warn);background:var(--warn-bg)}
.callout--warn .callout__i{color:var(--warn)}
.callout--danger{border-color:var(--danger-bd);border-left-color:var(--danger);background:var(--danger-bg)}
.callout--danger .callout__i{color:var(--danger)}
.callout--key{border-color:var(--accent-bd);border-left-color:var(--accent);background:var(--accent-bg)}
.callout--key .callout__i{color:var(--accent-d)}

/* ---------- 10. Tablas ---------------------------------------------------- */
/* Toda tabla ancha scrollea DENTRO de su contenedor: el body nunca scrollea de lado. */
.tabla{overflow-x:auto;border:1px solid var(--border);border-radius:var(--r);background:var(--surface);margin:0 0 1.2em}
.tabla table{border-collapse:collapse;width:100%;font-size:15px}
.tabla caption{caption-side:top;text-align:left;padding:12px 16px;border-bottom:1px solid var(--border);
  font:700 12px/1.4 var(--font);letter-spacing:.09em;text-transform:uppercase;color:var(--muted);background:var(--surface-alt)}
.tabla th,.tabla td{padding:9px 15px;text-align:left;border-bottom:1px solid var(--border-2);vertical-align:top}
.tabla thead th{font:700 12px/1.4 var(--font);letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);border-bottom:1px solid var(--border);white-space:nowrap}
.tabla tbody tr:last-child td{border-bottom:none}
.tabla .n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.tabla--zebra tbody tr:nth-child(even) td{background:var(--surface-alt)}
/* ⚠️ LA FILA DESTACADA VA DESPUÉS DE LA CEBRA Y CON SU MISMA ESPECIFICIDAD. Si no, cuando cae
   en una fila PAR gana la cebra y el resaltado desaparece — justamente en la fila que el lector
   viene a buscar (el año en curso). Pasaba en la tabla de la DT 7.ª: 2026 es la sexta fila. */
.tabla tr.destaca td,
.tabla--zebra tbody tr.destaca td{background:var(--accent-bg)}

/* ── Tablas que no caben ────────────────────────────────────────────────────
   Dos respuestas, y la primera es la buena:

   1. APILAR (`.tabla--apilada`). Cada fila pasa a ser una tarjeta con sus pares
      etiqueta/valor. Se ve TODO, sin scroll y sin que ninguna columna quede escondida.
      Es lo que se aplica a las tablas anchas en móvil.
   2. DESLIZAR, sólo para las que ni apiladas funcionan (muchas columnas numéricas que
      se leen comparando). Ahí el aviso y la sombra avisan de que hay más a la derecha.

   La sombra va `inset`: en un contenedor con scroll queda pegada al borde y no se va con el
   contenido. Ambas señales las pone el JS y sólo cuando el ancho real desborda. */
.tabla.desborda:not(.al-final){box-shadow:inset -17px 0 14px -14px rgba(30,27,51,.28)}

/* La etiqueta de cada celda sale de su propio <th> (la pone el JS en `data-label`), así que
   no hay que duplicar los encabezados en el marcado ni mantenerlos sincronizados a mano. */
.tabla--apilada{overflow-x:visible}
.tabla--apilada table{width:100%;display:block}
/* Con la tabla en `display:block` el <caption> hereda el ancho de la primera columna y sale
   estrujado en una tira de texto vertical. Hay que devolverle el ancho completo. */
.tabla--apilada caption{display:block;width:auto}
.tabla--apilada thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.tabla--apilada tbody,.tabla--apilada tr,.tabla--apilada td{display:block;width:auto}
.tabla--apilada tr{padding:13px 15px;border-bottom:1px solid var(--border)}
.tabla--apilada tbody tr:last-child{border-bottom:0}
.tabla--apilada td{padding:3px 0;border:0;display:grid;
  grid-template-columns:minmax(84px,36%) 1fr;gap:12px;align-items:baseline}
.tabla--apilada td::before{content:attr(data-label);font:700 11px/1.5 var(--font);
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.tabla--apilada td:empty{display:none}
/* La primera celda es el identificador de la fila: manda, y no necesita su etiqueta. */
.tabla--apilada td:first-child{grid-template-columns:1fr;font-weight:700;color:var(--brand-d);
  font-size:16px;padding-bottom:7px}
.tabla--apilada td:first-child::before{display:none}
.tabla--apilada .n{text-align:left}
.tabla--apilada tr.destaca{background:var(--accent-bg)}
/* `--accent-t` y no `--accent-d`: como TEXTO sobre el ámbar claro, `--accent-d` da 4,14:1.
   La paleta ya distingue los dos tokens justamente por esto. */
.tabla--apilada tr.destaca td:first-child{color:var(--accent-t)}
.tabla-desliza{display:flex;align-items:center;gap:6px;margin:-.7em 0 1.2em;
  font:600 13px/1.4 var(--font);color:var(--muted)}
.tabla-desliza svg{width:15px;height:15px;flex:none}
@media (prefers-reduced-motion:no-preference){
  .tabla-desliza svg{animation:sb-desliza 1.9s ease-in-out infinite}
}
@keyframes sb-desliza{0%,60%,100%{transform:translateX(0)}30%{transform:translateX(4px)}}

/* ---------- 11. Estadísticas --------------------------------------------- */
.stat-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:1px;
  background:var(--border);border:1px solid var(--border);border-radius:var(--r);overflow:hidden}
.stat{background:var(--surface);padding:15px 17px;display:flex;flex-direction:column;gap:2px}
.stat__l{font:700 12px/1.3 var(--font);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.stat__n{font-size:1.7rem;font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums;letter-spacing:-.02em;color:var(--brand-d)}
.stat__n--acento{color:var(--accent-t)}
.stat__d{font-size:13px;color:var(--muted);line-height:1.4}
.slab .stat-row{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.14)}
.slab .stat{background:rgba(255,255,255,.05)}
.slab .stat__l,.slab .stat__d{color:#A9A2CF}
.slab .stat__n{color:#fff}
.slab .stat__n--acento{color:var(--accent-o)}

/* ---------- 12. Pasos (alimentan el schema HowTo) ------------------------ */
.pasos{list-style:none;counter-reset:paso;padding:0;margin:0 0 1.2em}
.paso{counter-increment:paso;position:relative;padding:0 0 22px 46px;margin:0}
.paso::before{content:counter(paso);position:absolute;left:0;top:0;width:30px;height:30px;
  border-radius:50%;background:var(--brand);color:#fff;display:grid;place-items:center;
  font:700 15px/1 var(--font);font-variant-numeric:tabular-nums}
/* La línea que une los pasos: es la misma cronología del hero, a otra escala. */
.paso::after{content:"";position:absolute;left:15px;top:34px;bottom:4px;width:1px;background:var(--border)}
.paso:last-child{padding-bottom:0}
.paso:last-child::after{display:none}
.paso__t{font-weight:700;font-size:17px;color:var(--brand-d);margin:4px 0 4px}
.paso p{margin:0 0 .5em}

/* ---------- 13. Línea de tiempo (componente firma del sitio) ------------- */
.timeline{list-style:none;margin:0 0 1.2em;padding:0;position:relative}
.timeline::before{content:"";position:absolute;left:8px;top:6px;bottom:6px;width:2px;background:var(--track);border-radius:1px}
.tl{position:relative;padding:0 0 16px 30px;margin:0}
.tl::before{content:"";position:absolute;left:2px;top:7px;width:14px;height:14px;border-radius:50%;
  background:var(--surface);border:3px solid var(--brand-br)}
.tl--abierta::before{border-color:var(--accent);background:var(--accent-bg)}
.tl__fecha{font:700 12.5px/1.4 var(--font);letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-variant-numeric:tabular-nums}
.tl__t{font-weight:600;color:var(--ink);margin:1px 0 2px}
.tl__d{font-size:14.5px;color:var(--soft);margin:0}

/* ---------- 14. Preguntas ------------------------------------------------- */
.faq{border:1px solid var(--border);border-radius:var(--r);background:var(--surface);overflow:hidden}
.faq details{border-bottom:1px solid var(--border-2)}
.faq details:last-child{border-bottom:none}
.faq summary{cursor:pointer;padding:15px 18px;font-weight:600;color:var(--brand-d);list-style:none;
  display:flex;justify-content:space-between;align-items:center;gap:14px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";flex:none;width:9px;height:9px;border-right:2px solid var(--muted);
  border-bottom:2px solid var(--muted);transform:rotate(45deg);transition:transform .18s;margin-top:-4px}
.faq details[open] summary::after{transform:rotate(-135deg);margin-top:2px}
.faq summary:hover{background:var(--surface-alt)}
.faq__c{padding:0 18px 16px;color:var(--soft)}
.faq__c > *:last-child{margin-bottom:0}

/* ---------- 15. Herramientas (calculadoras y wizards) -------------------- */
.calc{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-xl);
  padding:clamp(18px,2.6vw,26px);box-shadow:var(--sh-2)}
.slab .calc{box-shadow:var(--sh-3)}
.calc__head{margin:0 0 16px}
.calc__head h2,.calc__head h3{margin:0 0 4px}
.calc__head p{margin:0;color:var(--soft);font-size:15px}
.calc-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.field{display:flex;flex-direction:column;gap:5px}
.field__lbl{display:flex;align-items:center;gap:7px;font-weight:600;font-size:14.5px;color:var(--ink)}
.field__help{font-size:13px;color:var(--muted);margin:0}
.field input,.field select{font:400 16.5px/1.4 var(--font);color:var(--ink);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-s);padding:10px 12px;width:100%}
.field input:focus,.field select:focus{border-color:var(--brand-br);outline:2px solid rgba(53,48,107,.15);outline-offset:0}
.field input[aria-invalid=true]{border-color:var(--danger)}
.field__err{font-size:13px;color:var(--danger);margin:0}

/* Resultado: aparece sólo cuando hay algo que decir. */
.calc-result{margin-top:18px;border-top:1px solid var(--border);padding-top:18px}
.calc-result[hidden]{display:none!important}
.res-top{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 16px;margin:0 0 12px}
.res-top .figure-xl{font-size:clamp(30px,5vw,44px);color:var(--brand-d)}
.res-top .figure-xl--acento{color:var(--accent-t)}
.res-lbl{font:700 12px/1.3 var(--font);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.result-rows{display:flex;flex-direction:column;gap:0;border:1px solid var(--border);border-radius:var(--r);overflow:hidden}
.result-rows div{display:flex;justify-content:space-between;gap:16px;padding:9px 14px;font-size:15px;border-bottom:1px solid var(--border-2)}
.result-rows div:last-child{border-bottom:none}
.result-rows dt,.result-rows .k{color:var(--soft)}
.result-rows dd,.result-rows .v{margin:0;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink);text-align:right}

/* Wizard del decisor de canal */
.decisor__q{font-weight:700;font-size:19px;color:var(--brand-d);margin:0 0 12px;line-height:1.3}
.slab .decisor__q{color:#fff}
.decisor__opts{display:flex;flex-wrap:wrap;gap:10px}
.decisor__opt{flex:1 1 150px;text-align:left;padding:13px 16px;border-radius:var(--r);
  border:1px solid var(--border);background:var(--surface);cursor:pointer;
  font:600 16px/1.35 var(--font);color:var(--ink);transition:border-color .15s,background .15s}
.decisor__opt:hover{border-color:var(--brand-br);background:var(--tile)}
.decisor__opt small{display:block;font-weight:400;font-size:13.5px;color:var(--muted);margin-top:3px}
.decisor__back{background:none;border:0;padding:6px 0;color:var(--muted);font:600 14px/1 var(--font);cursor:pointer;text-decoration:underline}
.slab .decisor__back{color:#A9A2CF}
/* Las dos salidas del veredicto. `gap` de 18px para que no se toquen los blancos de
   pulsación: son dos acciones muy distintas y una está a un toque de borrar el resultado. */
.decisor__salidas{display:flex;flex-wrap:wrap;align-items:center;gap:18px;margin-top:16px}
.decisor__salidas .decisor__back{min-height:24px}
.decisor__prog{display:flex;gap:5px;margin:0 0 14px}
.decisor__prog i{height:4px;flex:1;border-radius:2px;background:var(--track)}
.decisor__prog i[data-on]{background:var(--accent)}

/* Descifrador de códigos */
.codigo-card{border:1px solid var(--accent-bd);background:var(--accent-bg);border-radius:var(--r);padding:16px 18px;margin:0 0 12px}
.codigo-card__c{font:700 22px/1 var(--font);color:var(--accent-t);font-variant-numeric:tabular-nums;letter-spacing:.02em}
.codigo-card__t{font-weight:700;color:var(--brand-d);margin:6px 0 4px}
.codigo-card__d{margin:0;font-size:15px;color:var(--soft)}
.buscador{position:relative;margin:0 0 16px}
.buscador input{width:100%;font:400 17px/1.4 var(--font);padding:12px 14px 12px 42px;
  border:1px solid var(--border);border-radius:var(--r-s);background:var(--surface);color:var(--ink)}
.buscador svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);width:18px;height:18px;color:var(--muted);pointer-events:none}

/* Filas de períodos del contador de días */
.periodos{display:flex;flex-direction:column;gap:10px;margin:0 0 14px}
/* Reserva del alto de las DOS filas que dias.js inyecta al cargar. Sin esto el contenedor
   nace con 0px, el JS lo llena despues del primer paint y empuja todo lo de abajo: CLS 0,108
   medido contra prod el 2026-08-26 (3 de 3 corridas), el unico CLS del sitio. El :empty deja
   de aplicar en cuanto entran las filas, asi que no queda hueco si el markup cambia.
   Las dos alturas salen de medir el contenedor ya lleno a cada lado del breakpoint de
   .periodo (640px): 164px con la fila en linea, 334px con la fila apilada. */
.periodos:empty{min-height:164px}
@media (max-width:640px){.periodos:empty{min-height:334px}}
/* La 3.ª columna pasó de un «Jornada %» de dos cifras a un <select> cuyo texto más largo
   es «Fijo discontinuo»: con 92px se cortaba. */
.periodo{display:grid;grid-template-columns:1fr 1fr minmax(150px,auto) 40px;gap:9px;align-items:end}
@media (max-width:640px){.periodo{grid-template-columns:1fr 1fr;grid-template-areas:"a b" "c d"}}
.periodo__del{background:none;border:1px solid var(--border);border-radius:var(--r-s);
  color:var(--muted);cursor:pointer;height:42px;display:grid;place-items:center}
.periodo__del:hover{border-color:var(--danger);color:var(--danger)}

/* ---------- 16. Comparativa de canales ----------------------------------- */
.canal-tabla{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(215px,1fr))}
.canal{border:1px solid var(--border);border-radius:var(--r-l);background:var(--surface);padding:17px 19px;display:flex;flex-direction:column;gap:8px}
.canal--rec{border-color:var(--accent-bd);background:var(--accent-bg-2);box-shadow:var(--sh-1)}
.canal__t{font-weight:700;color:var(--brand-d);font-size:17px;margin:0}
.canal__req{font-size:13.5px;color:var(--muted);margin:0}
.canal__tiempo{font:700 15px/1 var(--font);color:var(--accent-t);font-variant-numeric:tabular-nums}
.canal ul{margin:0;padding-left:1.1em;font-size:14.5px;color:var(--soft)}

/* ---------- 17. Figuras / infografías ------------------------------------ */
.fig{margin:0 0 1.4em;border:1px solid var(--border);border-radius:var(--r-l);background:var(--surface);overflow:hidden}
.fig__c{padding:16px;overflow-x:auto}
.fig svg{display:block;max-width:100%;height:auto}
.fig figcaption{padding:11px 16px;border-top:1px solid var(--border-2);background:var(--surface-alt);
  font-size:13.5px;color:var(--muted)}
/* Dos versiones del mismo dibujo según ancho: un SVG apaisado no se lee en 390 px. */
.fig--ancho{display:none}
.fig--angosto{display:block}
@media (min-width:760px){.fig--ancho{display:block}.fig--angosto{display:none}}

/* ---------- 18. Aviso YMYL + fuentes ------------------------------------- */
.disclaimer-ymyl{border:1px solid var(--warn-bd);background:var(--warn-bg);border-radius:var(--r);
  padding:14px 17px;font-size:14.5px;color:var(--soft);margin:0 0 1.2em}
.disclaimer-ymyl strong{color:var(--ink)}
.fuentes{font-size:14.5px;color:var(--soft)}
.fuentes ul{padding-left:1.1em}
.fuentes a{word-break:break-word}

/* ---------- 19. Footer ---------------------------------------------------- */
.site-foot{background:var(--brand-d);color:#CFCAE8;margin-top:clamp(40px,6vw,72px);padding:clamp(30px,4.4vw,48px) 0 26px}
.site-foot a{color:#CFCAE8;text-decoration:none}
.site-foot a:hover{color:#fff;text-decoration:underline}
.footer-grid{display:grid;gap:26px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.footer-col h3{font:700 12px/1.3 var(--font);letter-spacing:.1em;text-transform:uppercase;color:#9791c6;margin:0 0 10px}
.footer-col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px;font-size:14.5px}
.footer-about{font-size:14.5px;line-height:1.6;color:#A9A2CF;max-width:34ch}
.footer-legal{margin-top:26px;padding-top:18px;border-top:1px solid rgba(255,255,255,.14);
  font-size:13.5px;color:#9791c6;display:flex;flex-wrap:wrap;gap:8px 20px;justify-content:space-between}

/* ---------- 20. Utilidades ------------------------------------------------ */
.grid2{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(270px,1fr))}
.ico{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;vertical-align:-.125em}
.ico--s{width:.85em;height:.85em}
.pill{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:var(--r-pill);
  font:700 12px/1.6 var(--font);letter-spacing:.04em;background:var(--tile);color:var(--soft)}
.pill--ok{background:var(--ok-bg);color:var(--ok)}
.pill--warn{background:var(--warn-bg);color:var(--warn)}
.pill--acento{background:var(--accent-bg);color:var(--accent-t)}

/* ============================================================================
   21. Fase de procesamiento de las herramientas
   ----------------------------------------------------------------------------
   La sensación de que la herramienta hace algo, no de que un `if` pintó un div.
   ⚠️ Es HONESTA: los pasos que se listan describen lo que de verdad ocurre, y
   todo ocurre en el navegador. El texto de privacidad va dentro de la propia
   card de carga, que es el momento en que el usuario se pregunta a dónde han
   ido sus datos.
   Patrón portado de es-sepe (assets/js/app.js → sbProcesar).
   ============================================================================ */
.calc-load{background:var(--surface-alt);border:1px solid var(--border);border-radius:var(--r-l);padding:20px 22px}
.cl-head{display:flex;align-items:center;gap:11px;font-size:16.5px;color:var(--brand-d);margin:0 0 14px}
.cl-spin{width:18px;height:18px;flex:none;border-radius:50%;border:2.5px solid var(--track);
  border-top-color:var(--accent);animation:sb-spin .7s linear infinite}
@keyframes sb-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.cl-spin{animation:none;border-top-color:var(--accent)}}
.cl-bar{height:7px;background:var(--track);border-radius:var(--r-bar);overflow:hidden}
.cl-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--brand-l),var(--accent));
  border-radius:var(--r-bar);transition:width .18s linear}
.cl-pct{font:700 12.5px/1 var(--font);color:var(--muted);margin:7px 0 14px;font-variant-numeric:tabular-nums}
.cl-steps{display:flex;flex-direction:column;gap:8px}
.cl-step{display:flex;align-items:center;gap:10px;font-size:14.5px;color:var(--muted);transition:color .2s}
.cl-step .dot{width:9px;height:9px;border-radius:50%;background:var(--track);flex:none;transition:background .2s,box-shadow .2s}
.cl-step.active{color:var(--ink)}
.cl-step.active .dot{background:var(--accent);box-shadow:0 0 0 4px var(--accent-bg)}
.cl-step.done{color:var(--soft)}
.cl-step.done .dot{background:var(--ok)}
.cl-priv{margin:14px 0 0;font-size:13px;color:var(--muted);display:flex;gap:8px;align-items:flex-start}

/* La aparición del resultado. Corta, sin rebote: el resultado es información, no un premio. */
.calc-reveal{animation:sb-reveal .34s cubic-bezier(.2,.7,.3,1) both}
@keyframes sb-reveal{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.calc-reveal{animation:none}}

/* ============================================================================
   22. «Y ahora, ¿qué?» — las rutas que salen del resultado
   ----------------------------------------------------------------------------
   El resultado no es el final: en base a lo que el usuario contestó sabemos en
   qué situación está, y ahí es donde se le ofrece a dónde seguir. Las dos rutas
   más pertinentes a SU caso van destacadas.
   ============================================================================ */
.next{margin-top:26px;padding-top:22px;border-top:2px solid var(--border)}
.next h3{font-size:18px;margin:0 0 4px}
.next > p{color:var(--soft);font-size:14.5px;margin:0 0 14px}
.next .cards{gap:12px}
.card--feat{border-color:var(--accent-bd);background:var(--accent-bg);position:relative}
.card-badge{display:inline-flex;align-self:flex-start;padding:3px 9px;border-radius:var(--r-pill);
  background:var(--accent-d);color:#fff;font:700 11px/1.5 var(--font);letter-spacing:.05em;
  text-transform:uppercase;margin:0 0 3px}

/* ============================================================================
   23. Tooltips de ayuda de campo — el (i)
   ----------------------------------------------------------------------------
   ⚠️ NO se usa `title=""` ni un tooltip por :hover: en móvil no existe el hover
   y `title` no se puede tocar. Es un <button> con aria-expanded que despliega un
   panel posicionado en absoluto, así que funciona con dedo, con teclado y con
   lector de pantalla, y NO altera el flujo del documento (no empuja nada).
   ============================================================================ */
.field__lbl{position:relative}
.field__info{flex:none;width:19px;height:19px;padding:0;border:0;border-radius:50%;cursor:pointer;
  background:var(--tile);color:var(--soft);display:grid;place-items:center;position:relative;
  font:700 12px/1 var(--font);transition:background .15s,color .15s}
/* El disco se ve de 19px, pero con el dedo eso no se acierta: WCAG 2.2 (2.5.8) pide 24px de
   mínimo y Google recomienda ~48. Se agranda el ÁREA TÁCTIL con un pseudo-elemento en absoluto
   —no el botón—, así el objetivo mide 44x44 sin que el dibujo crezca ni se mueva nada del
   diseño. Es la razón por la que el disco lleva position:relative. */
.field__info::after{content:"";position:absolute;top:50%;left:50%;width:44px;height:44px;
  transform:translate(-50%,-50%)}
.field__info:hover,.field__info[aria-expanded=true]{background:var(--brand);color:#fff}
.field__tip{position:absolute;z-index:30;left:0;top:calc(100% + 8px);width:min(304px,calc(100vw - 40px));
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:var(--sh-2);padding:13px 15px;font:400 14px/1.5 var(--font);color:var(--soft);
  text-align:left;animation:sb-reveal .16s ease-out both}
.field__tip[hidden]{display:none}
/* La casilla del navegador viene de 13px. Va dentro de un <label>, así que se acierta tocando
   el texto, pero el cuadrito en sí queda por debajo del mínimo: se sube a 18. */
.chk{width:18px;height:18px;margin-right:9px;accent-color:var(--brand);vertical-align:-3px}

/* Teléfonos. Se ven como lo que son —un número, no un enlace de texto corrido— pero se tocan.
   `white-space:nowrap` para que un número no se parta en dos renglones, que es donde la gente
   se equivoca al copiarlo. */
.tel{white-space:nowrap;font-variant-numeric:tabular-nums;text-decoration:none;
  border-bottom:1px solid var(--accent-o);color:inherit;font-weight:600}
.tel:hover,.tel:focus-visible{color:var(--accent-d);border-bottom-color:var(--accent-d)}
.slab .tel{border-bottom-color:var(--accent-o)}
.field__tip::before{content:"";position:absolute;top:-6px;left:14px;width:10px;height:10px;
  background:var(--surface);border-left:1px solid var(--border);border-top:1px solid var(--border);
  transform:rotate(45deg)}
.field__tip strong{color:var(--ink)}
.field__tip code{font-size:.9em}
/* En pantallas estrechas el panel se ancla al borde del bloque, no al del label, para que
   nunca se salga por la derecha. */
@media (max-width:520px){.field__tip{left:auto;right:0}.field__tip::before{left:auto;right:14px}}

/* ============================================================================
   24. Infografías de flujo (el patrón de br-cnpj)
   ----------------------------------------------------------------------------
   Un stepper es una lista numerada disfrazada. Como infografía, los pasos se ven
   a la vez y la relación entre ellos —que es lo que importa— se lee de un
   vistazo. En pantalla estrecha vuelve a apilarse, que es lo correcto.
   ============================================================================ */
.ig{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-l);
  padding:20px 22px;margin:0 0 1.4em;box-shadow:var(--sh-1)}
/* ⚠️ EL CONECTOR SE DERIVA DEL HUECO, no de un número a ojo. Antes el hueco era de 14px y el
   conector iba a `right:-11px` con 14px de ancho: su borde izquierdo caía 3px DENTRO de la
   tarjeta y el derecho 3px antes de la siguiente, así que la línea se veía corrida a la
   izquierda en vez de unir las dos cajas. Con la variable, mover el `gap` mueve el conector. */
.ig-flow{--ig-gap:14px;display:grid;gap:var(--ig-gap);
  grid-template-columns:repeat(auto-fit,minmax(178px,1fr));counter-reset:igp}
.ig-flow > div{position:relative;background:var(--surface-alt);border:1px solid var(--border-2);
  border-radius:var(--r);padding:15px 16px 15px}
.ig-flow > div::after{content:"";position:absolute;
  right:calc(var(--ig-gap) * -1);width:var(--ig-gap);top:50%;height:2px;
  background:var(--border);transform:translateY(-50%)}
.ig-flow > div:last-child::after{display:none}
/* ⚠️ EL CORTE VA EN 760px, NO EN 600. Con `auto-fit` y cuatro pasos de 178px mínimo, por
   debajo de ~754px la rejilla se parte en 2x2 — y entonces la última tarjeta de la primera
   fila sigue dibujando su conector HORIZONTAL hacia la derecha, apuntando al vacío. CSS no
   sabe si el hermano siguiente está en otra fila, así que en vez de taparlo con JS se elimina
   el caso: o caben todas en una fila, o van en una sola columna.
   El 850 no es a ojo: es el ancho medido al que cuatro pasos dejan de caber en una fila
   (a 840px ya se parten). Si cambia el `minmax` o el `gap`, hay que volver a medirlo. */
@media (max-width:850px){
  .ig-flow{grid-template-columns:1fr}
  .ig-flow > div::after{right:auto;left:50%;top:auto;
    bottom:calc(var(--ig-gap) * -1);height:var(--ig-gap);width:2px;transform:translateX(-50%)}
}
.ig-flow .n{width:26px;height:26px;border-radius:50%;background:var(--brand);color:#fff;
  display:grid;place-items:center;font:700 14px/1 var(--font);margin:0 0 9px;font-variant-numeric:tabular-nums}
.ig-flow .t{font-weight:700;color:var(--brand-d);font-size:15.5px;line-height:1.3;margin:0 0 4px}
.ig-flow .d{font-size:14px;color:var(--soft);line-height:1.45}
.ig-flow > div.hot{background:var(--accent-bg);border-color:var(--accent-bd)}
.ig-flow > div.hot .n{background:var(--accent-d)}
.ig-cap{font-size:13.5px;color:var(--muted);margin-top:14px;text-align:center}

/* ============================================================================
   25. Esquema del documento (el patrón de es-dni)
   ----------------------------------------------------------------------------
   Un dibujo de la propia hoja del informe, con un campo resaltado. Es lo que
   convierte «la columna CTP» en algo que el usuario localiza en su PDF sin
   tener que buscar. El SVG es esquemático y con datos de ejemplo evidentes: no
   reproduce un documento real.
   ============================================================================ */
.doc{margin:0 0 1.4em}
.doc__c{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-l);
  padding:18px;overflow-x:auto;box-shadow:var(--sh-1)}
.doc svg{display:block;width:100%;min-width:520px;height:auto}
.doc figcaption{margin-top:11px;font-size:13.5px;color:var(--muted);line-height:1.5}
.doc figcaption strong{color:var(--ink)}

/* ============================================================================
   26. Visor del documento con puntos numerados (patrón de es-dni)
   ----------------------------------------------------------------------------
   El esquema del informe con un dato señalado. Los puntos van posicionados en %
   sobre el contenedor, así que se mantienen sobre su campo cuando el SVG escala.
   ⚠️ Las coordenadas viven en sb_vl_campos(): si se mueve un campo del SVG, hay
   que mover el punto.
   ============================================================================ */
/* ⚠️⚠️ DOS CAPAS, Y LA DE DENTRO ES OBLIGATORIA.
   Los puntos se posicionan en % y ese % TIENE que ser del SVG, no del marco exterior. Antes
   había una sola capa con `overflow:hidden` y `min-width:480px` en el SVG, y por debajo de
   480px pasaban tres cosas a la vez: la hoja se cortaba por la derecha (se perdía la columna
   del nº de la Seguridad Social), el % del contenedor dejaba de coincidir con el % del SVG
   —que ya era más ancho— y los puntos señalaban el sitio equivocado. Con el envoltorio
   interno del mismo min-width, el % vuelve a ser exacto a cualquier tamaño y lo que hace el
   marco es DESLIZARSE en vez de recortar. El padding, por lo mismo, nunca va en la capa que
   sirve de referencia a los puntos. */
.visor-doc{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-l);
  padding:0;box-shadow:var(--sh-1);overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch}
.visor-doc__in{position:relative;min-width:480px}
.visor-doc__in > svg{display:block;width:100%;height:auto;margin:0}
/* La chapa va CENTRADA en el canalón, a la altura de su recuadro. Nunca sobre el dibujo: el
   dato que señala tiene que quedar a la vista, que es todo el propósito del esquema. */
.visor-doc .punto{position:absolute;width:24px;height:24px;border-radius:50%;
  display:grid;place-items:center;font:700 13px/1 var(--font);color:#fff;
  transform:translate(-50%,-50%);box-shadow:0 0 0 2px var(--surface);pointer-events:none}
.visor-doc .punto.fijo{background:var(--accent-d);box-shadow:0 0 0 3px var(--surface),0 0 0 6px var(--accent-bg)}
.visor-doc .punto.ctx{background:var(--brand-l);width:21px;height:21px;font-size:12px}
.esquema{margin:0 0 1.5em}
.esquema figcaption{margin-top:12px;font-size:14.5px;color:var(--soft);line-height:1.55}
.esquema__lista{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.esquema__lista li{display:grid;grid-template-columns:20px 1fr;gap:9px;align-items:start}
.esquema figcaption b{display:inline-grid;place-items:center;width:20px;height:20px;border-radius:50%;
  background:var(--accent-d);color:#fff;font:700 12px/1 var(--font);margin-top:2px}
.esquema figcaption b.ctx{background:var(--brand-l)}
.esquema figcaption strong{color:var(--ink)}
.esquema-doc{display:block;margin-top:7px;font-size:13px;color:var(--muted)}
