/* ============================================================================
   sb-lib — PIEL DE LAS HERRAMIENTAS
   ----------------------------------------------------------------------------
   La cara de los cuatro patrones de sb-tools.js: la fase de procesamiento, las
   rutas del «y ahora qué», los (i) de ayuda y el flujo de pasos.

   ── CÓMO SE ADAPTA A CADA SITIO ─────────────────────────────────────────────
   Esta hoja NO conoce la paleta de nadie: usa tokens propios con el prefijo
   `--sb-`. Cada sitio los mapea a los suyos en su propio CSS, UNA vez:

     :root{
       --sb-brand:var(--verde); --sb-brand-d:var(--verde-d); --sb-brand-l:var(--verde-l);
       --sb-brand-bd:var(--verde-bd);
       --sb-accent:var(--ambar); --sb-accent-d:var(--ambar-d); --sb-accent-o:var(--ambar-o);
       --sb-accent-bg:var(--ambar-bg); --sb-accent-bd:var(--ambar-bd);
       --sb-track:var(--bar-off);
     }

   Los tokens neutros (--surface, --border, --ink, --soft, --muted, --r*, --sh*,
   --font) se dan por existentes: los tienen los diez sitios del portfolio con la
   misma semántica.

   ⚠️ EL BOTÓN DE AYUDA SE LLAMA `.field__info`, NO `.field__i`. En es-vl se llama
   `field__i`, y en mx-semanas esa clase ya existía y son los INPUTS de los campos:
   al portar la hoja los dos nombres colisionaron y sólo el orden de la cascada
   evitaba que los inputs se dibujaran como un disco de 19px. Se renombró acá para
   que no vuelva a pasar en el siguiente sitio.
   Documentación: sb-docs/conventions/herramientas-ux.md
   ============================================================================ */

.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(--sb-brand-d);margin:0 0 14px}
.cl-spin{width:18px;height:18px;flex:none;border-radius:50%;border:2.5px solid var(--sb-track);
  border-top-color:var(--sb-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(--sb-accent)}}
.cl-bar{height:7px;background:var(--sb-track);border-radius:var(--r-bar);overflow:hidden}
.cl-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--sb-brand-l),var(--sb-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(--sb-track);flex:none;transition:background .2s,box-shadow .2s}
.cl-step.active{color:var(--ink)}
.cl-step.active .dot{background:var(--sb-accent);box-shadow:0 0 0 4px var(--sb-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(--sb-accent-bd);background:var(--sb-accent-bg);position:relative}
.card-badge{display:inline-flex;align-self:flex-start;padding:3px 9px;border-radius:var(--r-pill);
  background:var(--sb-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).
   ============================================================================ */
/* ⚠️ SE LLAMA `field__info` Y NO `field__i`, que es como se llama en es-vl. En este sitio
   `.field__i` ya existía y son los INPUTS de los campos («field input»): al portar la hoja
   los dos nombres colisionaron y sólo el orden de la cascada evitaba que los inputs de las
   nueve herramientas se dibujaran como un disco de 19px. Un empate que se rompe solo el día
   que alguien cambia el orden de los <link>. */
/* ⚠️ LA LIBRERÍA NO IMPONE EL LAYOUT DE LA ETIQUETA. Sólo pone `position:relative`, que es lo
   único que necesita para anclar el panel del tooltip, que va en absoluto.
   Llegó a tener `display:inline-flex` —hacía falta en mx-semanas, donde el (i) caía en su
   propia línea debajo de la etiqueta— y al migrar mx-afore se vio el precio: cambiaba el
   reflujo de TODAS sus etiquetas («Semanas cotizadas que llevas» pasó de dos líneas a una) y
   corría el resto de la página. Se veía mejor, pero un cambio de maqueta que nadie pidió, en
   siete páginas de un sitio en producción, no es una migración: es otra cosa.
   El sitio que lo necesite lo declara en su propio CSS, que es donde vive su maqueta. */
.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(--sb-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(--sb-brand);vertical-align:-3px}

/* `--tip-x` lo fija el JS con el centro del botón: sin eso, con una etiqueta larga la
   flecha señala aire. Cae a 14px si el JS no llegó a correr. */
.field__tip::before{content:"";position:absolute;top:-6px;left:var(--tip-x,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}}

/* ============================================================================
   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(--sb-accent-d);box-shadow:0 0 0 3px var(--surface),0 0 0 6px var(--sb-accent-bg)}
.visor-doc .punto.ctx{background:var(--sb-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}

/* ============================================================================
   24. Validación: el aviso vive DEBAJO DEL CAMPO
   ⭐ La regla está explicada en sb-tools.js §5. Acá sólo la piel, y con dos cuidados:

   ⚠️ NADA de esto cambia el ALTO de la línea de ayuda. Ni `padding`, ni `border`, ni un
   `display` distinto: el mensaje ocupa exactamente el mismo sitio que el texto que
   reemplaza, que es lo que hace que el formulario no se mueva al fallar. Lo único que
   cambia es el color y el peso. Si alguna vez hay que meter un icono, va como `::before`
   en línea, no como bloque.

   ⚠️ El color NO es lo único que marca el error: el campo lleva `aria-invalid`, que se
   dibuja con borde, y el mensaje dice qué pasa. Color solo no vale — es la trampa de
   accesibilidad clásica (WCAG 1.4.1), y acá hay usuarios daltónicos como en todas partes.
   ============================================================================ */
:root{ --sb-mal:#a4262c; --sb-mal-bd:#e3b3b5; --sb-mal-bg:#fdf2f2; }

/* ⚠️ La clase va DUPLICADA a propósito (0-2-0). La hoja del sitio se carga después de esta
   —es la base, el sitio la especializa— y su regla para la línea de ayuda (`.ayuda` en mx-bc,
   `.f-help` en es-sepe…) tiene la misma especificidad que `.sb-mal`: al empatar ganaba la del
   sitio y el mensaje de error salía del gris de un texto de ayuda cualquiera.
   Un error que no se distingue del texto normal no es un error, así que acá la librería sí
   pisa: es lo único de esta hoja que lo hace, y por eso está escrito. */
.sb-mal.sb-mal{ color:var(--sb-mal); font-weight:600 }

/* La línea que se CREA cuando el campo no tenía ninguna (el fallback de `sbCampoMal`). Va lo
   más compacta posible porque, al no existir antes, sí empuja lo que viene debajo: hereda el
   cuerpo del contexto y sólo separa 5 px del campo. */
.sb-ayuda{ margin:5px 0 0; font-size:13px; line-height:1.4 }

/* El borde del campo. `:where()` mantiene la especificidad en CERO, así que cualquier regla
   del sitio lo sigue pisando sin pelear: la librería no impone la piel, la propone. */
:where(input,select,textarea)[aria-invalid="true"]{
  border-color:var(--sb-mal-bd);
  box-shadow:0 0 0 1px var(--sb-mal-bd)
}

/* Aviso de condición conjunta: pequeño, pegado encima del botón. */
.sb-formerr{
  margin:0 0 10px; padding:8px 11px; border-radius:8px;
  background:var(--sb-mal-bg); border:1px solid var(--sb-mal-bd);
  color:var(--sb-mal); font:600 13.5px/1.45 var(--font,inherit)
}
.sb-formerr[hidden]{ display:none }

/* ── Salir del resultado ──────────────────────────────────────────────────── */
.sb-acciones{ display:flex; flex-wrap:wrap; gap:10px; margin-top:22px;
  padding-top:18px; border-top:1px solid var(--border,rgba(0,0,0,.1)) }
.sb-accion{
  appearance:none; cursor:pointer; font:600 14.5px/1 var(--font,inherit);
  padding:11px 16px; border-radius:8px;
  border:1px solid var(--sb-brand-bd,rgba(0,0,0,.18));
  background:transparent; color:var(--sb-brand,inherit)
}
.sb-accion:hover{ background:var(--sb-accent-bg,rgba(0,0,0,.04)) }
.sb-accion:focus-visible{ outline:2px solid var(--sb-accent,currentColor); outline-offset:2px }
/* El de reiniciar es el secundario de los dos: pierde el borde para que «Volver a calcular»
   —que es lo que casi todo el mundo quiere— se lea primero. Cuando va solo, no hay contra
   qué compararlo y el borde tampoco hace falta. */
.sb-accion--reset{ border-color:transparent; text-decoration:underline;
  text-underline-offset:3px }

/* Campos de dinero: sin las flechitas del `type=number`.
   No es cosmética: subir un saldo de a un centavo no le sirve a nadie, y los spinners aparecen
   al pasar por encima —desplazando el texto del campo— y se disparan con la rueda del ratón.
   Lo de la rueda ya lo neutraliza sb-tools.js; esto quita el resto. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0 }
input[type="number"]{ -moz-appearance:textfield; appearance:textfield }

/* ── «Y ahora, ¿qué?»: decir que la tarjeta se puede pulsar ────────────────────
   La tarjeta entera es un <a>, pero eso NO se comunica solo: en escritorio lo insinúa el
   cursor y el hover, y en un teléfono no hay ni cursor ni hover, así que se lee como una caja
   de texto y nadie la toca. Una marca permanente al pie lo dice sin depender del puntero.

   Es un `::after` de CSS y no un <a> real: anidar interactivos dentro de un <a> es HTML
   inválido y confunde a los lectores de pantalla, que anunciarían dos enlaces donde hay uno.

   ⚠️ `grid-column` está para mx-afore, que maqueta sus tarjetas con `display:grid` de dos
   columnas: sin eso la flecha se colocaría como un item más y se metería en la columna del
   texto. En las de `flex` la propiedad se ignora sola.

   ⚠️ Va con `:where()`, o sea con especificidad CERO, a propósito: es-sepe y mx-bc ya traen su
   propia versión —«Ver más →», «Ver →»— y tienen que seguir ganando sin pelear. La librería
   pone el suelo para quien no lo tenga, no la última palabra. */
:where(.next .card, .next .ruta)::after{
  content:"Ver \2192";
  grid-column:1 / -1;
  align-self:start;
  margin-top:10px;
  font-size:13.5px; font-weight:700;
  color:var(--sb-brand, currentColor);
}

/* La fila del botón de enviar y su aviso. El aviso va A SU DERECHA en pantalla ancha —así no
   empuja el botón justo cuando lo acabas de pulsar— y baja debajo cuando no cabe, que en un
   móvil es siempre. `flex:1 1 260px` es lo que decide ese salto: por debajo de 260px de hueco
   se va a la línea siguiente en vez de estrujarse. */
.sb-envio{display:flex;flex-wrap:wrap;align-items:center;gap:12px}
.sb-envio > .sb-formerr{flex:1 1 260px;margin:0}

/* El resultado que se está dejando atrás: apagado, pero todavía OCUPANDO SU SITIO. Ese es el
   punto — mantiene el alto de la página quieta mientras la vista sube, que es lo que evita el
   salto. Se borra al llegar. Ver sbSalirDelResultado en sb-tools.js. */
.sb-saliendo{opacity:.35;pointer-events:none;transition:opacity .25s ease}
@media (prefers-reduced-motion:reduce){.sb-saliendo{transition:none}}
