/* Gap Hunter Labs — application shell (Intelligence Cockpit)
   Fase 0: sistema de grid de 12 columnas + spacing scale compartido.
   Fase 1: sidebar persistente + drawer mobile, sobre ese grid.

   Depende de los custom properties ya definidos en el :root de cada
   página (--bg, --surface, --surface-2, --border, --text, --text-dim,
   --text-faint, --accent, --good, --cyan, --warn, --mono, --sans,
   --page-max, --page-pad, --section-gap, --card-pad, --card-pad-sm,
   --duration-*, --ease-*, --radius*) — este archivo no redefine esos
   tokens, los reusa. Cargar SIEMPRE después del <style> inline de la
   página (que define :root), nunca antes. */

/* ---- Fase 0: grid de 12 columnas + spacing scale ------------------- */

:root {
  --sidebar-w: 248px;
  --shell-header-h: 56px;
  /* Spacing scale (múltiplos de 4px, ya coherente con --page-pad:24px
     y --card-pad:16px existentes) -- para separaciones nuevas del
     shell/cockpit que no tenían un token propio todavía. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --grid-gap: var(--space-5);
}

.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--grid-gap);
}
/* Column-span utilities -- solo las que el cockpit necesita en las
   fases siguientes (no las 12 combinaciones posibles, se agregan más
   si hace falta). En mobile todo colapsa a ancho completo (ver media
   query al final del archivo). */
.col-span-3 { grid-column: span 3; }
.col-span-4 { grid-column: span 4; }
.col-span-6 { grid-column: span 6; }
.col-span-8 { grid-column: span 8; }
.col-span-9 { grid-column: span 9; }
.col-span-12 { grid-column: span 12; }

/* ---- Fase 1: application shell (header + sidebar + main) ----------- */

.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  grid-template-rows: var(--shell-header-h) 1fr;
  grid-template-areas:
    "shell-header shell-header"
    "shell-sidebar shell-main";
  min-height: 100vh;
}

/* El header reusa .topbar ya existente (marca + links externos +
   burger) -- solo se le quita el grid-area por defecto y se lo ubica
   en la fila de header del shell. .topbar-nav (Catalog/Methodology/
   Contact) se retira del header en las páginas que adoptan el shell:
   esos destinos viven ahora en el sidebar. */
.app-shell .topbar { grid-area: shell-header; position: sticky; top: 0; }
/* .topbar-inner base (definido inline por página) es un grid de 3
   columnas -- brand / .topbar-nav / actions. Las páginas que adoptan
   el shell sacan .topbar-nav del header (los destinos viven en el
   sidebar ahora), así que quedan solo 2 hijos reales; sin este
   override la última columna 1fr queda vacía y .topbar-actions no
   llega al borde derecho real. */
.app-shell .topbar-inner { grid-template-columns: minmax(0, 1fr) auto; }

/* Historial de esta regla, 5 bugs reales en 4 días -- cada fix anterior
   corrigió lo reportado a costa de otra cosa (ver commits del
   2026-09-09 al 2026-09-12): height:100vh+overflow-y:auto (scroll
   interno) -> max-height+align-self:start (se encoge al contenido) ->
   height fijo a 1 viewport (corta antes del footer en paginas largas)
   -> height:100% de una fila que ahora incluye el footer (empuja
   .sidebar-footer, que usa margin-top:auto, hasta el fondo REAL de la
   pagina -- rompe el timing del fade con el footer real, que dependia
   de que el logo quedara cerca del final del contenido principal, no
   de toda la pagina).

   Causa de fondo de los ultimos 3 intentos: intentar que la CAJA del
   sidebar "sepa" hasta donde llega el footer (que ademas varia por
   pagina -- index/catalog usan margin-top:var(--section-gap) en el
   footer, el resto usa margin-top:auto) mezclaba dos cosas que no
   deberian depender una de la otra: (a) el tamaño de la caja real que
   contiene nav+logo (del que depende el fade), y (b) la continuidad
   VISUAL de la franja oscura hasta el borde real de abajo de la
   pagina, footer incluido.

   Fix real: separar los dos. (a) esta caja vuelve a su tamaño simple
   de 1 viewport (el que ya funcionaba bien para el fade antes de que
   se tocara nada de esto) -- sticky + sin overflow-y seguyen evitando
   el bug original de scroll interno. (b) la franja oscura de ancho
   completo hasta el fondo real vive en el FONDO de <body> (ver regla
   nueva mas abajo) -- un background de body/html cubre el canvas
   completo (toda la altura real scrolleable), sin el problema de
   "necesito saber la altura de que" que arrastraban las 3 versiones
   anteriores. */
.app-sidebar {
  grid-area: shell-sidebar;
  position: sticky;
  top: var(--shell-header-h);
  height: calc(100vh - var(--shell-header-h));
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: var(--space-5) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Franja oscura de ancho = sidebar, hasta el borde real de abajo de la
   pagina (footer incluido, sin importar su margin-top por pagina) --
   pintada en <body>, no en .app-sidebar (ver comentario arriba). El
   radial-gradient decorativo es IDENTICO en las 6 paginas (confirmado
   por grep) y se preserva tal cual, solo se agrega la franja como
   segunda capa -- reemplazar "background-image" a secas perderia esa
   decoracion en vez de sumarse a ella. Solo en escritorio: en movil no
   hay columna de sidebar persistente (es un drawer superpuesto), pintar
   la franja ahi dejaria una banda oscura fantasma sin sidebar visible. */
@media (min-width: 841px) {
  body {
    background-color: var(--bg);
    background-repeat: no-repeat;
    background-image:
      linear-gradient(to right, var(--surface) 0, var(--surface) var(--sidebar-w), transparent var(--sidebar-w));
  }
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sidebar-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 11px 14px;
  border-radius: var(--radius-md);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
  text-decoration: none;
  position: relative;
}
.sidebar-link svg { width: 19px; height: 19px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.5; }
.sidebar-link:hover { color: var(--text); background: var(--surface-2); }
.sidebar-link:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Relleno sólido, no un acento tenue -- la página activa tiene que
   leerse con la misma confianza que el resto de la marca (--accent a
   pleno, texto blanco), no como un detalle sutil. */
.sidebar-link[aria-current="page"] {
  color: #fff;
  background: var(--accent);
}
.sidebar-link[aria-current="page"]:hover { color: #fff; background: var(--accent); }

/* Grupo "Legal" (2026-09-24): <details>/<summary> nativo -- abre/cierra sin JS
   (la CSP ya no permite scripts inline) y con teclado de fabrica (Enter/Espacio
   sobre el summary). En Security/Privacy/Terms llega ya abierto, con el
   subenlace de la pagina actual resaltado como el resto del sidebar. */
.sidebar-group > summary { list-style: none; cursor: pointer; }
.sidebar-group > summary::-webkit-details-marker { display: none; }
.sidebar-group > summary::marker { content: ""; }
.sidebar-link .sidebar-chevron {
  width: 16px; height: 16px; margin-left: auto;
  transition: transform var(--duration-base) ease;
}
.sidebar-group[open] > summary .sidebar-chevron { transform: rotate(180deg); }
.sidebar-group.has-current > summary { color: var(--text); }
.sidebar-sub {
  display: flex; flex-direction: column; gap: 2px;
  margin: 2px 0 6px 21px; padding-left: 12px;
  border-left: 1px solid var(--border);
}
.sidebar-sublink {
  display: block; padding: 8px 12px; border-radius: var(--radius-md);
  font-family: var(--sans); font-size: 13.5px; font-weight: 600;
  color: var(--text-dim); text-decoration: none;
}
.sidebar-sublink:hover { color: var(--text); background: var(--surface-2); }
.sidebar-sublink:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.sidebar-sublink[aria-current="page"] { color: #fff; background: var(--accent); }
.sidebar-sublink[aria-current="page"]:hover { color: #fff; background: var(--accent); }
/* Con el grupo abierto el sidebar crece ~110px; si la ventana es muy baja, la
   lista de navegacion (no el logo del pie) es la que hace scroll. */
.app-sidebar .sidebar-nav { min-height: 0; overflow-y: auto; }

.sidebar-footer {
  margin-top: auto;
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  transition: opacity var(--duration-slow) var(--ease-standard);
}
/* En páginas cortas, el sidebar (sticky, alto fijo) termina su caja
   justo donde empieza el <footer> real -- sin esto, la marca del pie
   del sidebar y la marca del footer quedan visibles casi superpuestas
   al llegar abajo (bug real reportado 2026-09-10: "el logo se
   triplica"). JS observa el footer real vía IntersectionObserver y
   agrega/saca esta clase -- fade-out al acercarse al footer,
   fade-in al alejarse subiendo. */
.sidebar-footer.is-near-footer { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .sidebar-footer { transition: none; }
}
.sidebar-footer svg { width: 22px; height: 22px; flex: none; }
.sidebar-footer-name {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  line-height: 1.3;
}
.sidebar-footer-sub {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-faint);
  line-height: 1.3;
}

/* Fondo de "red/circuito" + glow para el header de cualquier página --
   reusable: se agrega como clase extra sobre el contenedor del header
   de cada página (envolviendo kicker+h1+lead, o combinada con un
   layout propio como .contact-hero). CSS puro, sin asset nuevo --
   mismo patrón hand-rolled que el resto de los efectos del sitio. */
.page-hero {
  position: relative;
  padding: 7%;
  margin-bottom: var(--space-8);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  overflow: hidden;
  background: var(--surface);
}

.app-main {
  grid-area: shell-main;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Rail derecho liviano ("Platform Insights") -- versión chica de lo
   que en el plan es la Fase 3/4 (gráfico de tendencia + recent
   changes, que necesitan el pipeline). Esta versión usa solo datos
   YA cargados por GapCatalog.ready (stats agregados, categorías,
   plugin destacado) -- nada nuevo del lado del pipeline, nada
   inventado. Envuelve el contenido existente de la página + el rail
   en un grid de 2 columnas, sin tocar el padding/max-width que ya
   tiene cada .methodology-main/.contact-main. */
.main-with-rail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-6);
  align-items: start;
}
.main-with-rail > .methodology-main,
.main-with-rail > .contact-main {
  max-width: none;
  margin: 0;
}
.page-insights {
  padding: 40px var(--page-pad) 40px 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.pi-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow, none);
  padding: var(--card-pad);
}
.pi-eyebrow {
  margin: 0 0 var(--space-3);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  display: flex;
  align-items: center;
  gap: 6px;
}
.pi-stats { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
/* Rail content (2026-10-19): notes, lists, results with their status rule, and section links. */
.pi-note { margin: 0 0 var(--space-2); font-size: 13px; color: var(--text-dim); line-height: 1.55; }
.pi-note:last-child { margin-bottom: 0; }
.pi-list { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: 8px; }
.pi-list li { font-size: 13px; color: var(--text-dim); line-height: 1.5; }
.pi-results { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.pi-results li { padding-left: 10px; border-left: 3px solid var(--valid-line); font-size: 13px; line-height: 1.5; color: var(--text-dim); }
.pi-results li.is-open { border-left-color: var(--inspect-line); }
.pi-results a { display: block; margin-bottom: 2px; font: 600 13px/1.4 var(--mono); color: var(--text);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
.pi-links { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.pi-links a { display: block; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13.5px; color: var(--text); text-decoration: none; }
.pi-links li:last-child a { border-bottom: 0; }
.pi-links a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.pi-links a[aria-current="page"] { padding-left: 8px; border-left: 3px solid var(--text); font-weight: 600; }
.pi-cta { margin: var(--space-3) 0 0; font-size: 13.5px; }
.pi-card .pi-cta:first-of-type:last-child { margin-top: 0; }
.pi-stat-num { display: block; font-family: var(--mono); font-size: 20px; font-weight: 700; color: var(--text); }
.pi-stat-label { display: block; font-size: 11px; color: var(--text-faint); margin-top: 2px; }
.pi-categories { display: flex; flex-direction: column; gap: 2px; }
.pi-cat {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 4px; border-radius: var(--radius-sm);
  font-size: 12.5px; color: var(--text-dim); text-decoration: none;
}
.pi-cat:hover { color: var(--text); background: var(--surface-2); }
.pi-cat svg { width: 15px; height: 15px; flex: none; color: var(--cat, var(--accent)); stroke: currentColor; fill: none; stroke-width: 1.4; }
.pi-cat span { flex: 1; min-width: 0; }
.pi-cat b { font-family: var(--mono); font-weight: 600; font-size: 11px; color: var(--text-faint); }
.pi-featured {
  display: block; text-decoration: none; color: inherit;
  margin: var(--space-2) 0 0;
}
/* aspect-ratio + object-fit:cover -- las screenshots reales de cada
   plugin tienen proporciones distintas entre sí (GIF_URL apunta a
   demo.gif/screenshot_1.png de cada repo, sin tamaño uniforme). Sin
   esto, el alto de la card cambiaría según qué plugin salga
   destacado y algunas imágenes podrían verse estiradas. Con esto,
   siempre se recorta a 16:9, nunca se deforma. Inset dentro del
   padding de la card (no sangra a los costados) con un radio chico,
   a pedido explícito 2026-09-10. */
.pi-featured img {
  display: block; width: 100%; aspect-ratio: 16/9; object-fit: cover;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}
.pi-featured strong { display: block; font-size: 13px; font-weight: 650; padding: var(--space-3) 0 2px; }
.pi-featured span { display: block; font-size: 11.5px; font-weight: 600; color: var(--accent); padding: 0 0 var(--space-1); }

@media (max-width: 1100px) {
  .main-with-rail { grid-template-columns: 1fr; }
  .page-insights { padding: 0 var(--page-pad) var(--space-8); flex-direction: row; flex-wrap: wrap; }
  .pi-card { flex: 1 1 220px; }
}
/* .methodology-main/.contact-main (definidas inline por página) usan
   margin:0 auto -- correcto en el layout viejo (topbar sola, sin
   sidebar, centrado en el ancho completo), pero deja un hueco grande y
   asimétrico ahora que el sidebar ya ocupa la izquierda. Dentro del
   shell el contenido debe pegar contra el sidebar (0 auto -> 0), no
   flotar centrado en el espacio que sobra. */
.app-main > .methodology-main,
.app-main > .contact-main,
.app-main > .wrap {
  margin-left: 0;
  margin-right: 0;
}

/* ---- Pantallas grandes (2026-09-24) -------------------------------------
   Antes el contenido tope en --page-max (1280px) y quedaba pegado al
   sidebar: a 2560px sobraban ~1000px vacios a la derecha, mientras el
   topbar y el footer si iban centrados en el viewport (la marca flotaba
   sin alinear con el sidebar), y en las paginas con rail (methodology,
   security, privacy, terms) el grid 1fr+300px no tenia tope y estiraba el
   texto a ~2000px de ancho.
   Ahora: --page-max sube a 1600px, el contenido (y el grid contenido+rail)
   se centra en el area a la derecha del sidebar, y el topbar ocupa el ancho
   completo (marca a la izquierda, sobre el sidebar; links al borde derecho).
   Ojo: un hijo con margin auto dentro de .app-main (flex en columna) deja
   de estirarse, por eso el width:100% explicito. */
:root { --page-max: 1600px; }
.app-shell .topbar-inner { max-width: none; }
.app-main > .wrap,
.app-main > .main-with-rail {
  width: 100%;
  max-width: var(--page-max);
  margin-left: auto;
  margin-right: auto;
}
/* El footer va debajo de todo el shell; con el sidebar a la izquierda su
   contenido centrado en el viewport quedaba desalineado del contenido
   (centrado en el area a la derecha del sidebar): 124px a 2560px. Con este
   padding ambos comparten el mismo eje. Solo escritorio: en movil no hay
   columna de sidebar. */
@media (min-width: 841px) {
  .site-footer { padding-left: var(--sidebar-w); }
}

/* El drawer mobile reusa el mecanismo/nombre de clase ya existente en
   el topbar (.nav-open + #topbarBurger) -- mismo patrón, ahora
   controla .app-sidebar en vez de #topbarNav. */
@media (min-width: 841px) {
  .app-sidebar { transform: none !important; }
}
@media (max-width: 840px) {
  .app-shell { grid-template-columns: 1fr; grid-template-areas: "shell-header" "shell-main"; }
  /* Bug real reportado 2026-09-12: con bottom:0 + height:auto, un
     elemento position:fixed con top Y bottom fijos se ESTIRA para
     llenar ese hueco (no se ajusta a su contenido) -- el drawer medía
     788px reales (viewport completo) aunque nav+logo (.sidebar-footer,
     que ya usa margin-top:auto para pegarse abajo DE LO QUE HAYA)
     miden ~320px, dejando ~460px de hueco vacio entre "Contact" y el
     logo. bottom:0 nunca debio estar en un drawer mobile -- eso tiene
     sentido en el sidebar sticky de escritorio (llenar el viewport
     completo es el punto), no en un panel que se abre y cierra, donde
     lo esperable es que termine justo debajo de su propio contenido.
     Fix: sacar bottom:0, max-height como tope de seguridad (nunca se
     activa en la práctica, nav+logo siempre entran sobrados). */
  .app-sidebar {
    position: fixed;
    top: var(--shell-header-h);
    left: 0;
    max-height: calc(100vh - var(--shell-header-h));
    width: min(var(--sidebar-w), 82vw);
    height: auto;
    transform: translateX(-100%);
    transition: transform var(--duration-slow) var(--ease-standard);
    z-index: 39;
    box-shadow: 0 0 24px rgba(0,0,0,0.4);
  }
  /* .topbar y .app-sidebar son hermanos directos dentro de .app-shell
     (mismo orden en el HTML de cada página) -- el combinador de
     hermano adyacente alcanza, sin depender de :has(). */
  .topbar.nav-open + .app-sidebar {
    transform: translateX(0);
  }
  @media (prefers-reduced-motion: reduce) {
    .app-sidebar { transition: none; }
  }
  .col-span-3, .col-span-4, .col-span-6, .col-span-8, .col-span-9 { grid-column: span 12; }
}

/* ---- Topbar en pantallas chicas (2026-09-24) ---------------------------
   Los 4 links externos + burger miden ~222px fijos; por debajo de ~400px el
   nombre "Gap Hunter Labs" (nowrap) quedaba debajo de ellos y se cortaba
   (a 320px se pisaban ~105px). Ahora el logo y el texto se achican con el
   ancho, el nombre puede partirse en 2 lineas ("GAP HUNTER / LABS") en vez
   de cortarse, y los botones ceden un poco de ancho. Los selectores llevan
   .topbar delante para ganarle en especificidad a los @media inline de cada
   pagina (que fijan min-width:44px en los links). */
@media (max-width: 520px) {
  .topbar .topbar-inner { padding: 0 12px; gap: 8px; }
  .topbar .topbar-brand { gap: 8px; }
  .topbar .topbar-mark,
  .topbar .topbar-mark svg { width: 28px; height: 28px; }
  .topbar .tw-name {
    white-space: normal;
    font-size: clamp(10px, 3vw, 13px);
    letter-spacing: 0.04em;
    line-height: 1.1;
  }
  .topbar .topbar-ext { height: 40px; }
  .topbar .topbar-ext-link { min-width: 36px; padding: 0 8px; }
  .topbar .topbar-burger { width: 40px; }
}
@media (max-width: 380px) {
  .topbar .topbar-inner { padding: 0 8px; gap: 6px; }
  .topbar .topbar-brand { gap: 6px; }
  .topbar .topbar-mark,
  .topbar .topbar-mark svg { width: 22px; height: 22px; }
  .topbar .topbar-ext-link { min-width: 32px; padding: 0 6px; }
  .topbar .topbar-burger { width: 36px; }
}

/* 2026-09-27: barras (topbar/sidebar) en el azul tenue de las cajas; el
   fondo de pagina (--bg) queda un tono mas oscuro, a pedido del usuario. */
.app-shell .topbar { background: color-mix(in srgb, var(--surface) 94%, transparent); }

/* =====================================================================
   2026-09-27 -- Encabezado horizontal (top nav) y pie en columnas, al
   estilo de los sitios de herramientas para desarrolladores (JetBrains,
   Snyk, Sonar, Vercel). Reemplaza la barra lateral: .app-shell deja de
   ser una grilla de 2 columnas. Markup generado por pipeline/build_chrome.py.
   ===================================================================== */
:root { --page-max: 1280px; --gh-header-h: 64px; }
.app-shell { display: block; min-height: 0; }
.app-main > .methodology-main, .app-main > .contact-main { margin-left: auto; margin-right: auto; }
@media (min-width: 841px) { body { background-image: none; } }

.gh-header { position: sticky; top: 0; z-index: 50; background: color-mix(in srgb, var(--surface) 92%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(10px); backdrop-filter: saturate(1.4) blur(10px); border-bottom: 1px solid var(--border); }
.gh-header-inner { position: relative; max-width: var(--page-max); margin: 0 auto; padding: 0 var(--page-pad);
  height: var(--gh-header-h); display: flex; align-items: center; gap: 28px; }
.gh-brand { display: inline-flex; align-items: center; gap: 10px; color: var(--text); text-decoration: none;
  font: 700 16px var(--sans); white-space: nowrap; }
.gh-logo { width: 28px; height: 28px; flex: none; }
.gh-nav { display: flex; align-items: center; gap: 2px; flex: 1; min-width: 0; }
.gh-nav-link { display: inline-flex; align-items: center; gap: 4px; padding: 8px 12px; border: 0; border-radius: var(--radius);
  background: none; color: var(--text-dim); font: 500 14.5px var(--sans); text-decoration: none; cursor: pointer; white-space: nowrap; }
.gh-nav-link:hover, .gh-nav-link[aria-expanded="true"] { color: var(--text); background: var(--surface-2); }
.gh-nav-link[aria-current="page"], .gh-nav-link.is-active { color: var(--accent); font-weight: 600; }
.gh-chevron { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round;
  stroke-linejoin: round; transition: transform 150ms ease; }
[aria-expanded="true"] > .gh-chevron { transform: rotate(180deg); }

.gh-menu { position: relative; }
.gh-pop { position: absolute; top: calc(100% + 8px); right: 0; z-index: 60; min-width: 190px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-pop); }
.gh-pop[hidden] { display: none; }
.gh-nav-group .gh-pop { left: 0; right: auto; }
.gh-pop-wide { min-width: 330px; }
.gh-pop-link { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: var(--radius); color: var(--text); text-decoration: none; }
.gh-pop-link strong { font-size: 14px; font-weight: 600; }
.gh-pop-link span { font-size: 13px; color: var(--text-faint); }
.gh-pop-link:hover, .gh-pop-link[aria-current="page"] { background: var(--surface-2); }
.gh-pop-link[aria-current="page"] strong { color: var(--accent); }
.gh-pop-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 0; border-radius: var(--radius);
  background: none; color: var(--text); font: 500 14px var(--sans); text-align: left; cursor: pointer; }
.gh-pop-item:hover { background: var(--surface-2); }
.gh-pop-item[aria-pressed="true"] { color: var(--accent); font-weight: 600; }
.gh-ico { display: inline-flex; }
.gh-ico svg, .gh-seg-btn svg, .gh-social svg { width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

.gh-tools { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.gh-icon-btn { width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text-dim); cursor: pointer; }
.gh-icon-btn:hover, .gh-icon-btn[aria-expanded="true"] { color: var(--text); border-color: var(--border-strong); }
.gh-icon-btn .gh-ico { display: none; }
:root:not([data-theme]) .gh-icon-btn .gh-ico-system,
:root[data-theme="light"] .gh-icon-btn .gh-ico-light,
:root[data-theme="dark"] .gh-icon-btn .gh-ico-dark { display: inline-flex; }
.gh-cta.btn { padding: 9px 16px; }
.gh-nav-cta { display: none; }
.gh-burger { display: none; position: relative; width: 40px; height: 38px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface); cursor: pointer; }
.gh-burger span, .gh-burger span::before, .gh-burger span::after { content: ""; position: absolute; left: 11px;
  width: 16px; height: 2px; border-radius: 2px; background: var(--text); transition: transform .15s ease; }
.gh-burger span { top: 17px; }
.gh-burger span::before { top: -5px; left: 0; }
.gh-burger span::after { top: 5px; left: 0; }
.gh-header.nav-open .gh-burger span { background: transparent; }
.gh-header.nav-open .gh-burger span::before { top: 0; transform: rotate(45deg); background: var(--text); }
.gh-header.nav-open .gh-burger span::after { top: 0; transform: rotate(-45deg); background: var(--text); }
:focus-visible { outline: none; box-shadow: var(--focus-ring); }

@media (max-width: 960px) {
  .gh-burger { display: inline-block; }
  .gh-nav { display: none; position: absolute; top: 100%; left: 0; right: 0; flex-direction: column; align-items: stretch;
    gap: 2px; padding: 12px var(--page-pad) 18px; background: var(--surface); border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-pop); max-height: calc(100vh - var(--gh-header-h)); overflow-y: auto; }
  .gh-header.nav-open .gh-nav { display: flex; }
  .gh-nav-link { justify-content: space-between; padding: 12px; font-size: 16px; }
  .gh-nav-group .gh-pop { position: static; min-width: 0; padding: 0 0 6px 10px; border: 0; box-shadow: none; background: none; }
  .gh-nav-cta { display: inline-flex; justify-content: center; margin-top: 10px; }
}
@media (max-width: 560px) {
  .gh-cta { display: none; }
  .gh-header-inner { gap: 12px; }
}

.site-footer.gh-footer { margin-top: 72px; padding: 56px 0 28px; padding-left: 0; border-top: 0; background: var(--bg); color: var(--text); }
.gh-footer-inner { max-width: var(--page-max); margin: 0 auto; padding: 0 var(--page-pad); }
.gh-footer-top { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(0, 3fr); gap: 48px;
  padding-bottom: 40px; border-bottom: 1px solid var(--border); }
.gh-footer-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.gh-footer-brand p { margin: 0; max-width: 34ch; color: var(--text-dim); line-height: 1.6; }
.gh-footer-cols { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 24px; }
.gh-footer-col { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.gh-footer-title { margin: 0 0 4px; color: var(--text); font: 600 13.5px var(--sans); }
.gh-footer-col a { color: var(--text-dim); font-size: 14px; text-decoration: none; }
.gh-footer-col a:hover, .gh-footer-col a[aria-current="page"] { color: var(--text); }
.gh-footer-bottom { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; padding-top: 24px; }
.gh-footer-legal { flex: 1 1 320px; margin: 0; color: var(--text-faint); font-size: 13px; line-height: 1.5; }
.gh-footer-social { display: flex; gap: 8px; }
.gh-social { width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-dim); }
.gh-social:hover { color: var(--text); border-color: var(--border-strong); }
.gh-seg { display: inline-flex; gap: 2px; padding: 3px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.gh-seg-btn { width: 34px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 0;
  border-radius: var(--radius); background: none; color: var(--text-faint); cursor: pointer; }
.gh-seg-btn svg { width: 16px; height: 16px; }
.gh-seg-btn:hover { color: var(--text); }
.gh-seg-btn[aria-pressed="true"] { background: var(--surface-3); color: var(--text); }
@media (max-width: 1100px) {
  .gh-footer-top { grid-template-columns: 1fr; gap: 32px; }
  .gh-footer-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 560px) { .gh-footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (prefers-reduced-motion: reduce) { .gh-chevron, .gh-burger span, .gh-burger span::before, .gh-burger span::after { transition: none; } }

/* =====================================================================
   Encabezado de pagina (.gh-page-header), el mismo en las 10 paginas con
   encabezado. 2026-10-08: panel azul marino liso con el isotipo como
   marca de agua (se conserva por pedido del usuario). Se quitaron la
   franja superior en los 3 colores del logo, las dos luces radiales, el
   degradado de fondo y el cuadro con degradado del eyebrow. Siempre
   ocupa el ancho completo de su columna (el limite de lectura va en el
   texto, no en la caja) para que todos los encabezados compartan el
   mismo eje y el mismo borde.
   ===================================================================== */
.page-hero.gh-page-header {
  /* 2026-10-19: page headers sit on the page itself, closed by a thin rule,
     like the home hero. The navy panel (#0F2346) and the logo watermark were
     removed: with the neutral .band-dark they left dark text on navy. */
  position: relative;
  max-width: none;
  padding: clamp(28px, 4vw, 48px) 0 clamp(24px, 3vw, 36px);
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.page-hero.gh-page-header:not(.hero)::after { content: none; }

/* Eyebrow: texto en caja normal, sin icono. */
.gh-page-header .contact-kicker,
.gh-page-header .ch-copy > .eyebrow {
  display: block;
  margin: 0;
  color: var(--text-dim);
  font: 600 14px var(--sans);
  letter-spacing: 0;
  text-transform: none;
}

/* Titulo y bajada: misma escala tipografica en todas las paginas. */
.gh-page-header:not(.hero) h1 {
  max-width: 22ch;
  margin: 14px 0 0;
  color: var(--text);
  font: 600 clamp(30px, 3.6vw, 46px) / 1.12 var(--serif);
  letter-spacing: -0.02em;
}
.gh-page-header .contact-lead,
.gh-page-header .ch-copy > p:not(.eyebrow) {
  max-width: 62ch;
  margin: 16px 0 0;
  color: var(--text-dim);
  font-size: 17px;
  line-height: 1.65;
}
.gh-page-header.method-intro { max-width: none; }

@media (max-width: 640px) {
  .gh-page-header .contact-lead, .gh-page-header .ch-copy > p:not(.eyebrow) { font-size: 16px; }
}

/* 2026-09-27 -- Componentes compartidos del sistema nuevo: cifras de
   encabezado (.hdr-stats, en el encabezado de marca de la home, el
   catalogo y las fichas) y etiquetas de precio (.price-badge). */
.hdr-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--border); }
.hdr-stat { display: flex; flex-direction: column; gap: 4px; padding: 16px 20px; background: color-mix(in srgb, var(--surface) 88%, transparent); }
.hdr-stat-num { color: var(--text); font: 700 26px / 1.1 var(--sans); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.hdr-stat-label { color: var(--text-dim); font-size: 13px; }
/* Price labels are neutral (2026-10-19): green means a verified fix on this site, not "free". */
.price-badge { display: inline-flex; align-items: center; padding: 2px 8px; border: 1px solid var(--border-strong); border-radius: var(--radius);
  font: 600 12px / 1.4 var(--sans); letter-spacing: .02em; white-space: nowrap; }
.price-free, .price-freemium, .price-paid { background: transparent; color: var(--text); }
.price-pending { background: var(--surface-3); color: var(--text-dim); }

/* =====================================================================
   2026-09-27 -- Normalizacion tras el barrido de elementos antiguos:
   restos del diseno anterior (tipografia monoespaciada en UI y etiquetas
   de 10-11 px) pasan al sistema nuevo. El codigo real (code, pre, kbd,
   la ventana de codigo de contacto, IDs de tickets, el mensaje armado de
   contacto y las etiquetas del diagrama SVG) sigue en monoespaciada.
   ===================================================================== */
.btn, .gh-cta, .cf-copy, .catalog-pager-btn { font-family: var(--sans); letter-spacing: 0; text-transform: none; }
.cat-cell-count, .cat-cell-arrow { font-family: var(--sans); font-size: 12.5px; letter-spacing: 0; }
.ic-stat { font-family: var(--sans); font-size: 13px; letter-spacing: 0; }
.catalog-pager-status, .plugin-asof, .legal-updated, .sc-dl { font-family: var(--sans); letter-spacing: 0; }
.view-toggle button { font-family: var(--sans); font-size: 12.5px; letter-spacing: 0; text-transform: none; }
.crumbs a, .crumbs span, .crumb-sep { font-family: inherit; }
.similar-card .sc-niche { font-size: 13px; }
.pi-eyebrow, .pi-step-num { font-family: var(--sans); font-size: 12px; font-weight: 700; letter-spacing: .08em; }
.pi-stat-num { font-family: var(--sans); }
.pi-stat-label { font-size: 12px; }
.cf-counter { font-family: var(--sans); font-size: 12px; }
.page-insights b, .main-with-rail aside b { font-family: var(--sans); font-size: 12px; }
.methodology-main h2 { margin-top: 0; color: var(--text); font: 600 21px / 1.3 var(--serif); letter-spacing: -0.01em; text-transform: none; }
.case-meta-row dt { font-family: var(--sans); font-size: 12px; letter-spacing: .06em; }
.case-meta-note { font-size: 12.5px; }
.lab-cases .eyebrow, .identity-case .eyebrow { font-family: var(--sans); font-size: 12px; letter-spacing: .08em; }
.ticket-status { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: var(--radius);
  font: 700 12px / 1.4 var(--sans); letter-spacing: .02em; text-transform: none; }
/* Status colors on the evidence pages (2026-10-19). The pages carry older inline rules that mix the
   text color into its own background (below 4.5:1 in light mode); these use the validated token pairs
   and the site's meaning: green = fixed, amber = the gap is still there. */
.ticket-head .ticket-status.is-fixed { color: var(--valid); background: var(--valid-bg); }
.ticket-head .ticket-status.is-open { color: var(--inspect); background: var(--inspect-bg); }
.ticket-head .ticket-status.is-submitted { color: var(--text); background: var(--surface-3); }

/* Segunda pasada: mismos ajustes con la especificidad de las reglas viejas. */
.category-links .cat-cell-count, .category-links .cat-cell-arrow,
.catalog-explore .cat-cell-count, .catalog-explore .cat-cell-label { font-family: var(--sans); letter-spacing: 0; }
.category-links .cat-cell-count, .catalog-explore .cat-cell-count { font-size: 12.5px; }
.similar-card .sc-dl { font-family: var(--sans); font-size: 13px; }
nav.crumbs a, nav.crumbs span { font-family: var(--sans); }
.contact-section h2, .disclosure h2 { margin-top: 0; color: var(--text); font: 600 21px / 1.3 var(--serif); letter-spacing: -0.01em; text-transform: none; }
.catalog-explore .cat-cell-label { font-size: 13px; }

/* Selector de idioma (EN/ES) */
.gh-lang-btn { width: auto; gap: 6px; padding: 0 10px; }
.gh-lang-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.gh-lang-code { font: 700 12.5px var(--sans); letter-spacing: .04em; }
.gh-lang .gh-pop-item[aria-current="true"] { color: var(--accent); font-weight: 600; }
.gh-lang .gh-pop-item { text-decoration: none; }
@media (max-width: 420px) { .gh-lang-code { display: none; } .gh-lang-btn { width: 38px; padding: 0; } }

/* Buscador del topbar (2026-10-05): boton en .gh-tools + dialogo con lista y
   vista previa (js/site-search.js lo arma al abrirse). Tokens del tema, asi
   que funciona igual en claro y oscuro. */
.gh-search-btn { display: inline-flex; align-items: center; gap: 8px; height: 38px; min-width: 190px; padding: 0 8px 0 12px;
  border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); color: var(--text-dim);
  font: 500 13px var(--sans); cursor: pointer; }
.gh-search-btn:hover, .gh-search-btn[aria-expanded="true"] { border-color: var(--border-strong); color: var(--text); }
.gh-search-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gh-search-btn svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.gh-search-label { flex: 1; text-align: left; }
.gh-search-kbd { font: 600 11px var(--mono); padding: 2px 6px; border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-faint); background: var(--bg); }
@media (max-width: 1180px) {
  .gh-search-btn { min-width: 0; width: 38px; padding: 0; justify-content: center; }
  .gh-search-label, .gh-search-kbd { display: none; }
}
html.ghs-open { overflow: hidden; }
.ghs-backdrop { position: fixed; inset: 0; z-index: 1000; display: flex; justify-content: center; align-items: flex-start;
  padding: 72px 16px 16px; background: color-mix(in srgb, #020812 55%, transparent); }
.ghs-backdrop[hidden] { display: none; }
.ghs-dialog { width: min(880px, 100%); max-height: calc(100vh - 96px); display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-pop); }
.ghs-bar { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.ghs-bar svg { width: 18px; height: 18px; flex: none; fill: none; stroke: var(--text-faint); stroke-width: 1.6; stroke-linecap: round; }
.ghs-input { flex: 1; min-width: 0; border: 0; outline: none; background: transparent; color: var(--text); font: 500 16px var(--sans); }
.ghs-input::-webkit-search-cancel-button { display: none; }
.ghs-close { flex: none; padding: 3px 7px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); color: var(--text-dim);
  font: 600 11px var(--mono); cursor: pointer; }
.ghs-close:focus-visible, .ghs-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ghs-body { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); flex: 1; min-height: 0; }
.ghs-list { margin: 0; padding: 6px; list-style: none; overflow-y: auto; max-height: 60vh; border-right: 1px solid var(--border); }
.ghs-item { display: grid; gap: 2px; padding: 9px 10px; border-radius: var(--radius); cursor: pointer; }
.ghs-item.is-active { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.ghs-kind { color: var(--text-faint); font: 600 10.5px var(--sans); letter-spacing: .05em; text-transform: uppercase; }
.ghs-name { color: var(--text); font: 600 14.5px var(--sans); }
.ghs-name mark { padding: 0 1px; border-radius: 3px; background: color-mix(in srgb, var(--accent) 24%, transparent); color: inherit; }
.ghs-meta { overflow: hidden; color: var(--text-dim); font-size: 12.5px; white-space: nowrap; text-overflow: ellipsis; }
.ghs-empty { padding: 18px 14px; color: var(--text-dim); font-size: 14px; }
.ghs-empty p { margin: 0 0 6px; }
.ghs-empty a { color: var(--accent); font-weight: 600; }
.ghs-preview { padding: 18px 20px; overflow-y: auto; max-height: 60vh; }
.ghs-p-kind { margin: 0 0 4px; color: var(--text-faint); font: 600 11px var(--sans); letter-spacing: .05em; text-transform: uppercase; }
.ghs-p-name { margin: 0 0 10px; color: var(--text); font: 700 19px/1.3 var(--sans); letter-spacing: 0; text-transform: none; }
.ghs-p-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 8px; }
.ghs-p-chips span { padding: 2px 8px; border-radius: var(--radius); background: var(--surface-2); color: var(--text-dim); font: 600 12px var(--sans); }
.ghs-p-niche { margin: 0 0 4px; color: var(--text-dim); font-size: 13px; }
.ghs-p-stat { margin: 0 0 10px; color: var(--text); font: 600 13px var(--sans); }
.ghs-p-desc { margin: 0 0 14px; color: var(--text-dim); font-size: 14px; line-height: 1.6; }
.ghs-p-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.ghs-btn { display: inline-flex; align-items: center; padding: 8px 14px; border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface); color: var(--text); font: 600 13px var(--sans); text-decoration: none; }
.ghs-btn:hover { border-color: var(--accent); }
.ghs-btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.ghs-foot { display: flex; justify-content: space-between; gap: 12px; padding: 8px 14px; border-top: 1px solid var(--border);
  color: var(--text-faint); font-size: 12px; }
@media (max-width: 760px) {
  .ghs-backdrop { padding: 0; }
  .ghs-dialog { width: 100%; height: 100%; max-height: none; border-radius: 0; }
  .ghs-body { grid-template-columns: 1fr; }
  .ghs-list { max-height: none; border-right: 0; }
  .ghs-preview, .ghs-hint { display: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .ghs-dialog { animation: ghs-in .14s ease-out; }
  @keyframes ghs-in { from { opacity: 0; transform: translateY(-6px); } }
}

/* =====================================================================
   2026-10-08 -- Sitio sin adornos. Estas reglas anulan efectos que
   siguen en home.css, catalog.css y plugin.css (copias historicas de la
   misma hoja): resplandores de fondo, corchetes y barrido de brillo en
   las tarjetas, cajas con degradado y la linea animada de la hoja de
   ruta. shell.css se carga ultimo en todas las paginas.
   ===================================================================== */
body { background-image: none; }
.topbar::after { content: none; }
.plugin-card::before, .plugin-card::after { content: none; }
.svc-band, .hire-band, .path-card-strong { background: var(--surface); }
.identity-process .flow-line-1 { stroke: var(--accent); stroke-dasharray: none; opacity: 0.5; animation: none; }
.identity-process .flow-line-2, .identity-process .flow-line-3, .flow-line { animation: none; }
.rm-dot { box-shadow: none; }
/* Eyebrows: caja normal y color de texto secundario, como el del encabezado de pagina. */
.eyebrow, .path-card .path-kicker, .lab-cases .eyebrow, .identity-case .eyebrow {
  font: 600 14px var(--sans); letter-spacing: 0; text-transform: none; color: var(--text-dim);
}

/* =====================================================================
   Aparicion al hacer scroll (js/site-reveal.js). Solo actua sobre los
   elementos que el script marca con la clase .rv-target y solo si <html>
   tiene .rv-on. Es una clase y no un data-*: catalog.js copia los data-*
   de las tarjetas a las filas de la tabla, y un data-rv copiado dejaba
   filas ocultas que nadie observaba. Sin JavaScript, con "reducir
   movimiento" o al imprimir, todo
   .rv-on; sin JavaScript, con "reducir movimiento" o al imprimir, todo
   se ve desde el principio. Temporalidad y posicion salen de variables
   que el script fija por elemento desde su CONFIG y los data-reveal-*.
   ===================================================================== */
.rv-on .rv-target {
  opacity: 0;
  transform: translate3d(var(--rv-x, 0px), var(--rv-y, 0px), 0);
  transition:
    opacity var(--rv-dur, 450ms) var(--rv-ease, ease-out) var(--rv-delay, 0ms),
    transform var(--rv-dur, 450ms) var(--rv-ease, ease-out) var(--rv-delay, 0ms);
}
.rv-on .rv-target.rv-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv-on .rv-target { opacity: 1; transform: none; transition: none; }
}
@media print {
  .rv-on .rv-target { opacity: 1 !important; transform: none !important; }
}

/* 2026-10-08, segunda pasada de naturalizacion: rotulos pequenos en caja normal, titulares sin palabras de otro color
   y pasos numerados con un numero simple, sin circulo. */
.pi-eyebrow, .svc-kicker, .cv-eyebrow, .ee-kicker, .plat-label, .share-label, .case-meta-row dt, .lab-cases dt {
  text-transform: none; letter-spacing: 0;
}
h1 .accent, h2 .accent, .hero-title .accent { color: inherit; }
.pi-step-num { width: auto; height: auto; border-radius: 0; background: none; color: var(--text-dim); font-weight: 600; }
/* Estado de los tickets en texto normal. */
.ticket-status { font-family: var(--sans); font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none; }
/* Tabla del catalogo: cabecera y cifras en la tipografia del sitio, sin mayusculas forzadas ni monoespaciada. */
thead th { font-family: var(--sans); font-size: 12.5px; font-weight: 600; letter-spacing: 0; text-transform: none; }
td.num-cell { font-family: var(--sans); font-variant-numeric: tabular-nums; }
tr.row td[data-label]::before { font-family: var(--sans); font-size: 11px; letter-spacing: 0; text-transform: none; }
/* Botones dentro del encabezado de una pagina interna (p. ej. la auditoria de rendimiento). */
.gh-page-header:not(.hero) .hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }

/* Catalog spec sheet (2026-10-19): the catalog header states its scope as data rows, not as big numbers. */
.spec-sheet { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; margin: 28px 0 0; border-top: 1px solid var(--text); }
.spec-sheet .spec-row { display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.spec-sheet dt { font: 600 12px/1.6 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-dim); }
.spec-sheet dd { margin: 0; font-size: 14px; line-height: 1.55; color: var(--text); font-variant-numeric: tabular-nums; }
@media (max-width: 700px) {
  .spec-sheet { grid-template-columns: 1fr; }
  .spec-sheet .spec-row { grid-template-columns: 112px minmax(0, 1fr); }
}

/* Service price levels (2026-10-19): one ruled row per level -- name, what decides it, price and delivery. */
.tier-list { margin: 16px 0 4px; border-top: 1px solid var(--text); }
.tier-list .tier { display: grid; grid-template-columns: 168px minmax(0, 1fr) auto; gap: 4px 20px; align-items: baseline; padding: 12px 0; border-bottom: 1px solid var(--border); }
.tier-list dt { font-weight: 600; color: var(--text); }
.tier-list dd { margin: 0; }
.tier-list .tier-scope { font-size: 14.5px; line-height: 1.55; color: var(--text-dim); }
.tier-list .tier-terms { font: 400 13px/1.55 var(--mono); color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
@media (max-width: 760px) {
  .tier-list .tier { grid-template-columns: minmax(0, 1fr); }
  .tier-list .tier-terms { white-space: normal; text-align: left; }
}
