/* ============================================================================
   PLATAFORMA — shell de navegación, vistas y herramientas.
   ========================================================================== */

/* ─── Shell ─────────────────────────────────────────────────────────────── */
/* `--rail` es la anchura del índice. Se anima la retícula, no la barra: así el
   contenido recupera el ancho en el mismo gesto en que el índice se va. Donde
   el navegador no sepa interpolar grid-template-columns, el cambio es
   instantáneo y todo lo demás sigue funcionando. */
.shell {
  display: grid;
  grid-template-columns: 268px minmax(0, 1fr);
  min-height: 100vh;            /* alternativa para navegadores sin dvh */
  min-height: 100dvh;
  transition: grid-template-columns var(--dur-trans) var(--ease-out);
}
@media (min-width: 1081px) {
  .shell[data-rail="off"] { grid-template-columns: 0 minmax(0, 1fr); }
  .shell[data-rail="off"] > .side {
    transform: translateX(-100%);
    visibility: hidden;
    border-right-color: transparent;
    transition: transform var(--dur-trans) var(--ease-out),
                visibility 0s linear var(--dur-trans);
  }
  .shell[data-rail="off"] > .railbtn { display: inline-flex; }
  /* Un cambio hecho con teclado o restaurado al cargar no debe animarse. */
  .shell.no-anim, .shell.no-anim > .side { transition: none; }
}
@media (max-width: 1080px) { .shell { grid-template-columns: 1fr; } }

/* El velo del cajón vive fuera del flujo SIEMPRE. Si es un hijo más del grid
   en escritorio, ocupa la segunda columna y empuja el contenido a la barra
   lateral. Ese fallo dejó la portada renderizando en 268 px de ancho. */
.scrim { position: fixed; inset: 0; display: none; }

/* ─── Barra lateral ─────────────────────────────────────────────────────── */
.side {
  position: sticky; top: 0; align-self: start;
  height: 100vh; height: 100dvh; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--s-5) var(--s-5) var(--s-6);
  border-right: 1px solid var(--paper-30);
  background: var(--paper-00);
  z-index: var(--z-nav);
}
.side__top {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: start; gap: var(--s-3);
  margin-bottom: var(--s-6);
}
.side__mark { display: block; text-decoration: none; min-width: 0; }
.side__hide {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; margin-top: -3px;
  background: none; border: 1px solid var(--paper-30); border-radius: 2px;
  color: var(--ink-30); cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out),
              background-color var(--dur-micro) var(--ease-out);
}
.side__hide svg { width: 15px; height: 15px; }
.side__hide:hover { color: var(--pv-70); border-color: var(--pv-30); background: var(--pv-06); }
.side__hide:active { transform: scale(0.94); }
@media (max-width: 1080px) { .side__hide { display: none; } }

/* El control de reapertura. Fijo desde el principio: como hijo de una retícula
   en posición estática se convertiría en columna y desplazaría el contenido. */
.railbtn {
  position: fixed; top: var(--s-4); left: var(--s-4);
  z-index: var(--z-nav);
  display: none; align-items: center; gap: 8px;
  padding: 9px 14px 9px 11px;
  background: var(--paper-00);
  border: 1px solid var(--paper-30); border-radius: 2px;
  font: 600 var(--t-sm)/1 var(--font-text); color: var(--ink-10);
  box-shadow: 0 1px 2px rgba(28, 21, 35, 0.05), 0 8px 24px -12px rgba(28, 21, 35, 0.28);
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out);
}
.railbtn svg { width: 15px; height: 15px; }
.railbtn:hover { color: var(--pv-70); border-color: var(--pv-30); }
.railbtn:active { transform: scale(0.97); }
.side__mark b {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: 1.0625rem; line-height: 1.15; color: var(--ink-00);
  letter-spacing: var(--track-tight);
  font-variation-settings: "SOFT" 22, "WONK" 1, "opsz" 28;
}
.side__mark span { display: block; margin-top: 3px; font-size: var(--t-xs); color: var(--ink-30); }
.side__group { margin-bottom: var(--s-5); }
.side__group h2 {
  font-family: var(--font-text); font-size: var(--t-xs); font-weight: 600;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--ink-30); margin-bottom: var(--s-2);
}
.side__list { list-style: none; margin: 0; padding: 0; }
.side__list a {
  display: flex; align-items: center; gap: var(--s-2);
  padding: 7px 0 7px var(--s-3);
  font-size: 0.875rem; line-height: 1.3; color: var(--ink-20);
  text-decoration: none; border-left: 2px solid transparent;
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out);
}
.side__list a:hover { color: var(--pv-70); border-left-color: var(--pv-30); }
.side__list a[aria-current="page"] {
  color: var(--pv-70); font-weight: 600; border-left-color: var(--pv-50);
}
.side__list a::after {
  content: "herramienta"; margin-left: auto;
  font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--siena); opacity: 0; flex: none;
}
.side__list a[data-tool="1"]::after { opacity: 1; }
.side__foot { margin-top: var(--s-6); padding-top: var(--s-4); border-top: 1px solid var(--paper-30); font-size: var(--t-xs); color: var(--ink-30); }

/* Barra superior sólo en pantallas estrechas */
.topbar { display: none; }
@media (max-width: 1080px) {
  .side {
    position: fixed; inset: 0 auto 0 0; width: min(84vw, 320px);
    transform: translateX(-102%); transition: transform var(--dur-trans) var(--ease-out);
    box-shadow: var(--lift-3);
  }
  .side[data-open="true"] { transform: none; }
  .topbar {
    display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
    position: sticky; top: 0; z-index: calc(var(--z-nav) - 1);
    height: 60px; padding-inline: var(--margin);
    background: rgba(239, 233, 226, 0.92);
    background: color-mix(in oklab, var(--paper-10) 92%, transparent);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--paper-30);
  }
  .topbar b { font-family: var(--font-display); font-size: 0.95rem; letter-spacing: var(--track-tight); }
  .burger {
    display: inline-flex; align-items: center; gap: 8px;
    background: none; border: 1px solid var(--pv-30); border-radius: 2px;
    padding: 8px 12px; font: 600 var(--t-sm)/1 var(--font-text); color: var(--ink-10);
    cursor: pointer;
  }
  .burger i { display: block; width: 15px; height: 9px; border-top: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; }
  .scrim {
    display: block; z-index: calc(var(--z-nav) - 2);
    background: rgba(28, 21, 35, 0.42); opacity: 0; visibility: hidden;
    transition: opacity var(--dur-trans) var(--ease-out), visibility 0s linear var(--dur-trans);
  }
  .scrim[data-open="true"] { opacity: 1; visibility: visible; transition-delay: 0s; }
}

/* ─── Vistas ────────────────────────────────────────────────────────────── */
.main { min-width: 0; }
/* Cambiar de sección se hace decenas de veces: la entrada se queda en un
   fundido corto. El momento de autor no está aquí, sino en el filete de cada
   cabecera y en el lavado de las 316 partículas. */
.view { animation: viewIn 200ms var(--ease-out) both; }
@keyframes viewIn { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .view { animation: none; } }

/* La portada es a sangre en el lienzo, no en el texto. El canvas está en
   posición absoluta con inset:0, así que cubre también el relleno: quitarle el
   margen a la retícula no hacía sangrar nada, solo pegaba el titular al borde
   de la ventana. */
.view--full .hero { padding-inline: var(--margin); }
.page { padding: var(--s-8) var(--margin) var(--s-9); max-width: 1180px; margin-inline: auto; }
/* ─── Cabeceras de escena ────────────────────────────────────────────────
   Cuatro familias, una por grupo del manual. Ninguna lleva etiqueta de
   categoría encima del titular: el índice lateral ya dice en qué grupo estamos
   y quince veces la misma etiqueta no informa, decora. Lo que sí sube a la
   cabecera es el dato que el lector necesita — dónde está eso en la tesis, o
   qué hace exactamente la herramienta. */
.ph { position: relative; margin-bottom: var(--s-7); }
.ph h1 { font-size: clamp(2rem, 4.2vw, 3.25rem); outline: none; max-width: 20ch; }
.ph__lead { font-size: var(--t-md); color: var(--ink-10); max-width: 58ch; margin: 0; }
.ph__meta {
  margin: 0; font-size: var(--t-xs); color: var(--ink-30);
  letter-spacing: 0.03em; font-variant-numeric: tabular-nums;
}

/* El filete se traza al entrar en la escena. Es un solo gesto por vista, y
   ocupa un sitio distinto en cada familia: ahí está la variación. */
.ph__rule { border-top: 1px solid var(--paper-30); position: relative; }
.ph__rule::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px;
  border-top: 1px solid var(--pv-50);
  transform: scaleX(0); transform-origin: 0 50%;
}
.js .view:not([hidden]) .ph__rule::before {
  animation: ruleWipe 620ms var(--ease-out) 120ms forwards;
}
@keyframes ruleWipe { to { transform: scaleX(1); } }


/* A · Diagnóstico — apertura editorial. El titular manda; el filete lo cierra
   y debajo se reparten entradilla y procedencia. */
.ph--open h1 { max-width: 16ch; }
.ph--open .ph__rule {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline; column-gap: var(--s-6);
  margin-top: var(--s-6); padding-top: var(--s-5);
}
@media (max-width: 760px) {
  .ph--open .ph__rule { grid-template-columns: 1fr; row-gap: var(--s-4); }
}

/* B · Herramientas — cabecera de instrumento. La columna derecha no es
   decoración: es la ficha técnica del cálculo, y por eso el titular puede
   partirse en dos columnas sin caer en el split-header de relleno. */
.ph--tool {
  display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  column-gap: var(--s-7); align-items: start;
  padding-bottom: var(--s-6); border-bottom: 1px solid var(--paper-30);
}
.ph--tool .ph__lead { margin-top: var(--s-4); }
.ph__spec { margin: 6px 0 0; display: grid; gap: 1px; background: var(--paper-30); border: 1px solid var(--paper-30); }
.ph__spec > div { background: var(--paper-10); padding: var(--s-4) var(--s-5); }
.ph__spec dt {
  font-size: var(--t-xs); letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--ink-30); font-weight: 600; margin-bottom: 5px;
}
.ph__spec dd { margin: 0; font-size: var(--t-sm); color: var(--ink-10); line-height: 1.5; }
@media (max-width: 980px) {
  .ph--tool { grid-template-columns: 1fr; row-gap: var(--s-6); }
}

/* C · Recursos — página de referencia. Filete vertical a la izquierda, densa
   y sin lavado: son los materiales secos del manual. */
.ph--ref { padding-left: var(--s-6); }
.ph--ref::before {
  content: ""; position: absolute; left: 0; top: 6px; bottom: 0;
  width: 1px; background: var(--paper-30);
}
.ph--ref h1 { max-width: 18ch; }
.ph--ref .ph__lead { margin-top: var(--s-4); }
.ph--ref .ph__rule { margin-top: var(--s-5); padding-top: var(--s-3); }
@media (max-width: 760px) { .ph--ref { padding-left: var(--s-5); } }

/* D · Acción — el filete va arriba, con la procedencia colgada a la derecha:
   antes de leer la decisión se ve de dónde sale. */
.ph--act .ph__rule {
  display: flex; justify-content: flex-end;
  padding-top: var(--s-3); margin-bottom: var(--s-5); min-height: 1.4em;
}
.ph--act .ph__lead { margin-top: var(--s-4); }
@media (max-width: 760px) {
  .ph--act .ph__rule { justify-content: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  .js .view:not([hidden]) .ph__rule::before { animation: none; transform: scaleX(1); }
}

/* Compatibilidad heredada: quedan vistas con la entradilla antigua. */
.page__lead { font-size: var(--t-md); color: var(--ink-10); max-width: 58ch; margin-bottom: var(--s-7); }
.page > h1 { font-size: clamp(2rem, 4.2vw, 3.25rem); margin-bottom: var(--s-4); outline: none; }
.page .sub {
  font-size: var(--t-lg); margin: var(--s-8) 0 var(--s-4);
  padding-bottom: var(--s-2); border-bottom: 1px solid var(--paper-30);
}
.src {
  display: inline-block; margin-bottom: var(--s-6);
  font-size: var(--t-xs); color: var(--ink-30);
  border: 1px solid var(--paper-30); border-radius: 2px; padding: 4px 9px;
}
.plain { list-style: none; margin: 0 0 var(--s-5); padding: 0; }
.plain li { padding: var(--s-3) 0; border-bottom: 1px solid var(--paper-30); font-size: var(--t-sm); color: var(--ink-20); }
.plain b { color: var(--ink-00); margin-right: var(--s-2); }
.table-wrap { overflow-x: auto; }

/* ─── Herramientas ──────────────────────────────────────────────────────── */
.tool__form { display: grid; gap: var(--s-5); margin-bottom: var(--s-5); }
.tool__form--inline {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--s-4); align-items: end;
}
.field { display: grid; gap: 6px; }
.field label { font-size: var(--t-sm); font-weight: 600; color: var(--ink-10); }
.field input, .field select, .field textarea {
  font: 400 var(--t-base)/1.4 var(--font-text);
  color: var(--ink-00); background: var(--paper-00);
  border: 1px solid var(--paper-30); border-radius: 2px;
  padding: 10px 12px; width: 100%;
  transition: border-color var(--dur-micro) var(--ease-out), box-shadow var(--dur-micro) var(--ease-out);
}
.field textarea { resize: vertical; min-height: 76px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--pv-50);
  box-shadow: 0 0 0 3px var(--pv-06);
}
.field--check label { font-weight: 400; display: flex; gap: 9px; align-items: flex-start; }

/* El filete iba en el borde superior del fieldset y la leyenda lo interrumpía.
   Con `display:flex` en la leyenda, el hueco que abre el navegador deja de
   coincidir con el texto y la línea acababa cruzando la última palabra. La
   solución es no usar el borde del fieldset: el filete se dibuja en la propia
   leyenda, que así no tiene nada que interrumpir. */
.q-area { border: 0; margin: 0 0 var(--s-6); padding: 0; min-width: 0; position: relative; }
/* El filete es un pseudo-elemento del fieldset, no un borde: así no hay nada
   que la leyenda pueda interrumpir, y no depende de que un `width` en
   porcentaje resuelva bien dentro de un elemento con maquetación especial. */
.q-area::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  border-top: 2px solid var(--ink-00);
}
.q-area legend {
  display: block;
  padding: var(--s-4) 0 0; margin-bottom: var(--s-2);
  font-family: var(--font-display); font-size: var(--t-md); font-weight: 600;
  color: var(--ink-00); letter-spacing: var(--track-tight);
}
.q-area__id {
  font-size: var(--t-sm); color: var(--pv-50);
  font-variant-numeric: tabular-nums; margin-right: var(--s-3);
}
.q { padding: var(--s-4) 0; border-bottom: 1px solid var(--paper-30); }
.q:last-child { border-bottom: 0; }
.q__text { font-size: var(--t-sm); color: var(--ink-10); margin: 0 0 var(--s-3); max-width: 78ch; }
.q__opts { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.q__opts label { position: relative; }
.q__opts input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.q__opts span {
  display: inline-block; padding: 6px 14px;
  font-size: var(--t-sm); color: var(--ink-20);
  border: 1px solid var(--paper-30); border-radius: 2px;
  transition: all var(--dur-micro) var(--ease-out);
}
.q__opts input:hover + span { border-color: var(--pv-30); color: var(--pv-70); }
.q__opts input:checked + span { background: var(--pv-70); border-color: var(--pv-70); color: var(--paper-00); font-weight: 600; }
.q__opts input:focus-visible + span { outline: 2px solid var(--pv-50); outline-offset: 2px; }

.tool__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin: var(--s-5) 0; }
.tool__out { margin-top: var(--s-4); }
.tool__note { font-size: var(--t-sm); color: var(--ink-20); max-width: 72ch; margin-top: var(--s-3); }
.tool__warn {
  font-size: var(--t-sm); color: var(--granza);
  border-left: 2px solid var(--granza); padding: var(--s-2) 0 var(--s-2) var(--s-4);
  margin-top: var(--s-3);
}

.result { border-top: 2px solid var(--pv-50); padding-top: var(--s-4); }
.result__head { display: flex; align-items: flex-start; gap: var(--s-4); margin-bottom: var(--s-4); }
.result__head strong {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.5rem, 3vw, 2.25rem); line-height: 1.05; color: var(--ink-00);
  letter-spacing: var(--track-display); font-variant-numeric: tabular-nums;
}
.result__head span:not(.dot):not(.tag) { display: block; font-size: var(--t-sm); color: var(--ink-20); margin-top: 4px; }
.dot { width: 15px; height: 15px; border-radius: 50%; flex: none; margin-top: 8px; }
.dot--alto  { background: var(--pv-70); }
.dot--medio { background: var(--pv-30); }
.dot--bajo  { background: var(--granza); }
.dot--na    { background: var(--paper-30); }
.tag {
  font-family: var(--font-text); font-size: var(--t-sm); font-weight: 600;
  color: var(--paper-00); background: var(--pv-70);
  padding: 3px 9px; border-radius: 2px; flex: none;
}
.result__grid { display: grid; gap: 0; }
.result__row {
  display: grid; grid-template-columns: 15px minmax(0, 1fr) auto;
  gap: var(--s-3); align-items: center;
  padding: var(--s-3) 0; border-bottom: 1px solid var(--paper-30);
}
.result__row .dot { margin: 0; }
.result__name { font-size: var(--t-sm); color: var(--ink-10); }
.result__val { font-size: var(--t-sm); color: var(--ink-20); font-variant-numeric: tabular-nums; }
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.chip {
  font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.03em;
  color: var(--pv-70); background: var(--pv-06);
  border: 1px solid var(--pv-15); border-radius: 2px; padding: 4px 9px;
}
.chip--warm { color: var(--siena); background: var(--siena-15); border-color: var(--siena); }

.bench { margin-top: var(--s-7); padding-top: var(--s-5); border-top: 1px solid var(--paper-30); }
.bench h4 { font-family: var(--font-text); font-size: var(--t-sm); font-weight: 600; color: var(--ink-00); margin: 0 0 var(--s-2); }
.bench__list { list-style: none; margin: var(--s-4) 0 0; padding: 0; display: grid; gap: 0; }
.bench__list li {
  display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: var(--s-4);
  padding: var(--s-3) 0; border-bottom: 1px solid var(--paper-30);
}
.bench__list b {
  font-family: var(--font-display); font-size: var(--t-md); color: var(--pv-70);
  font-variant-numeric: tabular-nums; letter-spacing: var(--track-tight);
}
.bench__list span { font-size: var(--t-sm); color: var(--ink-10); }
.bench__list i { display: block; font-style: normal; font-size: var(--t-xs); color: var(--ink-30); margin-top: 3px; }

.ume { background: var(--pv-06); border-top: 2px solid var(--pv-50); padding: var(--s-5); margin-bottom: var(--s-6); }
.ume h4 { font-family: var(--font-text); font-size: var(--t-sm); font-weight: 600; margin: 0 0 var(--s-2); color: var(--pv-70); }
.ume p { font-size: var(--t-sm); color: var(--ink-10); margin: 0; }
.ume__ex { margin-top: var(--s-3) !important; font-style: italic; color: var(--ink-20) !important; }

/* ─── Libro de códigos ──────────────────────────────────────────────────── */
.cb__grid { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.cb { border-top: 2px solid var(--pv-50); padding-top: var(--s-4); }
.cb:nth-child(6) { border-top-color: var(--granza); }
.cb:nth-child(8) { border-top-color: var(--siena); }
.cb__head { display: grid; grid-template-columns: auto 1fr; gap: var(--s-3); align-items: baseline; margin-bottom: var(--s-3); }
.cb__id { font-family: var(--font-display); font-size: var(--t-lg); font-weight: 600; color: var(--pv-50); letter-spacing: var(--track-display); }
.cb__head h3 { font-size: var(--t-md); }
.cb__w { grid-column: 2; font-size: var(--t-xs); color: var(--ink-30); font-variant-numeric: tabular-nums; }
.cb__def { font-size: var(--t-sm); color: var(--ink-10); margin-bottom: var(--s-4); }
.cb__subs { margin: 0 0 var(--s-4); display: grid; gap: var(--s-2); }
.cb__subs dt { font-size: var(--t-sm); font-weight: 600; color: var(--ink-00); }
.cb__subs dd { margin: 2px 0 0; font-size: var(--t-sm); color: var(--ink-20); }
.cb__scene { font-size: var(--t-sm); color: var(--ink-20); background: var(--paper-00); padding: var(--s-3) var(--s-4); border-left: 2px solid var(--paper-30); }
.cb__refs { font-size: var(--t-xs); color: var(--ink-30); margin-top: var(--s-3); }

.layer { margin-bottom: var(--s-6); }
.layer h4 { font-family: var(--font-text); font-size: var(--t-sm); font-weight: 600; letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-30); margin: 0 0 var(--s-3); }
.layer ul { list-style: none; margin: 0; padding: 0; }
.layer li {
  display: grid; grid-template-columns: 76px minmax(0, 1fr) auto auto; gap: var(--s-3);
  align-items: baseline; padding: var(--s-3) 0; border-bottom: 1px solid var(--paper-30);
}
.layer li strong { display: block; font-size: var(--t-sm); color: var(--ink-00); }
.layer li span span { display: block; font-size: var(--t-sm); color: var(--ink-20); margin-top: 2px; }
.layer li b { font-family: var(--font-display); font-size: var(--t-md); color: var(--pv-70); font-variant-numeric: tabular-nums; }
.layer li i { font-style: normal; font-size: var(--t-xs); color: var(--ink-30); }
.layer .tag { background: var(--paper-20); color: var(--ink-10); }

/* ─── Universidades de la región ────────────────────────────────────────── */
.uni__grid { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.uni { border-top: 1px solid var(--paper-30); padding-top: var(--s-4); }
.uni header { display: flex; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-4); }
.uni h4 { font-family: var(--font-display); font-size: var(--t-md); font-weight: 600; margin: 0; letter-spacing: var(--track-tight); }
.uni header span { font-size: var(--t-xs); color: var(--ink-30); }
.uni__time { list-style: none; margin: 0 0 var(--s-4); padding: 0; }
.uni__time li { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: var(--s-3); padding: 7px 0; font-size: var(--t-sm); color: var(--ink-20); }
.uni__y { color: var(--pv-50); font-weight: 600; font-variant-numeric: tabular-nums; }
.uni__pend { font-size: var(--t-sm); color: var(--ink-20); background: var(--siena-15); padding: var(--s-3) var(--s-4); border-left: 2px solid var(--siena); }
.uni__pend b { color: var(--siena); }

/* ─── Ruta de implementación ────────────────────────────────────────────── */
/* Las reglas de .route__* viven ahora en el bloque «Acción», al final. */

/* Las reglas de .qa viven ahora en el bloque «Acción», al final. */


/* ─── Método dentro de su vista ─────────────────────────────────────────────
   El recorrido horizontal con pin necesita ocupar el viewport entero; dentro
   de una vista con página no cabe y deja un vacío. Aquí es una rejilla de
   cinco estadios, que sigue codificando la secuencia por orden de lectura. */
.method-grid {
  display: grid; gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  margin-bottom: var(--s-7);
}
.mstep { border-top: 2px solid var(--pv-50); padding-top: var(--s-4); }
.mstep:nth-child(5) { border-top-color: var(--siena); }
.mstep .method__stage {
  display: block; font-size: var(--t-xs); letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--ink-30); font-weight: 600;
  margin-bottom: var(--s-2); font-variant-numeric: tabular-nums;
}
.mstep .method__title { font-size: var(--t-md); margin: 0 0 var(--s-3); padding-top: 0; }
.mstep .method__body { font-size: var(--t-sm); color: var(--ink-20); margin: 0; }
.mstep .method__dot { display: none; }

/* ─── Evidencia dentro de su vista ──────────────────────────────────────────
   El bloque heredado trae su propia retícula de 12 columnas y su padding.
   Dentro de .page eso duplica márgenes y desborda las barras. */
.page .evidence { padding: 0; background: none; }
.page .evidence.grid { padding-inline: 0; max-width: none; }
.page .evidence__index { grid-column: 1 / 3; top: var(--s-5); }
.page .evidence__stream { grid-column: 4 / 13; }
@media (max-width: 1024px) {
  .page .evidence__index { grid-column: 1 / 13; position: static; }
  .page .evidence__stream { grid-column: 1 / 13; }
}
@media (max-width: 860px) {
  .page .evidence__index, .page .evidence__stream { grid-column: 1 / 5; }
}
/* El carril reserva sitio para el borde de acuarela: con overflow:hidden se
   recortaba justo el remate irregular que hace que la barra parezca pintada. */
.chart__track { margin-right: 18px; }


/* ─── Bloques heredados dentro de una vista ─────────────────────────────────
   Traen su propia retícula de 12 columnas y su padding. Anidados en .page
   quedaban en 173 px de ancho y con la columna del título en cero, lo que
   solapaba el texto. Aquí se les devuelve el ancho de la página. */
.page .rec, .page .trace { padding: 0; background: none; max-width: none; }
.page .rec__head, .page .rec__list,
.page .trace__head, .page .trace__wrap { grid-column: auto; }
.page .rec__head { margin-bottom: var(--s-6); }

/* ============================================================================
   BLOQUE «ACCIÓN» — decisiones, ruta, objeciones y trazabilidad

   Las cuatro vistas comparten un problema: son listas. Una lista sin jerarquía
   interna se lee como un índice, no como un argumento. Lo que sigue les da a
   cada una su propia gramática: carril numerado a la izquierda, metadato
   siempre visible y un solo acento violeta reservado al estado activo.
   ========================================================================== */

/* --- Índice de los tres grupos --------------------------------------------
   Sustituye al titular duplicado. No decora: dice cuántas decisiones hay en
   cada grupo antes de que el lector baje a contarlas. */
.rec__index {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--paper-30);
  border: 1px solid var(--paper-30);
  margin-bottom: var(--s-7);
}
.rec__index a {
  display: grid;
  /* Columna fija para el ordinal: con `auto`, «I» y «III» daban sangrías
     distintas y las tres tarjetas dejaban de alinearse entre sí. */
  grid-template-columns: 2.9rem minmax(0, 1fr);
  column-gap: var(--s-4);
  align-items: baseline;
  padding: var(--s-5);
  background: var(--paper-10);
  text-decoration: none;
  color: inherit;
  transition: background var(--dur-micro) var(--ease-out);
}
.rec__index a:hover { background: var(--paper-00); }
.rec__index i {
  grid-row: 1 / 3;
  font-family: var(--font-display);
  font-style: normal;
  font-size: var(--t-lg);
  font-weight: 600;
  /* --pv-30 sobre el papel da 2,89:1 y el mínimo para texto grande es 3:1. */
  color: var(--pv-50);
  line-height: 1;
  transition: color var(--dur-micro) var(--ease-out);
}
.rec__index a:hover i { color: var(--pv-70); }
.rec__index b {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink-00);
  line-height: 1.35;
}
.rec__index em {
  grid-column: 2;
  font-style: normal;
  font-size: var(--t-xs);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-30);
  margin-top: 5px;
}
@media (max-width: 900px) {
  .rec__index { grid-template-columns: 1fr; }
}

/* --- Barra de control ------------------------------------------------------ */
.rec__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-3);
}
.rec__bar p { margin: 0; font-size: var(--t-sm); color: var(--ink-30); }
.linkbtn {
  border: 0; background: none; padding: 0;
  font: inherit; font-size: var(--t-sm); font-weight: 600;
  color: var(--pv-50); cursor: pointer;
  border-bottom: 1px solid rgba(107, 63, 160, 0.35);
  border-bottom: 1px solid color-mix(in oklab, var(--pv-50) 35%, transparent);
  transition: border-color var(--dur-micro) var(--ease-out),
              color var(--dur-micro) var(--ease-out);
}
.linkbtn:hover { color: var(--pv-70); border-bottom-color: var(--pv-50); }

/* --- Cabecera de grupo ----------------------------------------------------- */
.rec__group {
  display: grid;
  grid-template-columns: 84px 1fr;
  align-items: center;
  gap: 0;
  padding: var(--s-6) 0 var(--s-3);
  border-bottom: 1px solid var(--ink-00);
  scroll-margin-top: 96px;
}
.rec__group b {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--paper-00);
  background: var(--ink-00);
  justify-self: start;
  padding: 4px 11px;
  line-height: 1.25;
}
.rec__group span {
  font-size: var(--t-xs);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-20);
  font-weight: 600;
}

/* --- Fila de decisión ------------------------------------------------------
   El resumen deja de ser una línea con cuatro celdas: pasa a dos renglones,
   con el destinatario y el modo de verificación siempre a la vista. Nadie
   debería tener que desplegar para saber quién decide. */
.rec__list .row { border-bottom: 1px solid var(--paper-30); }
.rec__list .row > summary {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr) auto 34px;
  align-items: start;
  column-gap: var(--s-5);
  row-gap: var(--s-2);
  padding: var(--s-5) 0;
  cursor: pointer;
  position: relative;
  transition: background var(--dur-micro) var(--ease-out);
}
.rec__list .row > summary::before {
  content: "";
  position: absolute;
  left: -18px; top: 0; bottom: 0;
  width: 2px;
  background: var(--pv-50);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform var(--dur-micro) var(--ease-out);
}
.rec__list .row > summary:hover::before,
.rec__list .row[open] > summary::before { transform: scaleY(1); }
.rec__list .row > summary:hover { background: var(--pv-06); }

.rec__list .row__id {
  grid-row: 1 / 3;
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--pv-50);
  letter-spacing: 0.02em;
  line-height: 1.4;
}
.rec__list .row__title {
  grid-column: 2;
  font-size: var(--t-md);
  line-height: 1.28;
  max-width: 40ch;
}
/* El destinatario baja a segundo renglón y se etiqueta: sin la etiqueta,
   «Consejos superiores» podía leerse como un tema, no como un responsable. */
.rec__list .row__who {
  grid-column: 2;
  grid-row: 2;
  font-size: var(--t-sm);
  color: var(--ink-20);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
}
.rec__list .row__who::before {
  content: "Decide";
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-30);
  font-weight: 600;
}
.rec__list .row__chev {
  grid-column: 4;
  grid-row: 1 / 3;
  align-self: center;
  justify-self: end;
}
/* Distintivo del modo de verificación, inyectado desde el panel. Ocupa
   columna propia a la derecha: así los ocho quedan alineados entre sí y se
   comparan de un vistazo, que es lo que se hace con una lista de ocho. */
.rec__list .row__tag { grid-column: 3; grid-row: 1 / 3; align-self: center; }
.row__tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--t-xs);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--pv-70);
  background: var(--pv-06);
  border: 1px solid rgba(107, 63, 160, 0.22);
  border: 1px solid color-mix(in oklab, var(--pv-50) 22%, transparent);
  padding: 3px 9px;
  white-space: nowrap;
}
.row__tag::before {
  content: "";
  width: 5px; height: 5px;
  background: var(--pv-50);
  border-radius: 50%;
}
/* El panel trae del diseño anterior una retícula de `3.25rem minmax(0,1fr)`.
   Al ponerle `grid-column: auto` el contenido caía en la PRIMERA pista, la de
   52 px, y encima llevaba 84 px de margen: ancho negativo y una palabra por
   línea. Aquí no hace falta retícula ninguna — basta un bloque con sangría
   que alinee con la columna del identificador. */
.rec__list .row__panel { display: block; padding: 0 0 var(--s-6); }
.rec__list .row__panel > div { padding-left: 84px; margin-left: 0; max-width: 64rem; }
@media (max-width: 760px) {
  .rec__list .row > summary { grid-template-columns: 52px minmax(0, 1fr) 28px; column-gap: var(--s-4); }
  .rec__list .row__tag { grid-column: 2; grid-row: 3; justify-self: start; margin-top: var(--s-2); }
  .rec__list .row__chev { grid-column: 3; }
  .rec__list .row__panel > div { padding-left: 52px; }
  .rec__list .row__title { max-width: none; }
}

/* --- Ruta de implementación -----------------------------------------------
   Es una secuencia, no una lista. Un eje vertical continuo y un marcador por
   fase hacen visible eso mismo: que el orden es el argumento. */
.route__h { position: relative; }
.route__step {
  display: grid;
  grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  column-gap: var(--s-7);
  padding: var(--s-6) 0 var(--s-7) var(--s-6);
  border-left: 1px solid var(--paper-30);
  position: relative;
}
.route__step:last-child { border-left-color: transparent; }
.route__step::before {
  content: "";
  position: absolute;
  left: -5px; top: calc(var(--s-6) + 0.6em);
  width: 9px; height: 9px;
  background: var(--paper-10);
  border: 2px solid var(--pv-50);
  border-radius: 50%;
}
.route__ord {
  display: block;
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-30);
  font-weight: 600;
  margin-bottom: var(--s-2);
}
.route__when {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 600;
  color: var(--ink-00);
  line-height: 1.12;
  letter-spacing: var(--track-tight);
  text-wrap: balance;
}
.route__what { list-style: none; margin: 0 0 var(--s-5); padding: 0; }
.route__what li {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  gap: var(--s-4);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--paper-20);
  color: var(--ink-10);
  max-width: none;
}
.route__what li:first-child { padding-top: 0; }
.route__refs { display: flex; gap: 5px; flex-wrap: wrap; }
.route__refs span {
  font-family: var(--font-display);
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--pv-70);
  border: 1px solid rgba(107, 63, 160, 0.28);
  border: 1px solid color-mix(in oklab, var(--pv-50) 28%, transparent);
  padding: 2px 7px;
  line-height: 1.5;
}
.route__why {
  font-size: var(--t-sm);
  color: var(--ink-20);
  border-left: 2px solid var(--pv-15);
  padding-left: var(--s-4);
  max-width: var(--measure);
}
@media (max-width: 900px) {
  .route__step { grid-template-columns: 1fr; row-gap: var(--s-4); padding-left: var(--s-5); }
  /* En columna estrecha los distintivos estrangulaban la frase: bajan debajo. */
  .route__what li { grid-template-columns: 1fr; row-gap: var(--s-2); }
}

/* --- Objeciones ------------------------------------------------------------
   La respuesta corta queda siempre visible: quien no despliega se lleva de
   todos modos la posición del trabajo, no solo la objeción. */
.qa { border-bottom: 1px solid var(--paper-30); }
.qa > summary {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  padding: var(--s-6) 0;
  cursor: pointer;
  list-style: none;
}
.qa > summary::-webkit-details-marker { display: none; }
.qa > summary::after { display: none; }
.qa__n {
  grid-row: 1 / 5;
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--pv-50);   /* --pv-30 no llega al 3:1 en negrita a 20px */
  line-height: 1.24;
}
.qa__q {
  grid-column: 2;
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--ink-00);
  line-height: 1.26;
  letter-spacing: var(--track-tight);
  max-width: 54ch;
  text-wrap: balance;
}
.qa__short {
  grid-column: 2;
  margin-top: var(--s-3);
  font-size: var(--t-base);
  color: var(--ink-10);
  max-width: var(--measure);
}
.qa__more {
  grid-column: 2;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: var(--s-3);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--pv-50);
}
.qa__more::after {
  content: "";
  width: 6px; height: 6px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--dur-micro) var(--ease-out);
}
.qa[open] .qa__more::after { transform: rotate(-135deg) translateY(1px); }
.qa__more i { font-style: normal; }
.qa[open] .qa__more i.is-shut,
.qa:not([open]) .qa__more i.is-open { display: none; }
.qa > div { padding: 0 0 var(--s-6) 84px; }
.qa > div p { color: var(--ink-10); }
@media (max-width: 760px) {
  .qa > summary { grid-template-columns: 44px minmax(0, 1fr); }
  .qa > div { padding-left: 44px; }
}

/* --- Trazabilidad ---------------------------------------------------------- */
.trace__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  flex-wrap: wrap;
  margin-bottom: var(--s-5);
}
.field--search {
  display: flex;
  align-items: center;
  gap: 9px;
  border: 1px solid var(--paper-30);
  background: var(--paper-00);
  padding: 0 var(--s-4);
  min-width: min(30rem, 100%);
  transition: border-color var(--dur-micro) var(--ease-out);
}
.field--search:focus-within { border-color: var(--pv-50); }
.field--search svg { width: 15px; height: 15px; color: var(--ink-30); flex: none; }
.field--search input {
  border: 0; background: none; padding: 11px 0; width: 100%;
  font: inherit; font-size: var(--t-sm); color: var(--ink-00);
}
.field--search input:focus { outline: none; }
.field--search input::-webkit-search-cancel-button { filter: grayscale(1); }
.trace__wrap .table caption {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.trace__count { margin: 0; font-size: var(--t-sm); color: var(--ink-30); }
.trace__wrap .table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--paper-10);
}
.trace__wrap .table tbody tr:nth-child(even) { background: var(--pv-06); }
.trace__wrap .table tbody tr:nth-child(even):hover,
.trace__wrap .table tbody tr:hover { background: var(--pv-15); }
.trace__wrap .table tbody tr[hidden] { display: none; }
.trace__empty { padding: var(--s-6) 0; color: var(--ink-30); font-size: var(--t-sm); }

/* ============================================================================
   PAGINADOR DE SECCIONES
   Quince secciones se recorren en orden. Sin esto había que abrir el índice
   lateral entre una y otra, que es exactamente el gesto que sobra.
   ========================================================================== */
.pager {
  margin-top: var(--s-9);
  padding-top: var(--s-4);
  border-top: 1px solid var(--ink-00);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--s-6);
  row-gap: var(--s-5);
}
.view--full .pager { margin-inline: var(--margin); margin-bottom: var(--s-8); }
.pager__pos {
  grid-column: 1 / -1;
  margin: 0 0 var(--s-4);
  font-size: var(--t-xs);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-30);
  font-variant-numeric: tabular-nums;
}
.pager a {
  display: grid;
  gap: 7px;
  padding: var(--s-5) 0;
  text-decoration: none;
  color: inherit;
  min-width: 0;
}
.pager__dir {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--t-xs); letter-spacing: 0.09em; text-transform: uppercase;
  font-weight: 600; color: var(--pv-50);
}
.pager__dir svg { width: 13px; height: 13px; flex: none; transition: transform var(--dur-micro) var(--ease-out); }
.pager a:hover .pager__dir { color: var(--pv-70); }
.pager--next a:hover .pager__dir svg { transform: translateX(3px); }
.pager--prev a:hover .pager__dir svg { transform: translateX(-3px); }
.pager__label {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: var(--track-tight);
  color: var(--ink-00);
  text-wrap: balance;
  transition: color var(--dur-micro) var(--ease-out);
}
.pager a:hover .pager__label { color: var(--pv-70); }
.pager__group { font-size: var(--t-sm); color: var(--ink-30); }
/* La siguiente es la acción principal: se alinea a la derecha y pesa más. */
.pager--next { text-align: right; justify-items: end; border-left: 1px solid var(--paper-30); padding-left: var(--s-6); }
.pager--next .pager__dir { flex-direction: row-reverse; }
.pager--prev .pager__label { font-size: var(--t-md); color: var(--ink-20); }
.pager--empty { min-height: 1px; }
@media (max-width: 760px) {
  /* En columna, primero la siguiente: es a donde va casi todo el mundo.
     El recuento se adelanta con order:-2 — sin eso quedaba entre las dos
     tarjetas y parecía el rótulo de la anterior. */
  .pager { grid-template-columns: 1fr; row-gap: 0; margin-top: var(--s-7); }
  .pager__pos { order: -2; }
  .pager--next { order: -1; text-align: left; justify-items: start; border-left: 0; padding-left: 0; border-bottom: 1px solid var(--paper-30); }
  .pager--next .pager__dir { flex-direction: row; }
  .pager--prev .pager__label { font-size: var(--t-base); }
}

/* ============================================================================
   IMPRESIÓN
   Un policy brief se imprime. En papel no hay índice lateral, ni scroll que
   dispare revelados, ni acordeones que abrir: el documento tiene que salir
   entero y en negro sobre blanco.
   ========================================================================== */
@media print {
  .side, .scrim, .railbtn, .topbar, .pager, .preload, .skip-link,
  .hero__canvas, .wash__canvas, .aguada, .coda__wash, .rec__bar,
  .trace__bar, .tool__actions { display: none !important; }
  body::after { display: none; }          /* el grano del papel */

  html, body { background: #fff; color: #000; }
  .shell { display: block; }
  .view[hidden] { display: block !important; }   /* las quince secciones */
  /* Al pasar de display:none a block la animación de entrada arrancaría de
     cero y el motor de impresión podría capturarla a mitad. Se desactiva. */
  .view { animation: none !important; opacity: 1 !important; }
  .ph__rule::before { transform: scaleX(1) !important; animation: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .page { max-width: none; padding: 0 0 1.5cm; }
  .view { break-before: page; page-break-before: always; }
  .view:first-of-type { break-before: auto; page-break-before: auto; }
  .ph h1, .row__title, .qa__q, .route__when { break-after: avoid; page-break-after: avoid; }
  .row, .qa, .route__step, .rec__group, tr, figure { break-inside: avoid; page-break-inside: avoid; }
  .row__panel, .qa > div { display: block !important; }
  .table { min-width: 0; font-size: 9.5pt; }
  .trace__wrap { overflow: visible; }
  a { color: #000; text-decoration: none; }
}

/* ─── Estado vacío de las herramientas ───────────────────────────────────────
   Un contenedor de resultado en blanco no dice si la herramienta está rota, si
   falta pulsar algo o si no hay nada que mostrar. El estado vacío nombra lo que
   va a aparecer, y desaparece en cuanto hay resultado. */
.tool__empty {
  display: grid; gap: 6px;
  padding: var(--s-5) var(--s-6);
  border: 1px solid var(--paper-30);
  /* Primero el valor llano, después color-mix: quien no entienda la función
     descarta esa línea y se queda con la anterior. Al revés no funciona. */
  background: rgba(246, 242, 236, 0.6);
  background: color-mix(in oklab, var(--paper-00) 60%, transparent);
}
.tool__empty b {
  font-family: var(--font-display); font-size: var(--t-base);
  font-weight: 600; color: var(--ink-20);
}
.tool__empty span { font-size: var(--t-sm); color: var(--ink-30); max-width: 62ch; }


/* ─── Ajustes de pantalla estrecha ───────────────────────────────────────────
   El aire que compone una cabecera a 1440 px es un hueco a 375. */
@media (max-width: 760px) {
  .page { padding-top: var(--s-6); padding-bottom: var(--s-7); }
  .ph { margin-bottom: var(--s-6); }
}
@media (max-width: 560px) {
  .ph__lead, .page__lead { font-size: var(--t-base); }
  .ph h1 { font-size: clamp(1.75rem, 8vw, 2.4rem); }
}

/* ============================================================================
   AGUADAS — la acuarela como argumento, no como adorno

   El hallazgo de la investigación es que el 92,7 % de los mecanismos opera de
   modo implícito. Lo implícito no tiene contorno; un protocolo sí. Por eso la
   geometría —filetes, tablas, retículas— dice «norma» y el pigmento dice
   «lo que se difumina». Cada escena lleva su propio gesto y ninguno se repite.

   Todo son degradados: cero peticiones de red, cero imágenes.

   Tres cosas hacen que parezca pigmento y no un resplandor de interfaz:

   · Velado sustractivo SIN `mix-blend-mode`. La mezcla multiplicativa sobre una
     superficie del tamaño de la vista obliga al compositor a rehacer la mezcla
     en cada fotograma: medido a 1920 px, dejaba la página en 1 fps. Como la
     aguada siempre cae sobre el papel liso —va detrás de todo lo demás— el
     resultado de multiplicar se puede precalcular: el violeta 107,63,160 sobre
     el papel 239,233,226 da 100,58,142, y ese color con alfa normal produce el
     mismo píxel sin coste de mezcla.
   · Borde acumulado — el alfa SUBE justo antes del corte. Al secar, el pigmento
     migra al filo de la mancha y deja un cerco más denso que el centro. Es el
     rasgo que distingue una acuarela de un degradado.
   · Silueta irregular — dos o tres manchas desplazadas por capa, nunca un
     círculo. Un círculo perfecto se lee como interfaz.
   · Rampas largas en lugar de `filter: blur()`. Desenfocar una superficie del
     tamaño de la vista entera —algunas pasan de 5000 px— obliga a rasterizar
     esa superficie completa, y a 1920 px el coste era medible. La misma caída
     se consigue alejando la parada transparente, y un degradado no cuesta nada.

   El techo de intensidad no es estético sino de contraste: con el texto
   terciario a #5B4F6B, un velo del 20 % deja la relación en 4,5:1. Ahí está el
   límite y ninguna aguada bajo texto lo pasa.
   ========================================================================== */
.page { position: relative; }
/* Solo los hijos directos suben de capa: así el pigmento queda debajo del texto
   sin crear un contexto de apilamiento por cada párrafo. */
.page > *:not(.aguada) { position: relative; z-index: 1; }

.aguada {
  position: absolute; inset: 0;
  z-index: 0;
  overflow: hidden;          /* el pigmento nunca provoca scroll horizontal */
  pointer-events: none;
}
.aguada i {
  position: absolute; inset: -18%;   /* margen para que el desenfoque no corte */
  display: block;
  background-repeat: no-repeat;
}

/* Deriva: dos capas con periodos que no vuelven a coincidir, así el conjunto
   nunca repite posición. Solo transform: ni un repintado. */
/* `will-change` promueve estas dos capas a su propia superficie compuesta: sin
   eso, moverlas obliga a repintar todo lo que tienen debajo en cada fotograma. */
@media (prefers-reduced-motion: no-preference) {
  .aguada i:nth-child(1) {
    animation: deriva-a 71s ease-in-out infinite alternate;
    will-change: transform;
  }
  .aguada i:nth-child(2) {
    animation: deriva-b 97s ease-in-out infinite alternate;
    will-change: transform;
  }
}
@keyframes deriva-a {
  /* Solo traslación. Un scale() obliga a rasterizar la capa de nuevo en cada
     fotograma; una traslación la compone sin volver a dibujarla. */
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(1.6%, -1.2%, 0); }
}
@keyframes deriva-b {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-1.9%, 1.6%, 0); }
}

/* ── 1 · Diagnóstico — mancha de apertura, tres lóbulos y cerco de secado ─── */
[data-view="diagnostico"] .aguada i:nth-child(1) {
  background-image:
    radial-gradient(30% 24% at 82% 8%,
      rgba(100,58,142,0.0391) 0 46%, rgba(100,58,142,0.0744) 72%,
      rgba(100,58,142,0.0588) 84%, rgba(100,58,142,0) 100%),
    radial-gradient(22% 20% at 68% 14%,
      rgba(69,40,95,0.0352) 0 50%, rgba(69,40,95,0.0626) 78%, rgba(69,40,95,0) 100%),
    radial-gradient(16% 26% at 92% 20%,
      rgba(100,58,142,0.043) 0 54%, rgba(100,58,142,0) 97.6%);
}
[data-view="diagnostico"] .aguada i:nth-child(2) {
  background-image:
    radial-gradient(34% 22% at 6% 86%,
      rgba(100,58,142,0.0352) 0 48%, rgba(100,58,142,0.0588) 76%, rgba(100,58,142,0) 100%),
    radial-gradient(14% 11% at 20% 78%, rgba(125,67,27,0.0509) 0 40%, rgba(125,67,27,0) 95.16%);
}

/* ── 2 · Evidencia — franja de lavado con el canto duro arriba ─────────────
   Es el borde que deja el pincel cargado al arrancar sobre papel seco. */
[data-view="evidencia"] .aguada i:nth-child(1) {
  background-image: linear-gradient(to bottom,
    rgba(100,58,142,0) 20.5%, rgba(100,58,142,0.1009) 17.4%,
    rgba(100,58,142,0.0557) 22%, rgba(100,58,142,0.0226) 33%, rgba(100,58,142,0) 57.34%);
}
[data-view="evidencia"] .aguada i:nth-child(2) {
  background-image:
    radial-gradient(20% 18% at 97% 58%,
      rgba(69,40,95,0.0557) 0 44%, rgba(69,40,95,0.0957) 74%, rgba(69,40,95,0) 97.6%),
    radial-gradient(15% 13% at 88% 70%, rgba(69,40,95,0.0505) 0 50%, rgba(69,40,95,0) 100%);
}

/* ── 3 · Autoevaluación — gota con cola: cae y arrastra pigmento ──────────── */
[data-view="autoevaluacion"] .aguada i:nth-child(1) {
  background-image:
    radial-gradient(6.5% 4% at 87% 6%,
      rgba(69,40,95,0.2088) 0 52%, rgba(69,40,95,0.1131) 84%, rgba(69,40,95,0) 100%),
    linear-gradient(176deg, rgba(69,40,95,0.087) 0%, rgba(69,40,95,0.0261) 14%, rgba(69,40,95,0) 34.16%);
}
[data-view="autoevaluacion"] .aguada i:nth-child(2) {
  background-image: radial-gradient(30% 16% at 10% 50%,
    rgba(100,58,142,0.087) 0 50%, rgba(100,58,142,0.1305) 78%, rgba(100,58,142,0) 100%);
}

/* ── 4 · Brechas — floración húmedo sobre húmedo: violeta y siena se invaden
   por el frente húmedo, que es como se comportan dos colores sin dejar secar. */
[data-view="brechas"] .aguada i:nth-child(1) {
  background-image:
    radial-gradient(24% 22% at 13% 72%,
      rgba(100,58,142,0.0379) 0 46%, rgba(100,58,142,0.0582) 74%, rgba(100,58,142,0) 97.6%),
    radial-gradient(15% 14% at 25% 64%, rgba(100,58,142,0.0321) 0 52%, rgba(100,58,142,0) 100%);
}
[data-view="brechas"] .aguada i:nth-child(2) {
  background-image:
    radial-gradient(19% 17% at 24% 82%,
      rgba(125,67,27,0.0379) 0 48%, rgba(125,67,27,0.0553) 76%, rgba(125,67,27,0) 100%),
    radial-gradient(13% 20% at 94% 16%, rgba(100,58,142,0.035) 0 54%, rgba(100,58,142,0) 100%);
}

/* ── 5 · Paridad — campo tendido: la escena más corta necesita cuerpo ─────── */
[data-view="paridad"] .aguada i:nth-child(1) {
  background-image:
    radial-gradient(52% 42% at 44% 44%,
      rgba(100,58,142,0.0331) 0 52%, rgba(100,58,142,0.0574) 80%, rgba(100,58,142,0) 100%),
    radial-gradient(30% 34% at 68% 58%, rgba(100,58,142,0.0313) 0 56%, rgba(100,58,142,0) 100%);
}
[data-view="paridad"] .aguada i:nth-child(2) {
  background-image:
    radial-gradient(15% 11% at 13% 17%,
      rgba(69,40,95,0.0618) 0 48%, rgba(69,40,95,0.0887) 76%, rgba(69,40,95,0) 100%),
    radial-gradient(14% 12% at 88% 86%, rgba(125,67,27,0.0574) 0 50%, rgba(125,67,27,0) 100%);
}

/* ── 6 · Clasificador — vetas: el pigmento se deposita siguiendo la fibra ─── */
[data-view="clasificador"] .aguada i:nth-child(1) {
  background-image: repeating-linear-gradient(97deg,
    rgba(100,58,142,0.08) 0 2px, rgba(100,58,142,0.0278) 2px 5px,
    rgba(100,58,142,0) 5px 19px);
  -webkit-mask-image: radial-gradient(44% 58% at 89% 28%, #000 0%, rgba(0,0,0,0.3828) 48%, transparent 78%);
          mask-image: radial-gradient(44% 58% at 89% 28%, #000 0%, rgba(0,0,0,0.3828) 48%, transparent 78%);
}
[data-view="clasificador"] .aguada i:nth-child(2) {
  background-image: radial-gradient(26% 20% at 5% 88%,
    rgba(69,40,95,0.0766) 0 48%, rgba(69,40,95,0.1183) 76%, rgba(69,40,95,0) 100%);
}

/* ── 7 · Libro de códigos — el material más seco: velo alto y una gota al pie ─ */
[data-view="codigos"] .aguada i:nth-child(1) {
  background-image: linear-gradient(to bottom,
    rgba(100,58,142,0.1175) 0%, rgba(100,58,142,0.0435) 8%, rgba(100,58,142,0) 23.18%);
}
[data-view="codigos"] .aguada i:nth-child(2) {
  background-image: radial-gradient(20% 12% at 79% 95%,
    rgba(125,67,27,0.1044) 0 46%, rgba(125,67,27,0.1479) 76%, rgba(125,67,27,0) 100%);
}

/* ── 8 · Indicadores — franja con el canto duro abajo: el pincel levanta ──── */
[data-view="indicadores"] .aguada i:nth-child(1) {
  background-image: linear-gradient(to bottom,
    rgba(100,58,142,0) 6.1%, rgba(100,58,142,0.04) 14%,
    rgba(100,58,142,0.0879) 24%, rgba(100,58,142,0.1462) 27%, rgba(100,58,142,0) 33.67%);
}
[data-view="indicadores"] .aguada i:nth-child(2) {
  background-image: radial-gradient(19% 22% at 3% 58%,
    rgba(69,40,95,0.08) 0 48%, rgba(69,40,95,0.1244) 76%, rgba(69,40,95,0) 100%);
}

/* ── 9 · Marco normativo — esquina cálida: aquí manda la tierra de siena ──── */
[data-view="marco"] .aguada i:nth-child(1) {
  background-image:
    radial-gradient(36% 30% at 100% 100%,
      rgba(125,67,27,0.0592) 0 50%, rgba(125,67,27,0.1009) 78%, rgba(125,67,27,0) 100%),
    radial-gradient(20% 26% at 86% 88%, rgba(125,67,27,0.0531) 0 54%, rgba(125,67,27,0) 100%);
}
[data-view="marco"] .aguada i:nth-child(2) {
  background-image: radial-gradient(20% 14% at 8% 5%,
    rgba(100,58,142,0.0713) 0 48%, rgba(100,58,142,0.1061) 76%, rgba(100,58,142,0) 100%);
}

/* ── 10 · Método — trazo diagonal, como una pincelada de prueba en el margen ─ */
[data-view="metodo"] .aguada i:nth-child(1) {
  background-image: linear-gradient(112deg,
    rgba(100,58,142,0) 43.92%, rgba(100,58,142,0.0446) 43%,
    rgba(100,58,142,0.0955) 49%, rgba(100,58,142,0.036) 55%, rgba(100,58,142,0) 74.42%);
}
[data-view="metodo"] .aguada i:nth-child(2) {
  background-image: radial-gradient(16% 14% at 90% 10%,
    rgba(69,40,95,0.0713) 0 48%, rgba(69,40,95,0.1073) 76%, rgba(69,40,95,0) 100%);
}

/* ── 11 · Ocho decisiones — el lavado sube desde el pie, hacia las decisiones ─ */
[data-view="acciones"] .aguada i:nth-child(1) {
  background-image: linear-gradient(to top,
    rgba(100,58,142,0.1079) 0%, rgba(100,58,142,0.04) 12%, rgba(100,58,142,0) 32.94%);
}
[data-view="acciones"] .aguada i:nth-child(2) {
  background-image:
    radial-gradient(9% 5.5% at 8% 15%,
      rgba(69,40,95,0.1444) 0 50%, rgba(69,40,95,0.0792) 84%, rgba(69,40,95,0) 100%),
    radial-gradient(19% 15% at 95% 42%, rgba(100,58,142,0.0722) 0 52%, rgba(100,58,142,0) 100%);
}

/* ── 12 · Ruta — columna de pigmento que acompaña al eje de fases ─────────── */
[data-view="ruta"] .aguada i:nth-child(1) {
  background-image: linear-gradient(to right,
    rgba(100,58,142,0) 15.25%, rgba(100,58,142,0.1653) 13.6%,
    rgba(100,58,142,0.0696) 17%, rgba(100,58,142,0.0218) 24%, rgba(100,58,142,0) 40.26%);
}
[data-view="ruta"] .aguada i:nth-child(2) {
  background-image: radial-gradient(24% 18% at 85% 86%,
    rgba(125,67,27,0.0957) 0 48%, rgba(125,67,27,0.1479) 76%, rgba(125,67,27,0) 100%);
}

/* ── 13 · Consultas — manchas alternas que bajan con la lista de objeciones ── */
[data-view="consultas"] .aguada i:nth-child(1) {
  background-image:
    radial-gradient(15% 9% at 2% 24%,
      rgba(100,58,142,0.1131) 0 48%, rgba(100,58,142,0.1653) 76%, rgba(100,58,142,0) 100%),
    radial-gradient(14% 8% at 99% 55%,
      rgba(100,58,142,0.1044) 0 48%, rgba(100,58,142,0.1566) 76%, rgba(100,58,142,0) 100%);
}
[data-view="consultas"] .aguada i:nth-child(2) {
  background-image: radial-gradient(17% 11% at 9% 90%,
    rgba(69,40,95,0.0957) 0 50%, rgba(69,40,95,0.1392) 78%, rgba(69,40,95,0) 100%);
}

/* ── 14 · Trazabilidad — velo mínimo: es la escena de la comprobación ─────── */
[data-view="cifras"] .aguada i:nth-child(1) {
  background-image: linear-gradient(to bottom,
    rgba(100,58,142,0.1001) 0%, rgba(100,58,142,0.0348) 9%, rgba(100,58,142,0) 25.62%);
}
[data-view="cifras"] .aguada i:nth-child(2) {
  background-image: radial-gradient(13% 17% at 99% 10%,
    rgba(69,40,95,0.1044) 0 50%, rgba(69,40,95,0.1479) 78%, rgba(69,40,95,0) 100%);
}

@media print { .aguada { display: none !important; } }

/* ── Tercera capa: pigmento a plena carga en los márgenes ────────────────────
   Bajo texto el pigmento tiene techo: con el terciario a #5B4F6B, un velo por
   encima del 20 % baja de 4,5:1 y deja de ser legible. Pero el relleno lateral
   de .page no lleva texto: son entre 20 y 112 px a cada lado, según el ancho.
   Ahí la acuarela puede ir al 30 % y sangrar hacia dentro como en el papel.
   Es lo que hace que las aguadas se vean sin comprometer una sola línea.
   Los degradados se anclan cerca de 0 % y 100 %, así que se quedan en el
   margen por construcción, sin máscaras que mantener. */
/* Las posiciones en porcentaje se resuelven contra la ALTURA TOTAL de la vista.
   En una sección de 3000 px eso deja casi todo el pigmento fuera de la primera
   pantalla. Esta capa se repite en vertical con dos periodos que no coinciden
   —780 y 1130 px—, así que su suma no vuelve a repetirse en ninguna página real
   y hay acuarela a cualquier altura del scroll. */
.aguada i:nth-child(3) {
  background-repeat: repeat-y;
  background-size: 100% 780px, 100% 1130px, 100% 940px;
}
/* La capa de márgenes se repite a lo largo de toda la altura de la vista, que
   en algunas pasa de 5000 px. Animarla obligaba a componer esa superficie
   entera en cada fotograma para un desplazamiento que nadie percibe: se queda
   quieta. Las otras dos siguen derivando y bastan para que el papel «respire». */
/* En pantalla estrecha el margen es de 20 px y el desenfoque se le sale:
   se rebaja la carga para que nunca alcance a la columna de texto. */
@media (max-width: 760px) { .aguada i:nth-child(3) { opacity: 0.42; } }

[data-view="diagnostico"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(4.5% 26% at 100% 34%, rgba(100,58,142,0.30) 0 52%, rgba(100,58,142,0) 100%),
    radial-gradient(3% 14% at 99% 62%, rgba(69,40,95,0.26) 0 50%, rgba(69,40,95,0) 100%);
}
[data-view="evidencia"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(4% 18% at 0% 22%, rgba(100,58,142,0.30) 0 50%, rgba(100,58,142,0) 100%),
    radial-gradient(3.5% 22% at 0% 58%, rgba(100,58,142,0.24) 0 52%, rgba(100,58,142,0) 100%),
    radial-gradient(2.5% 10% at 1% 86%, rgba(125,67,27,0.24) 0 50%, rgba(125,67,27,0) 100%);
}
[data-view="autoevaluacion"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(3% 34% at 100% 46%, rgba(69,40,95,0.28) 0 54%, rgba(69,40,95,0) 100%);
}
[data-view="brechas"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(4% 20% at 0% 40%, rgba(125,67,27,0.28) 0 50%, rgba(125,67,27,0) 100%),
    radial-gradient(4% 24% at 100% 66%, rgba(100,58,142,0.28) 0 52%, rgba(100,58,142,0) 100%);
}
[data-view="paridad"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(5% 30% at 0% 50%, rgba(100,58,142,0.30) 0 52%, rgba(100,58,142,0) 100%),
    radial-gradient(3% 12% at 100% 24%, rgba(69,40,95,0.24) 0 50%, rgba(69,40,95,0) 100%);
}
[data-view="clasificador"] .aguada i:nth-child(3) {
  background-image:
    repeating-linear-gradient(97deg, rgba(100,58,142,0.26) 0 2px, rgba(100,58,142,0) 2px 13px);
  -webkit-mask-image: radial-gradient(5% 40% at 100% 40%, #000 0 55%, transparent 88%);
          mask-image: radial-gradient(5% 40% at 100% 40%, #000 0 55%, transparent 88%);
}
[data-view="codigos"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(3% 16% at 0% 16%, rgba(100,58,142,0.26) 0 50%, rgba(100,58,142,0) 100%),
    radial-gradient(3% 20% at 0% 74%, rgba(125,67,27,0.22) 0 52%, rgba(125,67,27,0) 100%);
}
[data-view="indicadores"] .aguada i:nth-child(3) {
  background-image:
    linear-gradient(to right, rgba(100,58,142,0.26) 0%, rgba(100,58,142,0.10) 2.4%, rgba(100,58,142,0) 6.71%),
    radial-gradient(3% 16% at 100% 70%, rgba(69,40,95,0.26) 0 50%, rgba(69,40,95,0) 100%);
}
[data-view="marco"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(4.5% 26% at 0% 62%, rgba(125,67,27,0.30) 0 52%, rgba(125,67,27,0) 100%),
    radial-gradient(3% 12% at 100% 20%, rgba(100,58,142,0.24) 0 50%, rgba(100,58,142,0) 100%);
}
[data-view="metodo"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(3.5% 22% at 100% 28%, rgba(100,58,142,0.28) 0 52%, rgba(100,58,142,0) 100%),
    radial-gradient(3% 16% at 100% 74%, rgba(69,40,95,0.24) 0 50%, rgba(69,40,95,0) 100%);
}
[data-view="acciones"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(4% 28% at 0% 68%, rgba(100,58,142,0.30) 0 52%, rgba(100,58,142,0) 100%),
    radial-gradient(2.5% 10% at 0% 22%, rgba(69,40,95,0.26) 0 50%, rgba(69,40,95,0) 100%);
}
[data-view="ruta"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(4% 30% at 100% 44%, rgba(100,58,142,0.28) 0 52%, rgba(100,58,142,0) 100%),
    radial-gradient(3% 12% at 100% 84%, rgba(125,67,27,0.24) 0 50%, rgba(125,67,27,0) 100%);
}
[data-view="consultas"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(3% 12% at 0% 20%, rgba(100,58,142,0.28) 0 50%, rgba(100,58,142,0) 100%),
    radial-gradient(3% 12% at 100% 48%, rgba(100,58,142,0.26) 0 50%, rgba(100,58,142,0) 100%),
    radial-gradient(3% 12% at 0% 76%, rgba(69,40,95,0.24) 0 50%, rgba(69,40,95,0) 100%);
}
[data-view="cifras"] .aguada i:nth-child(3) {
  background-image:
    radial-gradient(3% 34% at 100% 40%, rgba(69,40,95,0.26) 0 54%, rgba(69,40,95,0) 100%),
    radial-gradient(2.5% 12% at 0% 12%, rgba(100,58,142,0.24) 0 50%, rgba(100,58,142,0) 100%);
}
