/* ==========================================================================
   MIND MIAMI — SYSTEM v1 · PÁGINAS INTERIORES (system-pages.css)
   Se carga SIEMPRE DESPUÉS de /css/system.css (tokens, reset, nav, footer,
   chips, tableros y marquees viven allí — aquí solo lo que el home no define).
   Shell obligatorio (ver docs/SYSTEM-STYLE.md):

     <link rel="stylesheet" href="/css/system.css">
     <link rel="stylesheet" href="/css/system-pages.css">
     <link rel="stylesheet" href="/css/motion.css">
     <script defer src="/js/i18n.js"></script>
     <script defer src="/js/system.js"></script>
     <script defer src="/js/motion.js"></script>

   ========================================================================
   NAV INTERIOR (.inner-nav) — COPIAR LITERAL este snippet.
   Sobre hero navy (por defecto):

   <nav class="nav-shell inner-nav" aria-label="Main navigation" data-en-attr="aria-label:Main navigation" data-es-attr="aria-label:Navegación principal">
     <a href="/" class="nav-brand" aria-label="Mind Miami home" data-en-attr="aria-label:Mind Miami home" data-es-attr="aria-label:Inicio de Mind Miami">
       <img class="brand-logo" src="/assets/brand/logo-inverse.png" alt="MIND MIAMI" width="435" height="93">
     </a>
     <div class="nav-links">
       <a href="/" data-es="Inicio">Home</a>
       <a href="/services" data-es="Servicios">Services</a>
       <a href="/industries" data-es="Industrias">Industries</a>
       <a href="/systems" data-es="Sistemas">Systems</a>
       <a href="/work" data-es="Trabajos">Work</a>
     </div>
     <div class="nav-right">
       <div class="lang-toggle" role="group" aria-label="Language / Idioma">
         <button type="button" data-lang="en" aria-pressed="true">EN</button>
         <button type="button" data-lang="es" aria-pressed="false">ES</button>
       </div>
       <a class="nav-cta" href="/start">
         <span data-es="Iniciar un proyecto">Start a project</span>
         <i aria-hidden="true">↗</i>
       </a>
     </div>
   </nav>

   · Marca la página actual con aria-current="page" en su enlace.
   · Sobre hero papel (.page-hero--paper): añadir la clase .inner-nav--paper
     al <nav> y cambiar el logo a /assets/brand/logo-primary.png.
   ========================================================================== */

/* Fuentes extra autoalojadas — SOLO para wordmarks de clientes (.cs-mark).
   PROHIBIDAS en titulares/copy de Mind Miami (el sistema es Sora + Inter). */
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin-400-normal.woff2") format("woff2");
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin-500-normal.woff2") format("woff2");
  font-weight: 500; font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin-700-normal.woff2") format("woff2");
  font-weight: 700; font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin-900-normal.woff2") format("woff2");
  font-weight: 900; font-display: swap;
}
@font-face {
  font-family: "Bebas Neue";
  src: url("/assets/fonts/bebas-neue-latin-400-normal.woff2") format("woff2");
  font-weight: 400; font-display: swap;
}

/* --------------------------------------------------------------------------
   AA en interiores: system.css pinta AMBOS spans del .section-kicker en cian
   13px; sobre papel eso es ~1.65:1 (SYSTEM-STYLE §Accesibilidad lo prohíbe).
   Aquí la ETIQUETA vuelve al estilo base del kicker (Inter 600 12px, color
   heredado: tinta-suave sobre papel / muted sobre navy) y el NÚMERO conserva
   el acento cian de la marca. Solo afecta a páginas que cargan este archivo.
   -------------------------------------------------------------------------- */
.section-kicker span + span {
  font-family: var(--body);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: .3em;
  color: inherit;
}

/* ==========================================================================
   1 · PAGE HERO — hero interior compacto (navy por defecto, --paper variante)
   ========================================================================== */
.page-hero {
  position: relative;
  min-height: clamp(520px, 66svh, 760px);
  display: flex; flex-direction: column;
  background: var(--navy);
  color: var(--text-on-navy);
  isolation: isolate;
  overflow: clip;
}
.page-hero-grid {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(rgba(246, 244, 241, .045) 1px, transparent 1px) 0 0 / 100% 25%,
    linear-gradient(90deg, rgba(246, 244, 241, .045) 1px, transparent 1px) 0 0 / 25% 100%;
}
.page-hero-glow {
  position: absolute; z-index: -1; right: -14%; top: -24%;
  width: 52vw; height: 52vw;
  background: radial-gradient(circle, rgba(6, 214, 221, .12), transparent 62%);
}
.page-hero-body {
  flex: 1;
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  padding: clamp(30px, 5vh, 60px) var(--pad-x) clamp(44px, 6vh, 76px);
}
.page-hero-body .section-kicker { margin-bottom: clamp(18px, 3vh, 28px); }
.page-hero h1 {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(42px, 5.8vw, 92px);
  line-height: .99;
  letter-spacing: -.02em;
  text-transform: uppercase;
  color: #fff;
}
.page-hero h1 > span { display: block; }
.page-hero h1 .cyan-dot { display: inline; }
.page-hero-intro {
  margin-top: clamp(20px, 3vh, 34px);
  max-width: 560px;
  color: var(--muted-on-navy);
  font-size: clamp(15px, 1.2vw, 17px);
}
.page-hero-cta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 14px 26px;
  margin-top: clamp(26px, 4vh, 44px);
}
.text-link {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px;
  font-size: 13px; font-weight: 600; letter-spacing: .04em;
  color: var(--text-on-navy);
  box-shadow: inset 0 -1px var(--cyan);
  transition: color .2s ease;
}
.text-link:hover { color: var(--cyan); }

/* Variante papel */
.page-hero--paper { background: var(--paper); color: var(--ink); }
.page-hero--paper .page-hero-grid {
  background:
    linear-gradient(rgba(10, 26, 47, .07) 1px, transparent 1px) 0 0 / 100% 25%,
    linear-gradient(90deg, rgba(10, 26, 47, .07) 1px, transparent 1px) 0 0 / 25% 100%;
}
.page-hero--paper .page-hero-glow { background: radial-gradient(circle, rgba(6, 214, 221, .10), transparent 62%); }
.page-hero--paper h1 { color: var(--ink); }
.page-hero--paper .outline-line {
  color: transparent;
  -webkit-text-stroke: 2px rgba(10, 26, 47, .82);
  text-stroke: 2px rgba(10, 26, 47, .82);
}
.page-hero--paper .outline-line .cyan-dot { color: var(--cyan); -webkit-text-stroke: 0; }
.page-hero--paper .page-hero-intro { color: var(--ink-soft); }
.page-hero--paper .text-link { color: var(--ink); }
.page-hero--paper .text-link:hover { color: var(--ink-soft); }

/* ==========================================================================
   2 · INNER NAV — .nav-shell del home adaptado a interiores
   (snippet exacto en el comentario de cabecera de este archivo)
   ========================================================================== */
.inner-nav .nav-links a[aria-current="page"] {
  color: #fff;
  box-shadow: inset 0 -2px var(--cyan);
}

/* Skin papel: .inner-nav--paper (usar con .page-hero--paper + logo-primary) */
.inner-nav--paper .nav-links a { color: var(--ink-soft); }
.inner-nav--paper .nav-links a:hover { color: var(--ink); }
.inner-nav--paper .nav-links a[aria-current="page"] { color: var(--ink); }
.inner-nav--paper .lang-toggle { border-color: var(--line-ink); }
.inner-nav--paper .lang-toggle button { color: var(--ink-soft); }
.inner-nav--paper .lang-toggle button.is-on { background: var(--cyan); color: var(--navy); }
/* CTA sólido navy sobre papel: el ↗ cian queda sobre navy (AA seguro) */
.inner-nav--paper .nav-cta { background: var(--navy); border-color: var(--navy); color: #fff; }
.inner-nav--paper .nav-cta:hover { background: var(--cyan); border-color: var(--cyan); color: var(--navy); }

/* ==========================================================================
   3 · CLIENT STRIP — 7 LOGOTIPOS de cliente desde el sprite vectorial
   /assets/brand/clients.svg  (symbols: cl-rabbit · cl-tiendita · cl-monkey ·
   cl-mad · cl-tulum · cl-pony · cl-ufactory). Todos con viewBox de alto 40,
   dibujados en currentColor, con el acento cian definido DENTRO del sprite
   (.cl-accent), así que funcionan igual sobre navy y sobre papel.

   Marcado (los nombres de clase no cambian; el contenido sí):

     <ul class="client-strip" aria-label="Selected clients">
       <li class="cs-mark cs-mark--rabbit">
         <svg viewBox="0 0 137 40" role="img" aria-label="Dirty Rabbit Group">
           <use href="/assets/brand/clients.svg#cl-rabbit"></use>
         </svg>
       </li>
       …
     </ul>

   Anchos de viewBox (el alto siempre 40):
     cl-rabbit 137 · cl-tiendita 149 · cl-monkey 116 · cl-mad 133 ·
     cl-tulum 104 · cl-pony 136 · cl-ufactory 142
   ========================================================================== */
.client-strip {
  /* alto óptico uniforme de TODOS los logos + columna mínima calculada:
     3.73 = relación de la marca más ancha (cl-tiendita 149/40) + aire */
  --cs-h: clamp(22px, 1.9vw, 27px);
  --cs-col: calc(var(--cs-h) * 4.6);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--cs-col), 1fr));
  align-items: center; justify-items: center;
  gap: clamp(20px, 2.4vw, 30px) clamp(24px, 3vw, 44px);
  list-style: none;
  background: var(--navy);
  border-block: 1px solid var(--line-paper);
  padding: clamp(26px, 3.5vw, 44px) var(--pad-x);
}
/* Reparto SIN HUÉRFANAS. Con 7 marcas sólo 7, 5, 4 y 1 columnas reparten sin
   dejar una sola marca colgando (6→6+1, 3→3+3+1, 2→2+2+2+1). Por eso el grid
   salta esos escalones: 7 en una fila → 4+3 → una por fila en móvil.
   Además, en el reparto 4+3 la fila corta se CENTRA: la rejilla se dobla (cada
   marca ocupa 2 de 8 columnas) y la segunda fila arranca una columna adentro,
   así no queda un hueco al final de la fila. */
@media (max-width: 1180px) {
  .client-strip { grid-template-columns: repeat(8, 1fr); }
  .client-strip > .cs-mark { grid-column: auto / span 2; }
  .client-strip > .cs-mark:nth-child(5) { grid-column: 2 / span 2; }
}
@media (max-width: 700px) {
  .client-strip {
    --cs-h: 24px;
    grid-template-columns: 1fr;
    gap: clamp(20px, 5vw, 26px);
  }
  .client-strip > .cs-mark,
  .client-strip > .cs-mark:nth-child(5) { grid-column: auto / span 1; }
}

.cs-mark {
  display: inline-flex; align-items: center;
  font-size: 17px; line-height: 1;
  /* Tinta del logotipo: clara por defecto (todas las superficies actuales son
     navy). Sobre papel basta con --cs-color: var(--ink) en el contenedor. */
  color: var(--cs-color, rgba(246, 244, 241, .92));
  white-space: nowrap;
}
/* El logo hereda ese color vía currentColor; el cian vive dentro del sprite.
   Fuera del strip el alto va en em para que un font-size local (mini-casos,
   style="font-size:13px" de las páginas de servicio) lo siga escalando. */
.cs-mark svg {
  display: block;
  height: var(--cs-h, 1.6em);
  width: auto;
  overflow: visible;
}

/* -- Fallback tipográfico: sólo para marcado antiguo que todavía lleve el
   nombre como TEXTO dentro de .cs-mark (sin <svg>). No afecta a los logos. -- */
.cs-mark:not(:has(svg)) i { font-style: normal; color: var(--cyan); }
.cs-mark:not(:has(svg)) b { font-weight: inherit; }
.cs-mark--rabbit:not(:has(svg)) { font-family: "Montserrat", var(--body); font-weight: 900; letter-spacing: .015em; text-transform: uppercase; }
.cs-mark--rabbit:not(:has(svg)) i { margin: 0 .34em; font-weight: 700; }
.cs-mark--rabbit:not(:has(svg)) b { font-weight: 500; font-size: .6em; letter-spacing: .32em; }
.cs-mark--tiendita:not(:has(svg)) { font-family: var(--display); font-weight: 600; font-size: 1.08em; letter-spacing: .045em; text-transform: lowercase; }
.cs-mark--tiendita:not(:has(svg)) i { font-weight: 800; margin-left: .06em; }
.cs-mark--monkey:not(:has(svg)) { font-family: "Montserrat", var(--display); font-weight: 900; font-size: .96em; letter-spacing: .06em; text-transform: uppercase; }
.cs-mark--monkey:not(:has(svg)) i { margin: 0 .16em; }
.cs-mark--mad:not(:has(svg)) {
  font-family: "Montserrat", var(--body); font-weight: 900; letter-spacing: -.03em; text-transform: uppercase;
  transform: skewX(-8deg);
  border-bottom: 3px solid var(--cyan);
  padding-bottom: 3px;
}
.cs-mark--tulum:not(:has(svg)) { font-family: var(--body); font-weight: 500; font-size: .9em; letter-spacing: .4em; text-transform: uppercase; }
.cs-mark--tulum:not(:has(svg)) i { font-weight: 600; margin-right: .12em; }
.cs-mark--pony:not(:has(svg)) { font-family: var(--display); font-weight: 800; letter-spacing: .02em; text-transform: uppercase; }
.cs-mark--pony:not(:has(svg)) b {
  margin-left: .3em;
  color: transparent;
  -webkit-text-stroke: 1.1px var(--cyan);
  text-stroke: 1.1px var(--cyan);
}
.cs-mark--ufactory:not(:has(svg)) { font-family: var(--body); font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.cs-mark--ufactory:not(:has(svg)) i { align-self: flex-start; font-size: .72em; font-weight: 700; margin-left: .14em; transform: translateY(-.18em); }

/* Variante marquee (duplicar el set de 7 marcas dentro del track, como en el
   .client-marquee del home, para el loop -50%) */
.client-strip--marquee { display: block; overflow: clip; padding: clamp(22px, 3vw, 34px) 0; }
.client-strip-track {
  display: inline-flex; align-items: center;
  gap: clamp(34px, 4.5vw, 64px);
  padding-left: clamp(34px, 4.5vw, 64px);
  white-space: nowrap; will-change: transform;
  animation: marquee 38s linear infinite; /* @keyframes marquee vive en system.css */
}
.client-strip--marquee:hover .client-strip-track { animation-play-state: paused; }

/* ==========================================================================
   4 · STEP FLOW — proceso vertical 01→05 con línea que se dibuja al scroll
   El riel cian usa la API de motion.js: data-scrub="clip:100,0" (estado
   natural = dibujado, así queda completo sin JS o con reduced-motion).
   ========================================================================== */
.step-flow { position: relative; }
.step-flow-rail {
  position: absolute; left: 30px; top: 10px; bottom: 10px;
  width: 2px;
  background: var(--line-ink);
}
.step-flow-rail i { position: absolute; inset: 0; display: block; background: var(--cyan); }
.step-flow-list { display: flex; flex-direction: column; gap: clamp(36px, 5vw, 60px); }
.step-flow-item {
  position: relative;
  display: grid; grid-template-columns: 82px 1fr;
  gap: clamp(14px, 2vw, 30px);
  align-items: start;
}
.step-flow-num {
  position: relative; z-index: 1;
  font-family: var(--display); font-weight: 700; font-size: 27px; line-height: 1.15;
  color: transparent;
  -webkit-text-stroke: 1.1px var(--ink);
  text-stroke: 1.1px var(--ink);
  background: var(--paper);           /* tapa el riel a su paso */
  padding: 8px 0 14px;
}
.step-flow-phase { font-size: 11px; font-weight: 600; letter-spacing: .26em; text-transform: uppercase; color: var(--ink-soft); }
.step-flow-body h3 {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(22px, 2.4vw, 34px);
  letter-spacing: -.015em;
  margin: 6px 0 10px;
}
.step-flow-text { color: var(--ink-soft); font-size: 15px; max-width: 520px; }

/* Variante sobre navy (asume fondo var(--navy)) */
.step-flow--dark .step-flow-rail { background: var(--line-paper); }
.step-flow--dark .step-flow-num {
  background: var(--navy);
  -webkit-text-stroke-color: rgba(246, 244, 241, .55);
}
.step-flow--dark .step-flow-phase { color: var(--muted-on-navy); }
.step-flow--dark .step-flow-body h3 { color: #fff; }
.step-flow--dark .step-flow-text { color: var(--muted-on-navy); }

/* ==========================================================================
   5 · FAQ SYSTEM — re-skin del patrón de main.js (NO renombrar clases:
   .faq-item > h3 > button[aria-expanded][aria-controls] + .faq-answer[id][hidden])
   ========================================================================== */
.faq-system { max-width: 860px; }
.faq-system .faq-item { border-top: 1px solid var(--line-ink); }
.faq-system .faq-item:last-child { border-bottom: 1px solid var(--line-ink); }
.faq-system .faq-item h3 { margin: 0; font-size: inherit; }
.faq-system .faq-item button {
  width: 100%;
  display: flex; align-items: baseline; justify-content: space-between; gap: 22px;
  background: none; border: 0; cursor: pointer; text-align: left;
  padding: 21px 4px; min-height: 44px;
  font-family: var(--display); font-weight: 600;
  font-size: clamp(16px, 1.5vw, 20px);
  line-height: 1.35; letter-spacing: -.01em;
  color: var(--ink);
  transition: background .2s ease;
}
.faq-system .faq-item button:hover { background: var(--paper-2); }
.faq-system .faq-item button::after {
  content: "+";
  flex: none;
  font-family: var(--display); font-weight: 700; font-size: 22px; line-height: 1;
  color: var(--ink-soft);
  transition: transform .3s ease;
}
.faq-system .faq-item button[aria-expanded="true"]::after { content: "–"; }
.faq-system .faq-answer {
  max-height: 0; overflow: hidden;
  transition: max-height .35s cubic-bezier(.22, .61, .36, 1);
}
.faq-system .faq-answer[hidden] { display: none; }
.faq-system .faq-answer p {
  padding: 2px 4px 26px;
  max-width: 700px;
  color: var(--ink-soft);
  font-size: 15px; line-height: 1.75;
}
/* Sin JS los paneles quedan abiertos y legibles */
@media (scripting: none) {
  .faq-system .faq-answer, .faq-system .faq-answer[hidden] { display: block; max-height: none; }
}

/* Variante sobre navy */
.faq-system--dark .faq-item,
.faq-system--dark .faq-item:last-child { border-color: var(--line-paper); }
.faq-system--dark .faq-item button { color: #fff; }
.faq-system--dark .faq-item button:hover { background: var(--navy-2); }
.faq-system--dark .faq-item button::after { color: var(--muted-on-navy); }
.faq-system--dark .faq-answer p { color: var(--muted-on-navy); }

/* ==========================================================================
   6 · PRICE CARD — tarjeta de paquete navy (+ .is-featured con marco cian)
   ========================================================================== */
.price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(272px, 1fr));
  gap: 14px;
  align-items: stretch;
}
.price-card {
  position: relative;
  display: flex; flex-direction: column; gap: 18px;
  background: var(--navy);
  color: var(--text-on-navy);
  border: 1px solid var(--line-paper);
  padding: clamp(26px, 3vw, 40px);
}
.price-card.is-featured { border: 2px solid var(--cyan); }
.price-flag {
  position: absolute; top: 0; left: clamp(24px, 3vw, 38px);
  transform: translateY(-50%);
  background: var(--cyan); color: var(--navy);
  font-family: var(--display); font-weight: 700; font-size: 10px; line-height: 1;
  letter-spacing: .18em; text-transform: uppercase;
  padding: 7px 12px;
}
.price-index { font-family: var(--display); font-weight: 700; font-size: 13px; color: var(--cyan); }
.price-name { font-family: var(--display); font-weight: 700; font-size: clamp(22px, 2vw, 30px); color: #fff; margin-top: 8px; }
.price-for { color: var(--muted-on-navy); font-size: 14px; margin-top: 6px; }
.price-amount {
  display: flex; align-items: baseline; gap: 10px;
  border-top: 1px solid var(--line-paper);
  padding-top: 18px;
}
.price-amount b {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(34px, 3vw, 46px); line-height: 1; letter-spacing: -.02em;
  color: #fff;
}
.price-amount span { font-size: 12px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--muted-on-navy); }
.price-includes { display: flex; flex-wrap: wrap; gap: 8px; }
.price-includes li {
  border: 1px solid var(--line-paper);
  padding: 7px 13px;
  font-size: 12px; font-weight: 500; letter-spacing: .04em;
  color: var(--text-on-navy);
}
.is-featured .price-includes li { border-color: rgba(6, 214, 221, .45); }
.price-cta { margin-top: auto; align-self: flex-start; } /* usar junto a .nav-cta */

/* ==========================================================================
   7 · INDUSTRY BLOCK — kicker + claim + mini-caso (marca cliente) + chips
   Sobre papel; el mini-caso es un panel navy para que el .cs-mark viva
   en su superficie correcta.
   ========================================================================== */
.industry-block {
  display: grid; grid-template-columns: 1.15fr .85fr;
  gap: clamp(26px, 4vw, 64px);
  border-top: 1px solid var(--line-ink);
  padding: clamp(38px, 5vw, 68px) 0;
}
.industry-block:last-child { border-bottom: 1px solid var(--line-ink); }
.industry-head .section-kicker { margin-bottom: 18px; }
.industry-claim {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(26px, 3vw, 44px);
  line-height: 1.1; letter-spacing: -.015em;
  margin-bottom: 14px;
}
.industry-claim em { font-style: italic; font-weight: 600; color: var(--ink-soft); }
.industry-copy { color: var(--ink-soft); max-width: 500px; }
.industry-services { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.industry-services li {
  border: 1px solid var(--line-ink);
  padding: 7px 13px;
  font-size: 12px; font-weight: 500; letter-spacing: .04em;
  color: var(--ink);
}
.industry-case {
  align-self: start;
  display: flex; flex-direction: column; align-items: flex-start; gap: 14px;
  background: var(--navy);
  color: var(--text-on-navy);
  padding: clamp(22px, 2.6vw, 36px);
}
.industry-case-label {
  font-size: 10px; font-weight: 600; letter-spacing: .24em; text-transform: uppercase;
  color: var(--muted-on-navy);
}
.industry-case .cs-mark { font-size: 19px; }
.industry-case-text { color: var(--muted-on-navy); font-size: 14px; line-height: 1.75; }

/* ==========================================================================
   8 · CTA BAND — banda final de conversión (reutiliza .contact-circle del
   home; puede contener el .site-footer al final, como en index.html)
   ========================================================================== */
.cta-band {
  background: var(--navy);
  color: var(--text-on-navy);
  padding: clamp(70px, 9vw, 130px) var(--pad-x);
}
.cta-band:has(.site-footer) { padding-bottom: 40px; }
.cta-band-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: clamp(26px, 4vw, 60px);
  flex-wrap: wrap;
}
.cta-band-kicker {
  font-size: 12px; font-weight: 600; letter-spacing: .3em; text-transform: uppercase;
  color: var(--cyan);
  margin-bottom: 16px;
}
.cta-band h2 {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(44px, 6.4vw, 104px);
  line-height: .98; letter-spacing: -.02em; text-transform: uppercase;
  color: #fff;
}
.cta-band-mail { margin-top: 22px; font-size: 14px; color: var(--muted-on-navy); }
.cta-band-mail a { color: var(--text-on-navy); box-shadow: inset 0 -1px var(--cyan); padding-bottom: 2px; }
.cta-band-mail a:hover { color: var(--cyan); }

/* ==========================================================================
   9 · FOTOGRAFÍA EN SECCIÓN — banco de /assets/services (ver docs/FOTOGRAFIA.md)
   Dos únicos contenedores, ambos radius 0 + filete, sin sombras ni filtros CSS
   (el duotono/papel viene cocido en el fichero).

   .section-spread  cabecera de sección + foto a su derecha, unidas por la
                    línea de base (align-items:end, mismo idioma que
                    .service-panel de system.css). Llena la columna derecha
                    vacía que dejan .services-intro / .experience-header.
   .section-band    franja horizontal bajo una cabecera; solo para los recortes
                    -desk- (3:1 / 2:1), capada a su ancho nominal para no
                    ablandarlos.
   El fondo lo manda el filete: --line-ink sobre papel, --line-paper sobre navy.
   ========================================================================== */
.section-spread {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .58fr);
  gap: clamp(26px, 4vw, 64px);
  align-items: end;
  margin-bottom: clamp(50px, 7vw, 100px);
}
.section-spread > .services-intro,
.section-spread > .experience-header { margin-bottom: 0; }
/* .experience-section no tiene padding lateral: lo llevan sus hijos. */
.section-spread--pad { padding-inline: var(--pad-x); }
.section-spread--pad > .experience-header { padding-inline: 0; }

.section-photo,
.section-band {
  display: block; margin: 0;
  overflow: clip;                    /* recorta el zoom 1.15→1 del <picture> */
  border: 1px solid var(--line-ink);
  background: var(--paper-2);
}
.section-photo picture,
.section-band picture { display: block; }
.section-photo img,
.section-band img { display: block; width: 100%; height: auto; }

.section-photo--navy,
.section-band--navy { border-color: var(--line-paper); background: var(--navy-2); }

.section-band {
  max-width: 900px;                  /* nunca por encima del ancho nominal */
  margin-bottom: clamp(52px, 7vw, 100px);
}
/* El tope de arriba es el de `web-desk-900`. Los recortes de 800 px de ancho
   (strategy-desk-800) se capan a su propio nominal: por encima se ablandan
   (docs/FOTOGRAFIA.md, "Qué NO hacer"). */
.section-band--800 { max-width: 800px; }
/* Pegada a su cabecera (es pie del titular, no un bloque suelto): se descuenta
   el margin-bottom de .services-intro y se deja una calle corta. */
.services-intro + .section-band { margin-top: calc(clamp(20px, 3vw, 44px) - clamp(50px, 7vw, 100px)); }

/* ==========================================================================
   RESPONSIVE (mismos cortes que system.css: 1080 / 860 / 560)
   ========================================================================== */
@media (max-width: 1080px) {
  .industry-block { grid-template-columns: 1fr; }
  .industry-case { width: 100%; }
  /* La foto pasa debajo de la cabecera (ese es el orden del DOM) y se capa
     para que no se coma la pantalla al apilar. */
  .section-spread { grid-template-columns: 1fr; gap: clamp(30px, 5vw, 46px); }
  .section-photo { max-width: 560px; }
}

@media (max-width: 860px) {
  .page-hero { min-height: clamp(440px, 58svh, 640px); }
  .step-flow-rail { left: 22px; }
  .step-flow-item { grid-template-columns: 58px 1fr; }
  .step-flow-num { font-size: 21px; padding: 6px 0 10px; }
  .cta-band h2 { font-size: clamp(40px, 11vw, 64px); }
}

@media (max-width: 560px) {
  .page-hero h1 { font-size: clamp(38px, 11.4vw, 52px); }
  /* system.css colapsa TODO .nav-cta a solo-icono en móvil (pensado para el
     nav). Los CTA dentro de la página conservan su etiqueta. */
  .page-hero-cta .nav-cta span,
  .price-cta span,
  .cta-band .nav-cta span { display: inline; }
  .page-hero-cta .nav-cta,
  .price-cta,
  .cta-band .nav-cta { padding: 13px 20px; }
  .page-hero--paper .outline-line { -webkit-text-stroke-width: 1.5px; }
  .client-strip { gap: 16px 26px; padding-inline: 22px; }
  .cs-mark { font-size: 15px; }
  .client-strip-track { gap: 26px; padding-left: 26px; }
  .industry-case .cs-mark { font-size: 16px; }
  .price-amount b { font-size: 34px; }
}

/* ==========================================================================
   MOVIMIENTO REDUCIDO — todo estático y visible
   (el riel del .step-flow ya queda dibujado: su estado natural es clip 0;
   motion.js ni siquiera arranca con reduced-motion)
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .client-strip-track { animation: none; }
  .faq-system .faq-answer { transition: none; }
  .faq-system .faq-item button::after { transition: none; }
  .text-link, .faq-system .faq-item button { transition: none; }
}

/* ==========================================================================
   12 · ZONA SERVICIOS — aplicación de la fundación (motor v2 + arte + iconos)
   Capa ADITIVA: no redefine ningún componente anterior, solo añade las tres
   piezas nuevas que la zona necesita. Todo lo que se mueve son transform /
   stroke-dashoffset, y todo tiene su estado natural completo y visible.
   ========================================================================== */

/* --- 12.1 · MARCA DEL HERO ------------------------------------------------
   El hero interior deja media pantalla vacía a la derecha en escritorio: ahí
   va el icono del servicio como filigrana, y se dibuja solo al cargar
   (data-draw="enter"). Va a z-index:-1 dentro del `isolation:isolate` del
   propio hero, así que SIEMPRE queda por detrás del titular pase lo que pase
   con la longitud del texto en ES. Alfa .13 sobre navy: no hay texto encima,
   pero se mantiene en el orden de magnitud del techo de marca de backdrops.
   Por debajo de 900px el hero es todo columna de texto y la filigrana estorba:
   desaparece. -------------------------------------------------------------- */
.hero-mark {
  position: absolute; z-index: -1;
  right: clamp(20px, 5vw, 96px);
  top: 50%;
  translate: 0 -46%;
  width: clamp(210px, 25vw, 340px);
  color: rgb(233 238 243 / .13);
  pointer-events: none;
}
.hero-mark svg {
  display: block; width: 100%; height: auto;
  overflow: visible;
  stroke-width: .34;            /* 24 de viewBox × ~13 de escala ≈ 4.5px reales */
}
.hero-mark .ic-accent { fill: rgb(6 214 221 / .20); stroke: none; }
.hero-mark .ic-dot { fill: currentColor; stroke: none; }
.page-hero--paper .hero-mark { color: rgb(10 26 47 / .10); }

/* --- 12.2 · ESCENA ILUSTRADA EN UNA CABECERA DE SECCIÓN --------------------
   Ocupa la columna derecha vacía que deja .services-intro, exactamente donde
   vive .section-photo (mismo .section-spread). Sin filete: es dibujo de línea
   sobre papel, no una lámina; encajonarlo lo convertiría en un diagrama. */
.svc-scene { margin: 0; color: var(--ink); }
.svc-scene .art-scene { width: 100%; height: auto; }

/* --- 12.3 · RIEL DEL STEP-FLOW DIBUJADO CON EL MOTOR v2 --------------------
   Antes: <i data-scrub="clip:100,0"> con ventana fija de viewport, que dejaba
   el riel completo mucho antes de que llegara el último paso. Ahora una <line>
   con data-draw="scrub" y un rango que cubre TODO el alto del flujo, así el
   trazo y los pasos avanzan juntos. viewBox 2×1000 con preserveAspectRatio
   "none": la escala en X es exactamente 1, así que el grosor del trazo sigue
   siendo 2px reales y el dasharray (unidades de usuario) casa con la altura.
   Sin JS o con movimiento reducido el motor no escribe nada: línea entera. */
.step-flow-rail svg {
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
  overflow: visible;
}
.step-flow-rail line { stroke: var(--cyan); stroke-width: 2; }
.step-flow--dark .step-flow-rail line { stroke: var(--cyan); }

@media (max-width: 1080px) {
  .svc-scene { max-width: 560px; }
}
@media (max-width: 900px) {
  .hero-mark { display: none; }
}

/* Movimiento reducido: motion2.js ni arranca, así que el riel y la escena ya
   quedan completos. Lo único que hay que neutralizar es el desplazamiento de
   las capas por si el motor se apagara a media sesión. */
@media (prefers-reduced-motion: reduce) {
  [data-parallax-scene] [data-layer] { transform: none !important; }
}

/* La flecha del .service-number pasa a icono del sprite (misma familia que la
   rejilla del hub). El <i> conserva su tamaño y su color cian de system.css:
   el icono solo hereda. */
.service-number .ic { --ic-size: 18px; display: block; vertical-align: baseline; }

/* ==========================================================================
   13 · ZONA INDUSTRIAS Y SISTEMAS — aplicación de la fundación
   (industries · systems · mind-os · apps/*)
   Capa ADITIVA, como la §12: no redefine ningún componente anterior. Todo lo
   que se mueve es transform / opacity / stroke-dashoffset, y todo tiene su
   estado natural COMPLETO y visible (sin JS, sin motor o con movimiento
   reducido no falta ni un trazo).
   ========================================================================== */

/* --- 13.0 · LA FILIGRANA DEL HERO, ANCLADA ABAJO --------------------------
   En /services el titular cabe en la mitad izquierda y la filigrana de §12.1
   puede vivir centrada a la derecha. En esta zona no: los titulares son
   largos ("MORE WAYS TO CONNECT.", "EVERY PART CONNECTED.") y su segunda
   línea va en versalita PERFILADA — hueca —, así que la filigrana se veía
   POR DENTRO de las letras y ensuciaba el remate. El hueco real de estos
   heroes está abajo a la derecha, junto a la línea de disponibilidad.
   Solo cambia el anclaje vertical: tamaño, alfa y z-index siguen siendo los
   de §12.1, y por debajo de 900px sigue desapareciendo con ella. ---------- */
.hero-mark--low {
  top: auto;
  bottom: clamp(12px, 6vh, 72px);
  translate: 0 0;
  /* Más pequeña que la de §12.1: el hueco de abajo mide ~290px de alto en un
     hero de 700, y una filigrana de 340 volvería a morder el titular. */
  width: clamp(150px, 17vw, 240px);
}

/* --- 13.1 · MARCA DE INDUSTRIA EN EL KICKER -------------------------------
   Cada bloque de /industries abre con su icono junto al número. El icono es
   DECORATIVO puro: la etiqueta de al lado ya dice lo mismo, así que va con
   <use> (barato, sin shadow-DOM que animar) y aria-hidden.
   Hereda el color del kicker (tinta-suave), nunca el cian del número: dos
   acentos cian pegados se anularían. El acento del propio icono aporta el
   único punto de color de la fila. -------------------------------------- */
.ind-ic {
  --ic-size: 26px;
  flex: none;
  color: var(--ink);
}
.industry-head .section-kicker { gap: 12px; }

/* --- 13.2 · CONEXIONES DIBUJADAS DEL .system-board ------------------------
   El conector de los tableros era un <span> de 1px pintado con background:
   imposible de dibujar. Ahora hospeda una <line> SVG que el motor v2 traza
   con data-draw="scrub", sincronizada con la aparición de los nodos vecinos.

   viewBox 0 0 100 2 + preserveAspectRatio="none": la caja del conector es
   elástica (flex:1) y de 1px de alto, así que la escala es NO uniforme —
   escala-x variable, escala-y fija en 0.5 (1px de caja ÷ 2 de viewBox).
   Eso es justo lo que hace falta: el GROSOR de una línea horizontal solo
   depende de la escala-y, así que `stroke-width: 2` mide siempre 1px real
   mida lo que mida el hueco; y el DASHARRAY corre a lo largo de la x, así
   que las 100 unidades que devuelve getTotalLength() tapan exactamente el
   ancho, sea cual sea.
   AVISO: aquí NO se puede usar vector-effect: non-scaling-stroke. Resuelve
   el trazo en espacio de pantalla y arrastra consigo el patrón de guiones:
   el dasharray de 100 pasaría a valer 100 px y la línea se dibujaría
   troceada en vez de entera (medido: 3-4 segmentos por conector).

   El fondo original se apaga SOLO en la variante --draw: el resto de los
   tableros del sitio siguen intactos. ----------------------------------- */
.flow-line--draw { background: none; }
.flow-line--draw > svg {
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
  overflow: visible;
}
.flow-line--draw > svg line {
  stroke: rgb(6 214 221 / .45);
  stroke-width: 2;              /* × escala-y 0.5 = 1px real, como el original */
}
/* La punta de flecha del conector (::after de system.css) existe para dar
   DIRECCIÓN a una línea quieta. Cuando el motor está montado la dirección ya
   la da el propio trazado —de izquierda a derecha— y la punta se adelantaba:
   quedaba un triangulito cian flotando sobre el hueco vacío hasta que la
   línea lo alcanzaba. Se retira solo bajo html.mm-motion2; sin JS o con
   movimiento reducido la línea está entera y la flecha sigue en su sitio. */
.mm-motion2 .flow-line--draw::after { display: none; }

/* --- 13.3 · ICONO DE PRODUCTO EN LAS LISTAS DE CAPACIDADES ----------------
   Los chips de .service-detail (y los de .industry-services) son etiquetas de
   una sola línea: el icono entra a 18px, antes del texto, con el hueco
   proporcional al cuerpo. El chip mantiene su filete y su padding: solo
   cambia el display para poder alinear icono y texto por su eje óptico. */
.service-detail li.cap-chip {
  display: inline-flex;
  align-items: center;
  gap: .55em;
}
.cap-chip .ic { --ic-size: 18px; flex: none; color: var(--ink-soft); }

/* --- 13.4 · ICONO DE CAPACIDAD EN EL STEP-FLOW (apps) ---------------------
   En /apps cada paso del flujo es una capacidad del producto. El icono va
   sobre el titular, no dentro: así la columna de texto conserva su ritmo y el
   icono lee como marca de la capacidad. */
.sf-ic { --ic-size: 30px; display: block; color: var(--ink-soft); margin-bottom: 2px; }
.step-flow--dark .sf-ic { color: var(--muted-on-navy); }

/* --- 13.5 · CIERRE DE /industries: EL SKYLINE QUE SE DIBUJA ---------------
   Pieza de cierre de la página, antes de la tira de clientes: Miami dibujado
   trazo a trazo con el scroll. Sin copy — es una lámina, no una sección: por
   eso todo el bloque va aria-hidden y no aparece en el índice del documento.
   Ancho acotado a 940px: a sangre completa en 1440 la escena 8:5 mediría casi
   900px de alto y se comería la caída hacia el cierre. -------------------- */
.ind-skyline { padding: clamp(22px, 3.4vw, 54px) var(--pad-x) clamp(26px, 3.4vw, 52px); }
.ind-skyline-art {
  margin: 0 auto;
  max-width: 980px;
  color: var(--text-on-navy);
}
/* En móvil el dibujo ya es pequeño: se le devuelve el aire lateral del
   padding de página para que el skyline no quede en miniatura. */
@media (max-width: 700px) {
  .ind-skyline { padding-inline: clamp(8px, 3vw, 18px); }
}
.ind-skyline-art .art-scene { width: 100%; height: auto; overflow: visible; }

/* --- 13.6 · BANDA DE CIRCUITO DEL ECOSISTEMA (systems · mind-os) ----------
   El fondo bd-circuit pertenece al DIAGRAMA, no a la sección entera: las
   secciones de arquitectura miden más de 2000px (cabecera + escena + mapa +
   cuatro pasos) y un campo de trazas a toda esa altura deja de ser textura
   para volverse ruido justo bajo el cuerpo de texto a 15px.

   Por eso el .bd-scene NO va en el <section> sino en un envoltorio que abarca
   solo la banda del diagrama. Los márgenes negativos lo devuelven al ancho
   completo de página (el <section> ya lleva su padding lateral), así que el
   circuito sigue leyéndose como campo de fondo y no como un panel recortado.

   Reutiliza .svc-scene (§12.2) para la escena dentro del .section-spread. */
.sys-circuit {
  margin-inline: calc(-1 * var(--pad-x));
  padding-inline: var(--pad-x);
}
.experience-section .svc-scene,
.svc-scene--light { color: var(--text-on-navy); }

/* --- 13.7 · EL PLANO DE PARALLAX DE LAS ESCENAS ---------------------------
   MEDIDO (Performance.getMetrics, ventana de scroll aislada tras una vuelta
   de calentamiento, 1440×900):

     escena con data-layer en los <g> DENTRO del SVG ... 14 layouts / pasada
     misma escena con el parallax en un <div> HTML ....  0 layouts / pasada

   El motivo es de motor de render, no del motor de scroll: en Blink el SVG
   tiene su propio árbol de layout y escribir `transform` en un <g> lo obliga
   a recalcular la geometría del subárbol; ni will-change ni contain lo evitan
   (probados: 15 y 16 layouts). En un elemento HTML el mismo transform es
   compositor puro. Así que el parallax de estas escenas vive en un PLANO
   HTML que envuelve al <svg>: una sola deriva contra la página en lugar de
   tres capas independientes. A esta amplitud (34px sobre un dibujo de línea)
   la diferencia perceptiva es mínima y el coste baja a cero.

   Las capas del sprite siguen ahí como <g> y siguen contando: data-draw las
   traza en orden de fondo a primer plano con data-draw-spread.

   MIGRADO (verificación de rendimiento): las 11 páginas de /services todavía
   llevaban el parallax en los <g> y pagaban el peaje. Ahora las 11 usan el
   mismo plano HTML que el resto:

     <figure class="svc-scene reveal" data-parallax-scene>
       <div class="art-plane" data-layer="0.06" data-layer-max="34">
         <svg class="art-scene" data-draw="scrub"> <g>…</g> ×3 </svg>

   Layouts por pasada de scroll, antes → después: social-media 5→0 ·
   seo-local-search 6→0 · growth-consulting 7→0 · web-design 8→0. El dibujo
   (data-draw) no se toca: sigue en el <svg> y las 14 geometrías se trazan
   igual. Solo desaparecieron los data-layer/-max de los tres <g>.

   NOTA: en /about los <g> llevan data-layer="1|2|3", que NO son factores de
   parallax sino los índices de profundidad que trae el sprite scenes.svg.
   Ahí no hay data-parallax-scene, así que motion2 nunca los registra: son
   inertes y no cuestan nada. Se dejan como están.
   ------------------------------------------------------------------------- */
.art-plane { display: block; }

/* --- 13.8 · MOVIMIENTO REDUCIDO ------------------------------------------
   motion2.js no arranca con reduced-motion, así que trazos y capas ya quedan
   completos; esto solo cubre el caso de que el usuario lo active en vivo. */
@media (prefers-reduced-motion: reduce) {
  .flow-line--draw > svg line {
    stroke-dasharray: none !important;
    stroke-dashoffset: 0 !important;
  }
  .art-plane { transform: none !important; }
}

/* ==========================================================================
   14 · FONDO CON MÁSCARA + PARALLAX — corrección de rasterizado
   --------------------------------------------------------------------------
   PROBLEMA MEDIDO. Un `.bd` que lleva máscara (`.bd-fade-y`) y además tiene
   planos que se mueven (`data-layer`) repinta el dibujo ENTERO en cada paso
   del parallax. La máscara obliga a rasterizar todo el subárbol en un único
   destino, así que los planos dejan de componerse por separado: el
   `will-change: transform` que ya traen no sirve de nada, porque el trabajo
   no está en la capa sino en el destino de la máscara.

   MEDIDO (scroll continuo de 3 s, 1440×900, p95 de frame / frames > 20 ms):

                        antes            después
     /insights  ondas   33.3 ms / 9      16.7 ms / 0
     /work      puntos  16.8 ms / 6      16.8 ms / 0
     /careers   puntos  16.8 ms / 8      16.7 ms / 0
     /community puntos  16.8 ms / 8      16.8 ms / 0

   /insights era el único que rompía el listón de p95 porque `bd-waves` son
   20 + 10 curvas largas trazadas sobre 1660×1149: el repintado más caro del
   sistema. En los tres de puntos el mismo fallo solo se veía en la cola
   (frames sueltos de 50 ms), pero es exactamente el mismo mecanismo.

   ARREGLO. La máscara baja del contenedor a cada plano. Geometría idéntica
   (los planos son `inset: 0` del `.bd`, y `--bd-fade` se hereda), pero ahora
   cada plano vuelve a ser una capa compuesta independiente y el parallax es
   de nuevo compositor puro. El degradado viaja con su plano; a la amplitud
   real (`data-layer-max` ≤ 80 px sobre una banda de desvanecido de ~184 px
   al 5-9 % de alfa) el desplazamiento no es perceptible — comprobado a 1440
   y 390.

   El `:has()` es la condición exacta: solo actúa cuando hay máscara Y hay
   planos en movimiento. Un fondo con máscara y quieto no paga nada y se
   queda como está.
   ------------------------------------------------------------------------- */
.bd-fade-y:has(> [data-layer]) { -webkit-mask-image: none; mask-image: none; }
.bd-fade-y:has(> [data-layer]) > .bd-i,
.bd-fade-y:has(> [data-layer]) > .bd-i2,
.bd-fade-y:has(> [data-layer]) > .bd-i3 {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--bd-fade), #000 calc(100% - var(--bd-fade)), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 var(--bd-fade), #000 calc(100% - var(--bd-fade)), transparent 100%);
}

/* ==========================================================================
   14 · CORRECCIONES DE DIRECCIÓN DE ARTE (pase de revisión nivel 2)
   Tres arreglos de LEGIBILIDAD sobre la aplicación de la fundación. Todo
   aditivo: ni un token nuevo, ni una palabra de copy tocada.
   ========================================================================== */

/* --- 14.1 · EL CIRCUITO NO PASA POR ENCIMA DEL TEXTO (systems · mind-os) ---
   Medido: sobre papel las trazas de bd-circuit llegan a 1.4-1.6 de contraste
   contra el papel — cuatro veces la tinta de bd-dots (1.03-1.07), que es la
   referencia que SÍ funciona en el sitio. A esa fuerza una traza de 1px deja
   de ser textura y se lee como un tachón cruzando el titular y el párrafo:
   en /mind-os §04 y /systems §03 las trazas cortaban «See your whole
   operation.» y «Each application owns a clear job…» a 1440 y a 390.

   ARREGLO. No se baja la alfa —eso mataría el motivo, que en las páginas de
   producto es el correcto— sino que se cambia la máscara: bd-fade-y (que
   solo desvanece arriba y abajo) se sustituye por el vaciado elíptico que la
   propia cabecera de backdrops.css recomienda como primera opción. El dibujo
   se conserva entero en los márgenes, donde acompaña al diagrama, y sale de
   la columna de texto. Elipse desplazada a 42% porque en ambas páginas la
   copia vive en la mitad izquierda y la escena en la derecha.
   ------------------------------------------------------------------------- */
.bd-circuit.bd-on-paper.bd-fade-y {
  -webkit-mask-image: radial-gradient(ellipse 62% 78% at 42% 50%, transparent 0%, rgb(0 0 0 / .14) 48%, #000 90%);
          mask-image: radial-gradient(ellipse 62% 78% at 42% 50%, transparent 0%, rgb(0 0 0 / .14) 48%, #000 90%);
}
/* Bajo 900px la copia ocupa el ancho entero: el vaciado se centra y se abre,
   porque ya no hay «columna izquierda» que proteger sino toda la plana. */
@media (max-width: 900px) {
  .bd-circuit.bd-on-paper.bd-fade-y {
    -webkit-mask-image: radial-gradient(ellipse 86% 74% at 50% 50%, transparent 0%, rgb(0 0 0 / .12) 52%, #000 94%);
            mask-image: radial-gradient(ellipse 86% 74% at 50% 50%, transparent 0%, rgb(0 0 0 / .12) 52%, #000 94%);
  }
}

/* --- 14.2 · EL SKYLINE DE CIERRE DE /industries, A ESCALA DE LÁMINA -------
   A 980px la escena 8:5 medía 960×530 y ocupaba una banda navy de casi 700px
   ella sola: a ese tamaño el trazo fino se estira y el sol cian se convierte
   en una mancha plana que pesa más que el dibujo entero. La misma lámina en
   /about §06 mide ~600px, va integrada en un spread editorial y se lee mucho
   mejor — esa es la referencia. Se baja a 760px: sigue siendo el cierre de la
   página, deja de ser una valla publicitaria. -------------------------------- */
.ind-skyline-art { max-width: 760px; }

/* ==========================================================================
   15 · .site-progress — BARRA FANTASMA DE main.js (neutralizada)
   --------------------------------------------------------------------------
   main.js crea al vuelo un <div class="site-progress"> y en CADA evento de
   scroll le escribe `style.width`. Su hoja de estilo es css/site.css, que
   ya NO la carga ninguna página del sitio: el nodo queda sin estilo, en
   flujo normal al final del <body>, con altura 0 y fondo transparente. Es
   invisible — pero `width` es una propiedad de LAYOUT, así que cada escritura
   ensucia el layout del documento y la lectura de `scrollHeight` que hace la
   propia función lo obliga a recalcularse de forma síncrona. Un layout
   forzado por frame, todo el scroll, para pintar nada.

   Solo la ven las 3 páginas que cargan main.js — /insights, /work y /contact
   — y en las tres la barra de lectura REAL es .page-progress (system.css),
   que ya hace el mismo trabajo con `transform: scaleX()`, sin tocar layout.
   Así que esto no esconde una función: quita un duplicado muerto.

   MEDIDO (layouts provocados por una pasada de scroll, tras calentamiento):

                  antes   después
     /insights     193       0
     /work         193       0
     /contact      193       0

   Probado también `contain: strict` sobre el nodo: no sirve (193 layouts
   igual). La escritura de `width` invalida el layout del documento aunque el
   elemento esté contenido; lo único que lo corta es sacarlo del árbol de
   cajas. main.js es intocable en esta fase, así que el arreglo vive aquí.
   Si algún día vuelve css/site.css, basta con borrar esta regla.
   ------------------------------------------------------------------------- */
.site-progress { display: none; }
