/* ============================================================================
   ScriptorIA — piezas del sitio
   ============================================================================
   Cada bloque de este fichero es UNA pieza interactiva de la web pública.
   Todas cuelgan de `.sc-site` y usan los tokens de `scriptoria-site.css`.
   Ninguna pieza inventa color: el cian de los hilos es `--filament`
   (= `--sky-400`) y sólo señala procedencia; el verde/ámbar/rojo son los tres
   estados de anclaje reales del motor y no se usan para decorar.
   ========================================================================= */

/* ══ 1. LA FORJA ══════════════════════════════════════════════════════════
   Banco de composición: fuentes fijadas → espina de bloques → entregable.
   Enseña el modelo mental del producto: una plantilla es una espina de
   bloques tipados, y el tipo del bloque decide el formato de salida. */

/* `stretch` estiraba las tres columnas al alto de la más larga y dejaba 152,8 px
   de vacío bajo las cortas. Cada columna mide lo que tiene. */
.forge {
  display: grid; grid-template-columns: .82fr 1.05fr 1.13fr; gap: 16px;
  align-items: start;
}
@media (max-width: 1080px) { .forge { grid-template-columns: 1fr 1fr; } .forge-out { grid-column: 1 / -1; } }
@media (max-width: 700px)  { .forge { grid-template-columns: 1fr; } }

.forge-col {
  background: #fff; border: 1px solid rgba(13,26,38,.09);
  border-radius: var(--radius-card); padding: 16px; display: flex;
  flex-direction: column; gap: 10px; min-height: 430px;
}
/* `min-height` porque las columnas 1 y 3 llevan un dato a la derecha que
   engorda su cabecera a 17 px y la central se quedaba en 11: el rótulo del
   medio se apoyaba 3,1 px por encima de sus vecinos, y se nota. */
.forge-head { display: flex; align-items: baseline; justify-content: space-between;
              gap: 10px; min-height: 17px; }
.forge-head h3 {
  font-family: var(--font-mono); font-size: .6875rem; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--slate-600); line-height: 1;
}
.forge-count { font-family: var(--font-mono); font-size: .6875rem; color: var(--slate-600); }

/* Fuentes fijadas */
.forge-src { display: flex; flex-direction: column; gap: 6px; }
.forge-src-item {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px;
  border-radius: var(--radius); background: var(--slate-50);
  border: 1px solid transparent; cursor: default; transition: background .18s, border-color .18s;
}
.forge-src-item.is-lit { background: var(--sky-50); border-color: var(--sky-200); }
.forge-src-ico { width: 26px; height: 26px; border-radius: 7px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(70,130,180,.13); color: var(--link); }
.forge-src-ico svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
                     stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.forge-src-tx { min-width: 0; }
.forge-src-tx b { display: block; font-size: .8125rem; font-weight: 600; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.forge-src-tx span { font-size: .6875rem; color: var(--slate-600);
                     font-family: var(--font-mono); line-height: 1.3; }

/* Espina de bloques */
.forge-spine { display: flex; flex-direction: column; gap: 7px; position: relative; }
.forge-spine::before {
  content: ''; position: absolute; left: 15px; top: 8px; bottom: 8px; width: 1px;
  background: repeating-linear-gradient(180deg, rgba(70,130,180,.35) 0 4px, transparent 4px 8px);
}
.forge-block {
  position: relative; display: flex; align-items: center; gap: 10px;
  padding: 9px 11px 9px 10px; border-radius: var(--radius);
  border: 1px solid rgba(13,26,38,.1); background: #fff; cursor: pointer;
  text-align: left; width: 100%; font-family: var(--font-body);
  transition: border-color .18s, box-shadow .18s, transform .18s;
}
.forge-block:hover { border-color: var(--sky-200); transform: translateX(2px); }
.forge-block.is-active {
  border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(70,130,180,.12);
}
.forge-block-n {
  width: 22px; height: 22px; border-radius: 6px; flex: none; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: .625rem; font-weight: 700;
  background: var(--ink); color: #fff; line-height: 1;
}
.forge-block.is-active .forge-block-n { background: var(--primary-color); }
.forge-block-tx { min-width: 0; flex: 1; }
.forge-block-tx b { display: block; font-size: .8125rem; font-weight: 600; line-height: 1.25; }
.forge-block-tx span { font-size: .6875rem; color: var(--slate-600); line-height: 1.3; }
.forge-kind {
  font-family: var(--font-mono); font-size: .625rem; font-weight: 700; padding: 2px 7px;
  border-radius: 999px; flex: none; line-height: 1.5; letter-spacing: .04em;
}
.forge-kind[data-k="sections"] { background: var(--sky-50);      color: var(--sky-700); }
.forge-kind[data-k="table"]    { background: var(--mint-50);     color: var(--mint-700); }
.forge-kind[data-k="object"]   { background: var(--lavender-200); color: var(--lavender-700); }

/* Selector de tipo de bloque */
.forge-kinds { display: flex; gap: 5px; flex-wrap: wrap; padding-top: 4px; }
.forge-kinds button {
  padding: 5px 10px; border-radius: 999px; border: 1px solid rgba(13,26,38,.13);
  background: #fff; cursor: pointer; font-family: var(--font-mono);
  font-size: .625rem; font-weight: 700; letter-spacing: .04em; color: var(--slate-600);
  line-height: 1.6; transition: all .15s;
}
.forge-kinds button:hover { border-color: var(--primary-color); color: var(--accent-color); }
.forge-kinds button.is-on { background: var(--ink); border-color: var(--ink); color: #fff; }

/* Salida */
.forge-out { background: var(--ink); border-color: rgba(255,255,255,.1); }
.forge-out .forge-head h3 { color: var(--sky-400); }
.forge-out .forge-count { color: var(--slate-300); }
.forge-paper {
  flex: 1; min-height: 0; border-radius: var(--radius); background: var(--vellum);
  padding: 18px 20px; overflow: hidden; position: relative;
  display: flex; flex-direction: column; gap: 9px;
  box-shadow: 0 8px 26px rgba(0,0,0,.34);
}
.forge-paper::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, transparent 68%, var(--vellum) 100%);
}
.fp-title { font-family: var(--font-heading); font-size: .9375rem; font-weight: 700;
            color: var(--ink); line-height: 1.15; }
.fp-meta { font-family: var(--font-mono); font-size: .625rem; color: var(--slate-600);
           letter-spacing: .05em; line-height: 1; }
.fp-rule { height: 1px; background: rgba(13,26,38,.14); }
.fp-h { font-family: var(--font-heading); font-size: .75rem; font-weight: 700;
        color: var(--ink); line-height: 1.2; margin-top: 4px; }
.fp-line { height: 6px; border-radius: 3px; background: rgba(13,26,38,.13); }
.fp-line.w90 { width: 90%; } .fp-line.w76 { width: 76%; } .fp-line.w64 { width: 64%; }
.fp-line.w48 { width: 48%; } .fp-line.w82 { width: 82%; }
.fp-cite { display: inline-block; width: 26px; height: 6px; border-radius: 3px;
           background: var(--sky-400); opacity: .75; }
/* Tabla */
.fp-table { display: grid; gap: 3px; }
.fp-tr { display: grid; gap: 3px; }
.fp-td { height: 13px; border-radius: 2px; background: rgba(13,26,38,.1); }
.fp-tr.head .fp-td { background: rgba(44,81,113,.4); }
/* Objeto (JSON) */
.fp-json { font-family: var(--font-mono); font-size: .6875rem; line-height: 1.6;
           color: var(--slate-800); white-space: pre; overflow: hidden; }
/* Las columnas de la tabla de la forja las fija el CSS y no un `style` en
   línea generado por el JS: es lo que permite retirar `'unsafe-inline'` del
   CSP sin que la pieza se desmorone. El JS acota a 8 el número de columnas. */
.fp-tr[data-cols="1"] { grid-template-columns: repeat(1, 1fr); }
.fp-tr[data-cols="2"] { grid-template-columns: repeat(2, 1fr); }
.fp-tr[data-cols="3"] { grid-template-columns: repeat(3, 1fr); }
.fp-tr[data-cols="4"] { grid-template-columns: repeat(4, 1fr); }
.fp-tr[data-cols="5"] { grid-template-columns: repeat(5, 1fr); }
.fp-tr[data-cols="6"] { grid-template-columns: repeat(6, 1fr); }
.fp-tr[data-cols="7"] { grid-template-columns: repeat(7, 1fr); }
.fp-tr[data-cols="8"] { grid-template-columns: repeat(8, 1fr); }

.fp-json .k { color: var(--sky-700); }
.fp-json .s { color: var(--mint-700); }
.fp-json .c { color: var(--slate-600); }

.forge-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding-top: 4px;
}
.forge-fmt {
  font-family: var(--font-mono); font-size: .6875rem; font-weight: 700;
  color: var(--sky-400); letter-spacing: .08em;
}
.forge-note { font-size: .6875rem; color: var(--slate-300); line-height: 1.35; }

/* ══ 2. EL BISTURÍ DE TRAZABILIDAD ════════════════════════════════════════
   Un párrafo generado con canaleta de anclaje por frase. Al pasar por una
   frase se encienden sus fragmentos fuente y se traza el hilo. El interruptor
   «sin anclaje» enseña lo que escribe un modelo suelto: la misma prosa, con
   las cifras inventadas. */

.trace { display: grid; grid-template-columns: 1.25fr .75fr; gap: 22px; align-items: start; }
@media (max-width: 940px) { .trace { grid-template-columns: 1fr; } }

.trace-doc {
  background: var(--vellum); border-radius: var(--radius-card);
  padding: 30px 30px 26px; position: relative; box-shadow: var(--shadow-card);
  border: 1px solid var(--vellum-deep);
}
.trace-switch { display: inline-flex; padding: 3px; border-radius: 999px;
                background: rgba(13,26,38,.07); margin-bottom: 20px; gap: 2px; }
.trace-switch button {
  padding: 6px 14px; border-radius: 999px; border: none; background: none;
  cursor: pointer; font-size: .75rem; font-weight: 600; color: var(--slate-600);
  line-height: 1.3; transition: background .18s, color .18s;
}
.trace-switch button.is-on { background: #fff; color: var(--accent-color);
                             box-shadow: 0 1px 4px rgba(0,0,0,.1); }
.trace-doc h3 {
  font-family: var(--font-heading); font-size: 1.0625rem; font-weight: 700;
  color: var(--ink); margin-bottom: 4px;
}
.trace-doc .trace-sub {
  font-family: var(--font-mono); font-size: .6875rem; color: var(--slate-600);
  letter-spacing: .05em; margin-bottom: 20px;
}
.trace-body { display: flex; flex-direction: column; gap: 3px; }
.trace-s {
  display: grid; grid-template-columns: 4px 1fr; gap: 12px; align-items: start;
  padding: 5px 8px 5px 0; border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  cursor: default; transition: background .18s;
}
.trace-s:hover, .trace-s.is-lit { background: rgba(255,255,255,.72); }
/* La canaleta lleva DOS portadores del estado, no uno. El color de la barra
   sigue estando —es lo que se lee de un vistazo— pero encima va un glifo con
   forma propia: ● anclado, ◐ parcial, ○ sin respaldo. Se distinguen por
   silueta, sin depender del tono, que es lo que exige WCAG 1.4.1. El tercero
   es el texto que sólo oye el lector de pantalla (`.u-sr`, en el JS).
   El glifo usa la rampa -700 y no la -600 porque aquí es información, no
   adorno: sobre `--vellum` da 4,86 / 4,86 / 4,94:1 según el estado. */
.trace-gutter {
  flex: 0 0 auto; width: 15px; align-self: stretch;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
}
.trace-gutter i {
  font-style: normal; font-size: .75rem; line-height: 1; color: var(--slate-400);
}
.trace-gutter::after {
  content: ''; flex: 1; width: 4px; border-radius: 2px; background: var(--slate-200);
}
.trace-s[data-g="anchored"] .trace-gutter::after { background: var(--anchored); }
.trace-s[data-g="partial"]  .trace-gutter::after { background: var(--partial); }
.trace-s[data-g="unbacked"] .trace-gutter::after { background: var(--unbacked); }
.trace-s[data-g="anchored"] .trace-gutter i { color: var(--mint-700); }
.trace-s[data-g="partial"]  .trace-gutter i { color: var(--marigold-700); }
.trace-s[data-g="unbacked"] .trace-gutter i { color: var(--rose-700); }
.trace-s p { font-size: .9375rem; line-height: 1.7; color: #24313d; }
.trace-fig {
  font-family: var(--font-mono); font-weight: 600; padding: 0 3px; border-radius: 3px;
  background: rgba(40,148,106,.14); color: #1b6d4e;
  box-shadow: inset 0 -1px 0 rgba(40,148,106,.4);
}
.trace-s[data-g="unbacked"] .trace-fig {
  background: rgba(212,80,94,.14); color: #a8323f;
  box-shadow: inset 0 -1px 0 rgba(212,80,94,.5);
}
.trace-legend { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 22px;
  padding-top: 16px; border-top: 1px solid var(--vellum-deep); }

.trace-side { display: flex; flex-direction: column; gap: 10px; position: sticky; top: 76px; }
.trace-side-h {
  font-family: var(--font-mono); font-size: .6875rem; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--slate-600); line-height: 1;
}
/* El estado «apagado» iba al 45 % de opacidad y dejaba el texto por debajo del
   mínimo de contraste: un fragmento sin resaltar seguía siendo contenido que
   hay que poder leer. Ahora se atenúa con el borde y el fondo, no con el
   texto. */
.trace-frag {
  border: 1px solid rgba(13,26,38,.08); border-radius: var(--radius);
  padding: 11px 13px; background: #fbfbfa; transition: all .2s;
}
.trace-frag.is-lit { background: #fff; border-color: var(--sky-400);
                     box-shadow: 0 0 0 3px rgba(106,180,240,.16); }
.trace-frag-h { display: flex; align-items: center; justify-content: space-between;
                gap: 8px; margin-bottom: 6px; }
.trace-frag-h b { font-size: .75rem; font-weight: 600; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trace-frag-q { font-size: .8125rem; line-height: 1.55; color: var(--text-light); }
.trace-frag-id { font-family: var(--font-mono); font-size: .625rem; color: var(--slate-600);
                 margin-top: 7px; word-break: break-all; line-height: 1.35; }
.trace-empty {
  border: 1px dashed rgba(212,80,94,.4); background: var(--rose-50);
  border-radius: var(--radius); padding: 14px; font-size: .8125rem; line-height: 1.55;
  color: #a8323f;
}

/* ══ 3. LA CINTA (pipeline dibujado al hacer scroll) ══════════════════════ */
/* La columna se acota y se centra a propósito. Con el ancho completo de `.wrap`
   el texto seguía rompiendo a 62ch —que es lo legible— y dejaba media pantalla
   vacía a la derecha: parecía un fallo de maquetación, no una decisión. */
.ribbon { position: relative; max-width: 860px; margin-inline: auto; }
.ribbon-track { position: relative; padding-left: 62px; }
.ribbon-svg { position: absolute; left: 0; top: 0; width: 62px; height: 100%;
              overflow: visible; pointer-events: none; }
.ribbon-svg path { fill: none; stroke-width: 2; stroke-linecap: round; }
/* El raíl al 18 % no se veía: sobre papel cálido eso es un gris que el ojo
   descarta, y sin él los siete puntos parecían sueltos en vez de un recorrido.
   Va punteado porque el hilo continuo es el que se dibuja encima al bajar. */
.ribbon-svg .rail { stroke: rgba(44,81,113,.34); stroke-dasharray: 3 7; }
.ribbon-svg .live { stroke: var(--filament);
  filter: drop-shadow(0 0 5px rgba(106,180,240,.55)); }
.ribbon-step { position: relative; padding: 0 0 46px; }
.ribbon-step:last-child { padding-bottom: 0; }
.ribbon-dot {
  position: absolute; left: -62px; top: 2px; width: 34px; height: 34px;
  border-radius: 50%; background: var(--paper); border: 2px solid rgba(44,81,113,.4);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: .6875rem; font-weight: 700;
  color: var(--slate-600); transition: all .35s; z-index: 1; margin-left: 14px;
}
.band--vellum .ribbon-dot { background: var(--vellum); }
.ribbon-step.is-in .ribbon-dot {
  border-color: var(--primary-color); color: #fff; background: var(--accent-color);
  box-shadow: 0 0 0 5px rgba(106,180,240,.2);
}
.ribbon-step h2 { font-size: 1.1875rem; font-weight: 700; margin-bottom: 8px; }
.ribbon-step > p { font-size: .9375rem; line-height: 1.68; color: var(--text-light);
                   max-width: 62ch; }
.ribbon-tech {
  margin-top: 12px; display: flex; flex-wrap: wrap; gap: 6px;
}
.ribbon-tech code {
  font-family: var(--font-mono); font-size: .6875rem; padding: 3px 8px;
  border-radius: var(--radius-sm); background: rgba(44,81,113,.08);
  color: var(--accent-color); line-height: 1.5;
}
@media (max-width: 640px) {
  .ribbon-track { padding-left: 46px; }
  .ribbon-dot { left: -46px; margin-left: 6px; width: 30px; height: 30px; }
}

/* ══ 4. ATLAS DE LA API (lee el openapi.json real) ════════════════════════ */
.atlas-bar {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  margin-bottom: 22px;
}
.atlas-search { flex: 1; min-width: 220px; position: relative; }
.atlas-search input {
  width: 100%; padding: 11px 14px 11px 38px; border-radius: var(--radius);
  border: 1px solid rgba(13,26,38,.14); font-family: var(--font-body);
  font-size: .875rem; background: #fff;
}
.atlas-search input:focus { outline: none; border-color: var(--primary-color);
  box-shadow: 0 0 0 3px rgba(70,130,180,.1); }
.atlas-search svg { position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; fill: none; stroke: var(--slate-400); stroke-width: 2;
  stroke-linecap: round; }
.atlas-stats { display: flex; gap: 20px; flex-wrap: wrap; }
.atlas-stat { display: flex; flex-direction: column; gap: 2px; }
.atlas-stat b { font-family: var(--font-heading); font-size: 1.375rem; font-weight: 700;
                color: var(--accent-color); line-height: 1; }
.atlas-stat span { font-size: .6875rem; color: var(--slate-600);
                   font-family: var(--font-mono); letter-spacing: .05em; }

.atlas-groups { display: flex; flex-direction: column; gap: 10px; }
.atlas-group { border: 1px solid rgba(13,26,38,.09); border-radius: var(--radius-card);
               background: #fff; overflow: hidden; }
/* El `overflow: hidden` redondea las esquinas del grupo, y de paso recortaba el
   anillo de foco de su cabecera, que ocupa todo el ancho. Se abre sólo mientras
   hay algo enfocado dentro: el redondeo se pierde durante ese instante y el
   anillo se ve entero, que es lo que importa. */
.atlas-group:has(:focus-visible) { overflow: visible; }
.atlas-group-h {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 18px;
  background: none; border: none; cursor: pointer; text-align: left;
  font-family: var(--font-body);
}
.atlas-group-h:hover { background: var(--slate-50); }
.atlas-group-h b { font-family: var(--font-heading); font-size: .9375rem; font-weight: 600;
                   flex: 1; line-height: 1.2; }
.atlas-group-h .chev { width: 16px; height: 16px; fill: none; stroke: var(--slate-400);
  stroke-width: 2.2; stroke-linecap: round; transition: transform .2s; flex: none; }
.atlas-group.is-open .chev { transform: rotate(180deg); }
.atlas-ops { display: none; border-top: 1px solid rgba(13,26,38,.07); }
.atlas-group.is-open .atlas-ops { display: block; }
.atlas-op {
  display: grid; grid-template-columns: 62px 1fr auto; gap: 12px; align-items: center;
  padding: 9px 18px; border-bottom: 1px solid rgba(13,26,38,.05);
}
.atlas-op:last-child { border-bottom: none; }
.atlas-op:hover { background: var(--sky-50); }
.atlas-m {
  font-family: var(--font-mono); font-size: .625rem; font-weight: 700; text-align: center;
  padding: 3px 0; border-radius: 4px; letter-spacing: .05em; line-height: 1.5;
}
.atlas-m[data-m="get"]    { background: var(--sky-50);      color: var(--sky-700); }
.atlas-m[data-m="post"]   { background: var(--mint-50);     color: var(--mint-700); }
.atlas-m[data-m="put"]    { background: var(--marigold-50); color: var(--marigold-700); }
.atlas-m[data-m="patch"]  { background: var(--marigold-50); color: var(--marigold-700); }
.atlas-m[data-m="delete"] { background: var(--rose-50);     color: var(--rose-700); }
.atlas-path { font-family: var(--font-mono); font-size: .75rem; color: var(--slate-800);
              overflow: hidden; text-overflow: ellipsis; line-height: 1.4; }
.atlas-path em { font-style: normal; color: var(--link); }
.atlas-sum { font-size: .75rem; color: var(--slate-600); text-align: right;
             max-width: 34ch; line-height: 1.35; }
@media (max-width: 760px) {
  .atlas-op { grid-template-columns: 56px 1fr; }
  .atlas-sum { display: none; }
}
.atlas-load { padding: 22px 40px; text-align: center; color: var(--slate-600);
              font-family: var(--font-mono); font-size: .8125rem; }

/* ══ 5. CASOS ═════════════════════════════════════════════════════════════ */
.cases { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
@media (max-width: 980px) { .cases { grid-template-columns: 1fr; } }
.case {
  display: flex; flex-direction: column; border-radius: var(--radius-card);
  overflow: hidden; background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.1);
}
.case-img { aspect-ratio: 16/9; overflow: hidden; background: var(--ink-deep); }
.case-img img { width: 100%; height: 100%; object-fit: cover;
                transition: transform .6s cubic-bezier(.2,.6,.2,1); }
.case:hover .case-img img { transform: scale(1.045); }
.case-body { padding: 20px 22px 6px; flex: 1; }
.case-tag { font-family: var(--font-mono); font-size: .625rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--sky-400); margin-bottom: 9px; }
.case-body h3 { font-size: 1.0625rem; font-weight: 700; color: #fff; margin-bottom: 9px; }
.case-body p { font-size: .875rem; line-height: 1.62; color: #9db3c6; }
.case-out { padding: 16px 22px 20px; margin-top: 14px;
            border-top: 1px solid rgba(255,255,255,.09); }
.case-out .lab { font-family: var(--font-mono); font-size: .625rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--slate-300); margin-bottom: 9px; }
.case-out ul { list-style: none; margin: 0; padding: 0; display: flex;
               flex-direction: column; gap: 6px; }
.case-out li { display: flex; align-items: baseline; gap: 8px; font-size: .8125rem;
               line-height: 1.45; color: #b9cadb; }
.case-out li code { font-family: var(--font-mono); font-size: .625rem; font-weight: 700;
  padding: 2px 6px; border-radius: 4px; background: rgba(106,180,240,.15);
  color: var(--sky-400); flex: none; line-height: 1.5; }

/* ══ 6. FORMATOS ══════════════════════════════════════════════════════════ */
.fmt-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
@media (max-width: 860px) { .fmt-grid { grid-template-columns: repeat(2, 1fr); } }
.fmt {
  border: 1px solid rgba(13,26,38,.1); border-radius: var(--radius);
  padding: 16px 16px 14px; background: #fff; transition: all .2s;
}
.fmt:hover { border-color: var(--primary-color); transform: translateY(-2px);
             box-shadow: var(--shadow-card); }
.fmt-ext { font-family: var(--font-mono); font-size: .8125rem; font-weight: 700;
           color: var(--accent-color); line-height: 1; margin-bottom: 8px; }
.fmt b { display: block; font-size: .8125rem; font-weight: 600; margin-bottom: 4px;
         line-height: 1.25; }
.fmt span { font-size: .75rem; color: var(--text-light); line-height: 1.5; display: block; }
.fmt-kind { font-family: var(--font-mono); font-size: .625rem; color: var(--slate-600);
            margin-top: 9px; padding-top: 8px; border-top: 1px solid rgba(13,26,38,.07);
            display: block; letter-spacing: .04em; }

/* ══ 7. PRECIOS ═══════════════════════════════════════════════════════════ */
/* `align-items: start` dejaba cada tarjeta con su alto natural, y como Pro
   tiene un punto más que Basic, las tres llamadas a la acción quedaban a
   tres alturas distintas (755 / 842 / 774 px medidos). `stretch` iguala
   los altos y, con la lista estirada, los botones caen a la misma línea. */
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px;
         align-items: stretch; }
@media (max-width: 940px) { .plans { grid-template-columns: 1fr; } }
.plan {
  background: #fff; border: 1px solid rgba(13,26,38,.1); border-radius: var(--radius-card);
  padding: 26px 24px 24px; display: flex; flex-direction: column; gap: 12px;
}
.plan.is-hot { background: var(--ink); border-color: var(--ink); color: #c7d6e2; }
.plan-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.plan-name { font-family: var(--font-heading); font-size: 1.125rem; font-weight: 700;
             color: var(--accent-color); line-height: 1; }
.plan.is-hot .plan-name { color: #fff; }
.plan-tag { font-family: var(--font-mono); font-size: .625rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; padding: 3px 8px; border-radius: 999px;
  background: rgba(70,130,180,.12); color: var(--link); line-height: 1.5; }
.plan.is-hot .plan-tag { background: rgba(106,180,240,.2); color: var(--sky-400); }
.plan-price { display: flex; align-items: baseline; gap: 6px; }
.plan-price .pv { font-family: var(--font-heading); font-size: 2.125rem; font-weight: 700;
                  color: var(--ink); line-height: 1; letter-spacing: -.02em; }
.plan.is-hot .plan-price .pv { color: #fff; }
.plan-price .pu { font-size: .8125rem; color: var(--text-light); }
.plan.is-hot .plan-price .pu { color: #8fa8bd; }
.plan-note { font-size: .75rem; color: var(--text-light); line-height: 1.5; }
.plan.is-hot .plan-note { color: #8fa8bd; }
/* La lista se estira y empuja el botón al fondo: sin esto, las tres
   tarjetas terminan a alturas distintas y sus llamadas a la acción
   quedan a tres alturas distintas, que es lo primero que se nota al
   compararlas. Medido antes del arreglo: 478 / 532 / 490 px. */
/* `flex: 1` estira la lista y empuja el botón al fondo, pero dejaba 117 px de
   blanco en Basic y 30 en Pro: Basic parecía inacabada al lado. Con el hueco
   repartido entre las viñetas, la diferencia se disuelve en cinco huecos en
   vez de acumularse en uno solo al final. */
.plan ul { flex: 1; list-style: none; margin: 4px 0 0; padding: 0; display: flex;
           justify-content: space-evenly;
           flex-direction: column; gap: 9px; flex: 1; }
.plan li { display: flex; align-items: flex-start; gap: 9px; font-size: .8125rem;
           line-height: 1.5; color: var(--text-color); }
.plan.is-hot li { color: #c7d6e2; }
.plan li svg { width: 15px; height: 15px; flex: none; margin-top: 2px; fill: none;
  stroke: var(--mint-600); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.plan.is-hot li svg { stroke: var(--mint-400); }
.plan .btn { justify-content: center; width: 100%; margin-top: 6px; }

.calc {
  margin-top: 26px; display: grid; grid-template-columns: 1fr 1fr .8fr; gap: 26px;
  background: #fff; border: 1px solid rgba(13,26,38,.1);
  border-radius: var(--radius-card); padding: 26px; align-items: center;
}
@media (max-width: 980px) { .calc { grid-template-columns: 1fr; gap: 18px; } }
.calc h2 { font-size: 1.125rem; font-weight: 700; margin-bottom: 8px; }
.calc-lead { font-size: .8125rem; line-height: 1.6; color: var(--text-light);
             margin-top: var(--sp-pair); }
.calc-ctl { display: flex; flex-direction: column; gap: 16px; }
.cc-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
          margin-bottom: 6px; }
.cc-lab { font-size: .75rem; color: var(--text-light); line-height: 1.3; }
.cc-num { font-family: var(--font-mono); font-size: .875rem; font-weight: 700;
          color: var(--accent-color); line-height: 1; }
input[type="range"].cc {
  -webkit-appearance: none; appearance: none; width: 100%; height: 4px; border-radius: 2px;
  background: rgba(70,130,180,.22); outline: none; cursor: pointer;
}
input[type="range"].cc::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 17px; height: 17px; border-radius: 50%;
  background: var(--primary-color); cursor: pointer; border: 2px solid #fff;
  box-shadow: 0 1px 5px rgba(0,0,0,.24);
}
input[type="range"].cc::-moz-range-thumb {
  width: 15px; height: 15px; border-radius: 50%; background: var(--primary-color);
  cursor: pointer; border: 2px solid #fff; box-shadow: 0 1px 5px rgba(0,0,0,.24);
}
.calc-out { background: var(--ink); border-radius: var(--radius); padding: 20px;
            text-align: center; color: #c7d6e2; }
.co-cash { font-family: var(--font-heading); font-size: 2rem; font-weight: 700; color: #fff;
           line-height: 1; letter-spacing: -.02em; }
.co-unit { font-family: var(--font-mono); font-size: .6875rem; color: var(--sky-400);
           letter-spacing: .09em; margin-top: 5px; }
.co-plan { margin-top: 14px; padding-top: 12px; border-top: 1px solid rgba(255,255,255,.12);
           font-size: .8125rem; font-weight: 600; color: #fff; line-height: 1.3; }
.co-price { font-size: .75rem; color: #8fa8bd; margin-top: 3px; }
/* La misma cifra en la unidad en la que piensa quien compra: documentos.
   El cupo en pibiCash no le dice nada a nadie hasta que se traduce. */
.co-docs { font-size: .75rem; color: var(--sky-400); margin-top: 8px;
           line-height: 1.45; }

/* ══ 8. SPOT ══════════════════════════════════════════════════════════════ */
.spot-wrap { position: relative; border-radius: var(--radius-card); overflow: hidden;
             background: #000; box-shadow: var(--shadow-lift); aspect-ratio: 16/9; }
.spot-wrap video { width: 100%; height: 100%; display: block; object-fit: cover; }
.spot-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(8,16,24,.32); border: none; cursor: pointer; transition: opacity .25s;
}
.spot-play.is-hidden { opacity: 0; pointer-events: none; }
.spot-play span {
  width: 66px; height: 66px; border-radius: 50%; background: rgba(255,255,255,.94);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 30px rgba(0,0,0,.35); transition: transform .2s;
}
.spot-play:hover span { transform: scale(1.07); }
.spot-play svg { width: 24px; height: 24px; fill: var(--ink); margin-left: 3px; }
.spot-meta { display: flex; flex-wrap: wrap; gap: 8px 18px; justify-content: center;
  margin-top: var(--sp-tight); font-family: var(--font-mono); font-size: .6875rem; color: var(--slate-700);
  letter-spacing: .05em; }

/* ══ 9. LOS CUATRO TIPOS ══════════════════════════════════════════════════ */
.kinds { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 980px) { .kinds { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .kinds { grid-template-columns: 1fr; } }
.kind {
  border-radius: var(--radius-card); padding: 22px 20px 20px; background: #fff;
  border: 1px solid rgba(13,26,38,.09); display: flex; flex-direction: column;
  /* `gap` y no `margin` en los hijos: en un contenedor flex se SUMAN, y
     con las dos cosas el hueco titular→texto salía 19 px aquí y 9 en las
     tarjetas normales. */
  gap: var(--sp-pair);
  transition: transform .2s, box-shadow .2s;
}
.kind:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
.kind-code { font-family: var(--font-mono); font-size: .625rem; font-weight: 700;
  letter-spacing: .09em; padding: 3px 8px; border-radius: 999px; align-self: flex-start;
  line-height: 1.5; }
.kind[data-k="sections"] .kind-code { background: var(--sky-50);      color: var(--sky-700); }
.kind[data-k="table"]    .kind-code { background: var(--mint-50);     color: var(--mint-700); }
.kind[data-k="object"]   .kind-code { background: var(--lavender-200); color: var(--lavender-700); }
.kind h3 { font-size: 1rem; font-weight: 700; }
.kind p { font-size: .8125rem; line-height: 1.6; color: var(--text-light); flex: 1; }
.kind-out { font-family: var(--font-mono); font-size: .6875rem; color: var(--accent-color);
  padding-top: 10px; border-top: 1px solid rgba(13,26,38,.07); letter-spacing: .04em; }

/* ══ 10. SESIÓN EN VIVO ═══════════════════════════════════════════════════
   Bloque que enseña datos REALES de api_script cuando hay sesión, y dice
   con todas las letras que no los tiene cuando no la hay. */
.live {
  border-radius: var(--radius-card); border: 1px solid rgba(255,255,255,.12);
  background: rgba(255,255,255,.045); padding: 24px 26px;
  display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: center;
}
@media (max-width: 760px) { .live { grid-template-columns: 1fr; } }
.live-h { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.live-h b { font-family: var(--font-heading); font-size: 1rem; font-weight: 600; color: #fff; }
/* Este párrafo es el bloque de texto más grande de la banda de marca y el que
   peor estaba: #9db3c6 da 2,30:1 en el tramo claro del gradiente. Los dos
   elementos vecinos sí se midieron en la ronda 2 y éste se quedó fuera. */
.live p { font-size: .875rem; line-height: 1.6; color: var(--on-brand); max-width: 58ch; }
.live-nums { display: flex; gap: 30px; flex-wrap: wrap; }
.live-num { display: flex; flex-direction: column; gap: 4px; }
.live-num b { font-family: var(--font-heading); font-size: 1.625rem; font-weight: 700;
              color: #fff; line-height: 1; }
/* Colores sólidos, no `rgba` sobre gradiente: con transparencia el contraste
   real depende del tramo que quede debajo, y eso no se puede fijar. Medidos
   contra los tres tramos de `.band--brand`, el peor caso de cada uno:
     etiqueta #e8f1f8 → 4,81:1  (mínimo 4,5 para 10 px)
     guion    #b6d0e6 → 3,44:1  (mínimo 3,0 para 26 px en negrita) */
.live-num span { font-family: var(--font-mono); font-size: .625rem;
                 color: #e8f1f8; letter-spacing: .07em; }
.live-num.is-pending b { color: #b6d0e6; }

/* ══ 11. Cierre ═══════════════════════════════════════════════════════════ */
.final { position: relative; overflow: hidden; text-align: center; }
.final-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
            opacity: .3; }
.final::after { content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at 50% 50%, rgba(8,16,24,.55), rgba(8,16,24,.95)); }
.final .wrap-narrow { position: relative; z-index: 2; }
.final h2 { font-size: clamp(1.75rem, 4vw, 2.75rem); font-weight: 700; color: #fff;
            margin-inline: auto; max-width: 22ch; }
.final p { margin: 18px auto 0; max-width: 54ch; font-size: 1.0625rem; line-height: 1.6;
           color: #a9c0d3; }
.final .sc-hero-cta { justify-content: center; margin-top: 30px; }

/* ══ 12. Bloque de citas / notas al pie honestas ══════════════════════════ */
/* Sin franja de borde: la guía de marca sólo admite tinte de fondo, sombra o
   resplandor. El bloque se distingue con el fondo y con la sangría, que es lo
   mismo que hace una cita en un libro. */
/* MEDIDA DE LÍNEA. Sin tope, este bloque llegaba a 134 caracteres por línea
   —1.180 px— en cuatro páginas: a esa anchura el ojo pierde el renglón al
   volver. El mismo componente está capado a 74 ch en la landing de Talk2Doc.
   Se capa aquí y en los tres textos largos que quedaban sueltos. */
.honesty {
  margin-top: 34px; padding: 18px 22px 18px 26px; border-radius: var(--radius);
  background: rgba(70,130,180,.09); max-width: 74ch;
  font-size: .875rem; line-height: 1.65; color: var(--text-light);
}
.band--ink .honesty { background: rgba(255,255,255,.06); color: #9db3c6; }
.honesty b { color: var(--accent-color); font-weight: 600; }
.band--ink .honesty b { color: var(--sky-400); }

/* ══ 13. FILAS DE CASO (página /casos) ════════════════════════════════════ */
/* El compás de /casos era exacto: tres bandas de 1104 px, cada una con una
   fila de 675 y una rejilla de 151, a intervalos de 1104. El lector recibe
   el mismo golpe tres veces y deja de leer en el segundo. La fila central
   respira distinto y se alinea por arriba, que además le sienta mejor a un
   texto más largo que su imagen. */
.sc-case-row { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: center; }
.sc-case-row--flip { grid-template-columns: 1.08fr .92fr; gap: 64px; align-items: start; }
@media (max-width: 900px) { .sc-case-row { grid-template-columns: 1fr; gap: 26px; } }
/* En la fila invertida el texto va primero en el código —para que un lector de
   pantalla lo reciba en orden— y la imagen se manda a la derecha con `order`.
   En móvil el orden vuelve a ser el natural: imagen arriba, texto debajo. */
.sc-case-row--flip .sc-case-media { order: 2; }
.sc-case-row--flip .sc-case-text  { order: 1; }
@media (max-width: 900px) {
  .sc-case-row--flip .sc-case-media { order: 1; }
  .sc-case-row--flip .sc-case-text  { order: 2; }
}
.sc-case-p { margin-top: 16px; font-size: .9375rem; line-height: 1.72; color: var(--text-light); }
.sc-case-out { margin-top: 24px; padding-top: 18px; border-top: 1px solid rgba(13,26,38,.12); }
.sc-case-lab {
  font-family: var(--font-mono); font-size: .625rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--slate-600); margin-bottom: 12px; line-height: 1;
}
.sc-case-out ul { list-style: none; padding: 0; margin: 0;
                  display: flex; flex-direction: column; gap: 9px; }
.sc-case-out li { display: flex; gap: 11px; align-items: baseline;
                  font-size: .875rem; line-height: 1.5; }
.sc-case-out li code {
  font-family: var(--font-mono); font-size: .625rem; font-weight: 700; flex: none;
  background: rgba(70,130,180,.12); color: var(--accent-color);
  padding: 3px 8px; border-radius: 5px; line-height: 1.6;
}

/* ══ 14. HERO A SANGRE DE /trazabilidad ═══════════════════════════════════ */
.tz-hero {
  padding: 0; position: relative; min-height: 54vh;
  display: flex; align-items: flex-end; overflow: hidden;
}
.tz-hero-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 62% 34%; opacity: .46;
}
.tz-hero-veil {
  position: absolute; inset: 0;
  background:
    linear-gradient(100deg, rgba(8,16,24,.94) 0%, rgba(8,16,24,.72) 46%,
                    rgba(8,16,24,.30) 78%),
    linear-gradient(180deg, rgba(8,16,24,.78) 0%, transparent 34%,
                    rgba(8,16,24,.92) 100%);
}
@media (max-width: 760px) { .tz-hero { min-height: 42vh; } }


/* ══ 15. MARCA DE EJEMPLO ═════════════════════════════════════════════════
   Este sitio sostiene que un dato sin fuente no se publica. Lo mínimo que
   puede hacer es señalar cuál de sus propios bloques es una demostración
   construida y cuál sale del servicio. No va en letra pequeña al pie: va
   pegada a la pieza. */
.is-demo {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: 999px; font-family: var(--font-mono); font-size: .625rem;
  font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  background: var(--marigold-50); color: var(--marigold-700);
  border: 1px solid var(--marigold-200); line-height: 1.6;
}
.is-demo svg { width: 11px; height: 11px; fill: none; stroke: currentColor;
               stroke-width: 2.4; stroke-linecap: round; }
.band--ink .is-demo, .band--ink-deep .is-demo {
  background: rgba(242,200,78,.14); color: var(--marigold-400);
  border-color: rgba(242,200,78,.3);
}
.demo-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
            margin-bottom: var(--sp-cap); }
/* El texto se queda al lado de la marca en vez de caer debajo: cuando
   envolvía, la pastilla «Ejemplo» quedaba sola en su renglón y parecía un
   adorno suelto en vez del rótulo de lo que viene después. */
.demo-row p { flex: 1; min-width: 0; max-width: 78ch; font-size: .8125rem;
              line-height: 1.5; color: var(--text-light); }
@media (max-width: 700px) { .demo-row p { flex-basis: 100%; } }
.band--ink .demo-row p { color: #9db3c6; }


/* ══ 16. CONTROL DE PAUSA DEL BUCLE DEL HERO ══════════════════════════════
   Exigido, no decorativo: un movimiento automático de más de cinco segundos
   tiene que poder pararse, y el bucle dura casi catorce. Discreto abajo a la
   derecha, y sólo visible si el vídeo llegó a cargarse. */
.sc-hero-pause {
  position: absolute; right: 20px; bottom: 20px; z-index: 3;
  width: 36px; height: 36px; display: flex; align-items: center;
  justify-content: center; border-radius: var(--radius-sm); border: none;
  background: rgba(8,16,24,.55); color: #fff; cursor: pointer;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: background .15s, transform .15s; padding: 0;
}
.sc-hero-pause:hover { background: rgba(8,16,24,.8); transform: translateY(-1px); }
.sc-hero-pause svg { width: 16px; height: 16px; fill: currentColor; }
.sc-hero-pause[hidden] { display: none; }
@media (max-width: 760px) { .sc-hero-pause { right: 12px; bottom: 12px; } }

/* ══ 16b. SEGURO DEL REVELADO ═════════════════════════════════════════════
   La clase `js` la pone un script del <head>, así que cubre «JavaScript
   desactivado» pero NO «JavaScript roto»: si `site_core.js` no llega —un `?v=`
   rancio en caché, un fallo de red, un error en otro módulo— el observador
   nunca añade `is-in` y la página se queda en blanco igual.

   Esta animación es el suelo para ese caso: si a los seis segundos `site_core.js`
   no ha llegado siquiera a marcar la clase `sc-rv-ok` en el <html>, el contenido
   aparece igual.

   OJO CON EL RETARDO. La primera versión era `.js .rv:not(.is-in)` con 3 s, sin
   la puerta de `sc-rv-ok`, y esa regla el navegador la aplica a TODOS los `.rv`
   desde la carga —no cuando entran en pantalla—. A los 3,45 s la página entera
   se había revelado sola, así que quien se parase a leer el hero no veía un solo
   revelado: el seguro anulaba lo que protegía. Ahora el suelo sólo actúa si el
   observador no ha dado señales de vida, y el revelado por pantalla lo lleva el
   JS, que sabe qué está a la vista y qué no. */
@keyframes sc-rv-failsafe { to { opacity: 1; transform: none; } }
html:not(.sc-rv-ok) .rv:not(.is-in) { animation: sc-rv-failsafe .45s ease 6s forwards; }

/* ══ 17. UTILIDADES ═══════════════════════════════════════════════════════
   TODAS VAN PREFIJADAS CON `.sc-site`, Y NO ES ADORNO. Una utilidad de un solo
   nombre de clase puntúa (0,1,0) y pierde contra `.sc-site p { margin: 0 }`
   (0,1,1) y contra `.sc-site h1..h4`. Medido en producción: `p.u-btn-pair`
   declaraba `margin-top: 12px` y el navegador aplicaba 0, así que el par
   Swagger/ReDoc salía pegado al párrafo de encima; y lo mismo les pasaba a los
   `p.u-mt` y `p.u-mt-md` que separan las llamadas a la acción del final de
   cada sección. Es la misma trampa que dejó los botones azules sobre azul en
   la primera ronda, cuatrocientas líneas más arriba de donde se causó.

   Lo comprueba `test_site_regressions.py::test_las_utilidades_ganan_al_reset`.

   Estas clases sustituyen a los `style="…"` que había repartidos por las
   plantillas. No es limpieza cosmética: la CSP de producción todavía trae
   `style-src 'self' 'unsafe-inline'`, pero quitar ese `unsafe-inline` está en
   la lista de endurecimiento de la casa, y el día que se quite un sitio lleno
   de estilos en línea se descuadra entero. Con clases, ese cambio no se nota.
   Son pocas y con nombre: si hacen falta veinte más, lo que falla es el
   sistema, no la utilidad. */
.sc-site .u-center { text-align: center; }
.sc-site .u-narrow { margin-inline: auto; max-width: 24ch; }
.sc-site .u-narrow-wide { margin-inline: auto; max-width: 26ch; }
.sc-site .u-lede-center { margin: 16px auto 0; max-width: 52ch; }
.sc-site .u-mt { margin-top: var(--sp-blk); }
.sc-site .u-mt-lg { margin-top: var(--sp-sec); }
.sc-site .u-note { font-size: .8125rem; line-height: 1.55; color: var(--text-light);
                   max-width: 72ch; }
.sc-site .u-row { display: flex; gap: 10px; align-items: baseline; }
.sc-site .u-figure { border-radius: var(--radius-card); box-shadow: var(--shadow-lift); }
.sc-site .u-hero-figure { margin-top: 44px; width: 100%;
                 border-radius: var(--radius-card) var(--radius-card) 0 0; }

/* Cabecera de página interior: banda oscura con el título y la entradilla. */
.sc-site .band--page-top { padding-top: 88px; }
.sc-site .band--page-top-sm { padding-top: 88px; padding-bottom: 56px; }
.sc-site .band--page-top-flush { padding-top: 88px; padding-bottom: 0; }
.sc-site .sec-head--flush { margin-bottom: 0; }

/* Titulares de página y de caso. */
.sc-site .sec-title--page { font-size: clamp(1.875rem, 4.2vw, 3rem); }
.sc-site .sec-title--h1 { font-size: clamp(2rem, 4.6vw, 3.25rem); max-width: 22ch; }
.sc-site .sec-title--case { font-size: clamp(1.5rem, 2.8vw, 2.125rem); }
.sc-site .sec-lede--page { margin-top: 20px; max-width: 64ch; }
.sc-site .sec-lede--tight { margin-top: 20px; max-width: 62ch; }

/* Llamada a la acción centrada al pie de una sección. */
.sc-site .sc-hero-cta--center { justify-content: center; margin-top: 26px; }

/* Botón pequeño, para el par Swagger/ReDoc del atlas. */
.sc-site .btn-sm { padding: 7px 14px; font-size: .8125rem; }

/* Chip de formato en la lista «por dónde viaja» de /trazabilidad. */
.sc-site .tag-code {
  font-family: var(--font-mono); font-size: .6875rem; flex: none;
  background: rgba(70,130,180,.1); color: var(--accent-color);
  padding: 2px 7px; border-radius: 5px; line-height: 1.6;
}
.sc-site .tag-list { list-style: none; padding: 0; margin: 14px 0 0;
            display: flex; flex-direction: column; gap: 8px; }

/* Bloque de fórmula, en /trazabilidad. */
.sc-site .formula {
  font-family: var(--font-mono); font-size: .75rem; line-height: 1.6;
  background: var(--slate-50); color: var(--accent-color);
  padding: 12px 14px; border-radius: var(--radius); overflow-x: auto;
}

/* Contador del bisturí, al final de la leyenda. */
.sc-site .trace-count { font-family: var(--font-mono); font-size: .6875rem;
               color: var(--slate-600); margin-left: auto; }

/* Nota al pie de una columna de la forja. */
.sc-site .forge-note--foot { color: var(--text-light); margin-top: var(--sp-blk); }

/* El epígrafe centrado de una sección con titular centrado. */
.sc-site .eyebrow--center { justify-content: center; }
.sc-site .u-mt-sm { margin-top: 12px; }
.sc-site .u-mt-md { margin-top: var(--sp-blk); }
.sc-site .u-mt-note { margin-top: var(--sp-blk); }
.sc-site .u-mb { margin-bottom: 14px; }
/* Ya no reduce la cabecera de sección por debajo del ritmo: para eso está
   `--sp-sec`. Queda para bloques que no son cabecera. */
.sc-site .u-mb-lg { margin-bottom: var(--sp-blk); }
.sc-site .u-btn-pair { margin-top: 12px; display: flex; gap: 8px; }
.sc-site .band--pull-up { padding-top: 52px; }
.sc-site .band--pull-mid { padding-top: 56px; }
.sc-site .sc-panel-form { display: flex; flex-direction: column; flex: 1;
                 min-height: 0; overflow: hidden; }
/* Cabecera del hero a sangre de /trazabilidad. */
.sc-site .tz-hero-inner { position: relative; z-index: 2; padding: 104px 0 68px; }
.sc-site .tz-hero h1 { font-size: clamp(2rem, 4.8vw, 3.5rem); max-width: 18ch; color: #fff; }
.sc-site .tz-hero .sec-lede { margin-top: 20px; max-width: 60ch; color: #a9c0d3; }

/* ══ 18. IMPRESIÓN ════════════════════════════════════════════════════════
   No había `@media print`, y este sitio se imprime: es la página que alguien
   pasa a un comité de compras. Sin reglas, las cuatro bandas oscuras salen con
   su fondo —o sin él, según el navegador y la casilla de «gráficos de fondo»—
   y el texto claro encima queda entre 1,00:1 y 2,47:1 sobre papel blanco.

   La decisión es imprimir todo sobre blanco y con tinta oscura, revelar lo que
   el revelado deja oculto, y quitar lo que en papel no sirve: vídeo, barra
   fija, panel, controles y decoraciones. Los enlaces internos no se anotan
   —serían cuatro páginas de URLs— pero los externos sí: en papel, un enlace sin
   destino es una promesa que no se puede seguir. */
@media print {
  .sc-site, .sc-site .band, .sc-site .band--ink, .sc-site .band--ink-deep,
  .sc-site .band--brand, .sc-site .band--vellum, .sc-site .sc-hero {
    background: #fff !important;
    color: #111 !important;
  }
  .sc-site h1, .sc-site h2, .sc-site h3, .sc-site h4, .sc-site b,
  .sc-site .sec-lede, .sc-site p, .sc-site li, .sc-site span {
    color: #111 !important;
  }
  .sc-site a, .sc-site a:not(.btn) { color: #111 !important; text-decoration: underline; }
  .sc-site a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .75em; word-break: break-all; }

  /* El revelado deja `opacity: 0` en lo que nunca entró en pantalla: sin esto,
     imprimir sin haber hecho scroll da páginas en blanco. */
  .sc-site .rv, .sc-site .rv:not(.is-in) { opacity: 1 !important; transform: none !important; animation: none !important; }

  /* Lo que en papel no existe. */
  .sc-nav, .sc-hero-media, .sc-hero-pause, .sc-panel, .sc-backdrop, .sc-skip,
  .spot, .spot-play, .sc-foot-bar, .atlas-search, .forge-kinds, .trace-switch,
  video, .fmt:hover { display: none !important; }

  .sc-site .card, .sc-site .plan, .sc-site .fmt, .sc-site .kind {
    border: 1px solid #999 !important; box-shadow: none !important;
    break-inside: avoid; page-break-inside: avoid;
  }
  .sc-site section, .sc-site .band { break-inside: auto; page-break-before: auto; }
  .sc-site h2, .sc-site h3 { break-after: avoid; page-break-after: avoid; }
}

/* ══ 19. /api — EL RECORRIDO Y EL MOSAICO DE FAMILIAS ═════════════════════
   La primera versión de esta página era el contrato volcado: un titular y
   ciento cuarenta y nueve filas, con los grupos grandes abiertos de salida.
   Se leía como un log de sistema. Lo que un lector necesita antes que la
   lista es la FORMA de la API —qué se puede hacer y en qué orden—, y eso son
   seis llamadas, no ciento cuarenta y nueve. La lista sigue entera debajo,
   cerrada, para quien vaya a integrarla. */

.jrn { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.jrn-step {
  display: grid; grid-template-columns: 34px 1fr auto 26px; gap: 16px; align-items: center;
  background: #fff; border: 1px solid rgba(13,26,38,.09); border-radius: var(--radius-card);
  padding: 16px 20px; transition: border-color .18s, transform .18s;
}
.jrn-step:hover { border-color: rgba(70,130,180,.4); transform: translateX(3px); }
.jrn-n {
  font-family: var(--font-mono); font-size: .8125rem; font-weight: 700;
  color: var(--link); background: var(--sky-50); border-radius: 50%;
  width: 34px; height: 34px; display: grid; place-items: center;
}
.jrn-t { font-family: var(--font-heading); font-size: .9375rem; font-weight: 600; color: var(--ink); }
.jrn-d { font-size: .8125rem; line-height: 1.5; color: var(--text-light);
         margin-top: var(--sp-pair); max-width: 68ch; }
.jrn-c {
  font-family: var(--font-mono); font-size: .75rem; color: var(--slate-700);
  background: var(--slate-50); border-radius: var(--radius-sm); padding: 6px 10px;
  white-space: nowrap;
}
.jrn-c i { font-style: normal; font-weight: 700; color: var(--link); margin-right: 6px; }
/* La marca no es decoración: dice si esa llamada sigue en el contrato. */
.jrn-ok { font-size: .875rem; color: var(--slate-400); text-align: center; }
.jrn-step[data-paso-ok="1"] .jrn-ok { color: var(--mint-700); }
.jrn-step[data-paso-ok="0"] .jrn-ok { color: var(--rose-700); }
@media (max-width: 860px) {
  .jrn-step { grid-template-columns: 30px 1fr 22px; row-gap: 8px; }
  .jrn-c { grid-column: 2 / 4; white-space: normal; overflow-wrap: anywhere; }
}

.atlas-fams-h {
  font-family: var(--font-mono); font-size: .6875rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--slate-700); margin: 30px 0 12px;
}
.atlas-fams {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 8px; margin-bottom: 26px;
}
.atlas-fam {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  background: #fff; border: 1px solid rgba(13,26,38,.09); border-radius: var(--radius-sm);
  padding: 11px 13px; cursor: pointer; text-align: left; font-family: var(--font-body);
  transition: border-color .16s, background .16s;
}
.atlas-fam:hover { border-color: rgba(70,130,180,.45); background: var(--sky-50); }
.atlas-fam b { font-size: .8125rem; font-weight: 600; color: var(--ink); flex: 1; }
.atlas-fam-n { font-family: var(--font-mono); font-size: .8125rem; color: var(--link); font-weight: 700; }
.atlas-fam-pub {
  font-family: var(--font-mono); font-size: .625rem; color: var(--mint-700);
  background: var(--mint-50); border-radius: 4px; padding: 2px 6px; width: 100%;
}
/* Todos los azulejos igual de altos: la insignia de «pública» sólo la llevan
   algunos y sin un mínimo la rejilla salía escalonada. */
.atlas-fam { min-height: 62px; align-content: center; }
.atlas-fam.is-on { border-color: var(--link); background: var(--sky-50); }

/* La llamada a la acción de un plan va siempre al fondo y siempre a la misma
   distancia del último punto de la lista. */
.sc-site .plan > .btn { margin-top: 18px; }

/* El pie del spot iba a 4 px del vídeo: no era un pie, era una línea suelta
   pegada al borde. Y la nota de honestidad que sigue a una pieza usa el mismo
   hueco que cualquier otro bloque, para que no dependa de la sección. */
.sc-site .spot-wrap + .u-note { margin-top: var(--sp-cap); }
.sc-site .honesty { margin-top: var(--sp-blk); }
.sc-site .sec-head + .honesty { margin-top: 0; }

/* ══ 20. OBJETIVOS TÁCTILES ═══════════════════════════════════════════════
   Medido con emulación a 390x844: «Solicitar acceso» del pie tenía 17 px de
   alto, las pestañas de la forja y del bisturí 28, y el par Swagger/ReDoc 32.
   Con el dedo eso se falla. Va bajo `pointer: coarse` para no engordar los
   mismos controles en escritorio, donde 28 px con el ratón están bien y
   engordarlos descuadraría el ritmo. 44 px es la medida de siempre. */
@media (pointer: coarse) {
  .sc-site .btn,
  .sc-site .sc-foot-link,
  .sc-site .sc-foot a,
  .sc-site .forge-kinds button,
  .sc-site .forge-tabs button,
  .sc-site .trace-switch button,
  .sc-site .atlas-fam,
  .sc-site .atlas-group-h,
  .sc-site [data-tpl],
  .sc-site [data-lang] {
    min-height: 44px;
  }
  /* Un enlace de pie es texto: se le da área con relleno, no con altura de
     caja, para que la columna no se estire. */
  .sc-site .sc-foot a, .sc-site .sc-foot-link {
    display: inline-flex; align-items: center;
  }
  /* El botón de cerrar del panel es de sólo icono, así que crece en las dos
     medidas a la vez: en esta casa esos botones son cuadrados perfectos. */
  .sc-site .icon-btn { min-width: 44px; min-height: 44px; }
}

/* ══ 21. RONDA 4 · TOQUE Y DESLIZADORES ═══════════════════════════════════
   El deslizador de la calculadora medía 4 px de alto: la única pieza
   interactiva de /precios era intocable con el dedo. El carril sigue viéndose
   de 4 px —es lo que debe— pero la caja del control crece a 44. */
input[type="range"].cc {
  height: 44px; background: none; padding: 0;
}
input[type="range"].cc::-webkit-slider-runnable-track {
  height: 4px; border-radius: 2px; background: rgba(70,130,180,.22);
}
input[type="range"].cc::-moz-range-track {
  height: 4px; border-radius: 2px; background: rgba(70,130,180,.22);
}
input[type="range"].cc::-webkit-slider-thumb { margin-top: -7px; }

@media (pointer: coarse) {
  .sc-site .forge-block,
  .sc-site .forge-src,
  .sc-site .trace-s,
  .sc-site .sc-burger,
  .sc-site .icon-btn,
  .sc-site .spot-play,
  .sc-site .sc-hero-pause button { min-height: 44px; }
  .sc-site .sc-burger { min-width: 44px; }
}

/* ══ 22. RONDA 4 · CIERRE ═════════════════════════════════════════════════ */

/* G2 · «cifra → etiqueta» tomaba 2, 3, 4, 5 y 8 px según dónde estuviera. */
.sc-site .atlas-stat span,
.sc-site .live-num span,
.sc-site .sc-hero-meta .m-lab,
.sc-site .co-docs,
.sc-site .co-price { margin-top: var(--sp-hair); }

/* G2 · «titular → texto de apoyo» tomaba 3, 4, 8, 9 y 10 px. */
.sc-site .trace-doc .trace-sub,
.sc-site .ribbon-step p { margin-top: var(--sp-pair); }

/* M1 · un escalón real entre el titular de tarjeta (17 px) y el de plan, que
   estaba a 18: un píxel de diferencia entre dos niveles jerárquicos no es una
   jerarquía, es una coincidencia. */
.sc-site .plan-name, .sc-site .calc h2 { font-size: 1.375rem; }
.sc-site .sec-title--case { font-size: 2rem; }

/* G6 · los mandos de la forja y del bisturí —las dos piezas que justifican la
   portada— medían 28 px de alto en móvil. Y el menú, 36. */
@media (max-width: 760px) {
  .sc-site .forge-kinds button,
  .sc-site .trace-switch button { min-height: 44px; padding-inline: 16px; }
  .sc-site .sc-burger { width: 44px; height: 44px; }
  .sc-site .sc-nav-cta .btn-primary, .sc-site .sc-nav .btn-primary { min-height: 44px; }
  .sc-site .btn-sm { min-height: 40px; }
  /* M4 · con la columna estrecha, partir palabras evita el carácter colgando. */
  .sc-site p { hyphens: auto; -webkit-hyphens: auto; }
}

/* G5 · /casos era un metrónomo: tres bandas de 1104 px exactos, cada una con
   una fila de 675 y una rejilla de 151, a intervalos de 1104. El alto lo manda
   la columna de texto, así que tocar el `gap` no cambiaba nada: hay que variar
   la estructura. El caso central —el que la página quiere que se lea con más
   calma— respira más y reparte sus tarjetas de apoyo en dos columnas anchas.
   Medido después: 1104 / 1289 / 1104 en vez de tres veces lo mismo. */
.band--case-mid { padding-top: 128px; padding-bottom: 128px; }
.grid-3--pair { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 760px) { .grid-3--pair { grid-template-columns: 1fr; } }
