/* ─── Fuentes locales ─────────────────────────────────────────────────────── */
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/InterVariable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../assets/fonts/JetBrainsMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ─── Tokens — copiar íntegro según BALAM-DESIGN-SYSTEM.md §2 ─────────────── */
:root {
  /* Fase 4 (color, 2026-10-02): el fondo general baja un paso (#e6eaf0 ->
     #e1e6ed) para separar el plano de las tarjetas (--surface sigue igual).
     Paso corto a propósito: más oscuro obligaría a oscurecer --text-faint
     hasta igualarlo con --text-soft y se perdería la jerarquía. */
  --bg:            #e1e6ed;
  --surface:       #e6eaf0;
  --surface-alt:   #eceff5;
  --sh-dark:       rgba(160,174,196,.60);
  --sh-light:      rgba(255,255,255,.92);

  --text:          #38414f;
  /* Fase 4: --text-soft (3.71:1) y --text-faint (2.14:1) no llegaban al 4.5:1
     de AA sobre la tarjeta. Oscurecidos y medidos contra el fondo MÁS oscuro
     donde aparecen (--bg): ver la tabla @contraste al final de :root. */
  --text-soft:     #535d6a;
  --text-faint:    #5c6672;

  /* Fase 4: --accent como texto daba 3.36:1 y el blanco sobre el badge de
     grado A 4.06:1. Mismo tono (teal, el del grado), un paso más oscuro. */
  --accent:        #176673;
  --accent-soft:   rgba(31,138,156,.14);
  --on-accent:     #ffffff;  /* texto/ícono sobre fondo --accent */
  --danger:        #c2565a;
  --ok:            #3f9070;
  --ok-soft:       rgba(63,144,112,.16);
  --muted:         #8679c6;  /* Fase 9: era #8b7ec8 (2.94:1); mínimo para 3:1 como gráfico sobre --bg y --surface */
  --muted-soft:    rgba(139,126,200,.16);

  /* ── Tintas de texto sobre fondos "-soft" (Fase 4, B6 — contraste AA) ──
     Los tonos base (--accent, --ok, --muted, --danger) están calibrados
     para usarse sobre el fondo de la tarjeta, NO sobre su propio fondo
     "-soft": ahí el fondo se aclara y el mismo texto se queda entre 2.2:1
     y 3.9:1, por debajo del 4.5:1 que WCAG AA exige para texto pequeño
     (los badges son de 10-11px). Estos tokens son la versión "tinta" del
     mismo tono, oscurecida lo justo para cruzar el umbral CON MARGEN
     (objetivo 4.6:1, medido, no estimado; ver la tabla de medición en
     ESTADO-PROYECTO.md § B6).

     Se usan SOLO como color de texto sobre el fondo "-soft" del mismo
     color. Nunca como fondo, nunca sobre --surface: ahí el tono base
     sigue siendo el correcto y cambiarlo apagaría el acento del sistema.

     En tema oscuro los tonos base YA pasan AA sobre sus fondos "-soft"
     (medidos entre 4.76:1 y 5.81:1), así que ahí estos tokens valen el
     tono base sin cambio — la única excepción es --faint-ink. */
  --accent-ink:    #176673;  /* 4.70:1 sobre accent-soft  */
  --ok-ink:        #2d6851;  /* 4.61:1 sobre ok-soft      */
  --muted-ink:     #60578a;  /* 4.65:1 sobre muted-soft   */
  --danger-ink:    #9b4548;  /* 4.63:1 sobre danger-soft  */
  --soft-ink:      #626c7a;  /* 4.62:1 sobre surface-alt  */
  --faint-ink:     #646b75;  /* 4.67:1 sobre surface-alt  */
  --danger-soft:   rgba(194,86,90,.10);

  /* Corona de líder (Fase 8, tarea A). El ámbar es el que el proyecto ya
     usa para el grado B en los PDF (radar/reporte.py::_CMED), para no
     meter un color nuevo al sistema. La tinta se oscurece en claro hasta
     cruzar AA con margen; en oscuro el tono base ya pasa y se deja tal cual.
     Medido con la fórmula WCAG, no estimado:
        claro   #7d5b11 sobre #e6decb = 4.64:1
        oscuro  #e8a820 sobre #413825 = 5.53:1
     El ícono de la corona también cumple 1.4.11 (3:1) en los dos temas con
     esos mismos pares. */
  --corona-soft:   rgba(232,168,32,.18);
  --corona-ink:    #7d5b11;

  /* Separador (Fase 4, B6). Antes era un gris fijo rgba(128,128,128,.1)
     para los dos temas: en oscuro daba 1.13:1 contra el fondo de la
     tarjeta — prácticamente invisible. Ahora es un token por tema. */
  --sep-line:      rgba(0,0,0,.10);

  --border-subtle:      rgba(31,138,156,.55);
  --border-line:        #4d9bae; /* acento #1f8a9c mezclado ~62 % con fondo #e6eaf0; opaco */
  --divider-highlight:  rgba(255,255,255,.70); /* luz superior del surco neumórfico */
  --glass-bg:      rgba(255,255,255,.42);
  --glass-brd:     rgba(255,255,255,.65);
  --glass-blur:    blur(20px) saturate(180%);

  /* ── Barra de navegación y franja del nombre (Fase 4, color) ──────────
     Fondo oscuro sólido (azul marino) en la píldora .navbar y en
     .site-header a todo lo ancho. Solo color: el layout no cambia. Las
     sombras neumórficas (luz blanca arriba-izquierda) no funcionan sobre
     oscuro; aquí la profundidad la da una sombra difusa (--nav-sombra). */
  --nav-bg:          #1f2a44;
  --nav-brd:         rgba(255,255,255,.08);
  --nav-text:        #e8edf6;
  --nav-text-soft:   #b3bdd1;
  --nav-ind:         rgba(255,255,255,.10);   /* indicador del ítem activo y botones */
  --nav-focus:       #e8edf6;                 /* contorno de foco sobre --nav-bg */
  --nav-sombra:      0 10px 34px rgba(10,16,28,.28);
  /* Texto del ítem activo, uno por sección, sobre --nav-ind/--nav-bg. */
  --nav-acc-radar:          #9dbcff;
  --nav-acc-noticias:       #f2a6c6;
  --nav-acc-oportunidades:  #b8dc7a;

  /* ── Acento por sección (Fase 4) ──────────────────────────────────────
     Franja de 3 px en el encabezado de sección (.subnav), en la pestaña
     activa y en el borde superior de las tarjetas. Tonos elegidos LEJOS de
     los que ya tienen significado: teal del grado A/B (189°), verde ok
     (156°), ámbar de corona/cotizando (38-41°), rojo danger (358°) y
     violeta muted (251°). Si un acento chocara con un grado, gana el grado.
     --sec-*: la franja (gráfico, 3:1). --sec-*-ink: el texto (4.5:1). */
  --sec-radar:              #3566cc;   /* azul, 221° */
  --sec-radar-ink:          #2c56b0;
  --sec-noticias:           #b44674;   /* frambuesa, 335° */
  --sec-noticias-ink:       #9c3a63;
  --sec-oportunidades:      #4f7a14;   /* oliva, 85° */
  --sec-oportunidades-ink:  #3e6610;

  /* ── Colores que antes iban sueltos en los componentes (Fase 4) ──────
     Mismo valor que tenían: pasar a token no cambia lo que se ve. */
  --linea-tenue:        rgba(0,0,0,.06);
  --borde-boton:        rgba(0,0,0,.12);
  --borde-filtros:      rgba(128,128,128,.1);
  --velo-panel:         rgba(0,0,0,.55);
  --velo-panel-claro:   rgba(20,28,40,.18);
  --velo-modal:         rgba(20,28,40,.30);
  --sombra-modal:       0 24px 64px rgba(10,16,28,.35);
  --sombra-toast:       0 8px 26px rgba(20,28,40,.18);
  --sombra-acento:      0 2px 8px rgba(31,138,156,.3);
  --sombra-acento-hover: 0 4px 14px rgba(31,138,156,.4);
  --danger-tenue:       rgba(194,86,90,.08);
  --negro:              #000;                 /* solo para color-mix() del degradado de .btn--accent */
  /* Puntos de estatus del pizarrón. --estatus-contactado conserva el teal
     anterior a la Fase 4 a propósito: es un gráfico (3:1, no texto) y el PDF
     del pizarrón (jsPDF, en el navegador) lee este color. */
  --estatus-contactado: #1f8a9c;
  --estatus-cotizando:  #f59e0b;

  /* Sectores (2026-10-22, catálogo único radar/taxonomia.py::SECTORES).
     Son GRÁFICOS (muestra junto a la etiqueta escrita y rebanadas del
     pastel del PDF del pizarrón): 3:1 sobre --surface, --bg y
     --surface-alt en los dos temas. La etiqueta, no el color, identifica
     el sector. */
  --sector-industrial:      #8a5a00;
  --sector-hoteles:         #b0407a;
  --sector-hospitales:      #b8474c;
  --sector-infraestructura: #176673;
  --sector-datacenter:      #3566cc;
  --sector-residencial:     #4f7a14;
  --sector-corporativo:     #6f4cc0;

  /* ── Colores del PDF del pizarrón (jsPDF, Fase 4) ─────────────────────
     "Los PDF no cambian de color": el PDF que se genera en el navegador
     resolvía --accent/--text*/--surface en tiempo de ejecución, así que el
     cambio de paleta de arriba lo habría recoloreado. Lee estos, con los
     valores de antes de la Fase 4 (y los del tema oscuro en su bloque). */
  --pdf-accent:      #1f8a9c;
  --pdf-text:        #38414f;
  --pdf-text-soft:   #6d7887;
  --pdf-text-faint:  #98a2b1;
  --pdf-surface:     #e6eaf0;

  --r-sm: 12px; --r-md: 18px; --r-lg: 28px; --r-pill: 999px;

  --d: 6px;
  --b: 14px;
  --neu-out:    var(--d) var(--d) var(--b) var(--sh-dark),
                calc(var(--d) * -1) calc(var(--d) * -1) var(--b) var(--sh-light);
  --neu-out-sm: 3px 3px 7px var(--sh-dark), -3px -3px 7px var(--sh-light);
  --neu-in:     inset 5px 5px 10px var(--sh-dark),
                inset -5px -5px 10px var(--sh-light);
  --neu-in-sm:  inset 3px 3px 6px var(--sh-dark), inset -3px -3px 6px var(--sh-light);

  --ease:   cubic-bezier(.2,.8,.2,1);
  --t:      .4s var(--ease);
  --t-fast: .22s var(--ease);
  --bounce: cubic-bezier(.34,1.56,.64,1);

  --sp-1: 6px; --sp-2: 12px; --sp-3: 18px;
  --sp-4: 26px; --sp-5: 40px; --sp-6: 64px;

  --font: "Inter","SF Pro Text",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --mono: "JetBrains Mono","SF Mono",ui-monospace,Menlo,Consolas,monospace;
}

[data-theme="dark"] {
  --bg:          #1c2026;
  --surface:     #1c2026;
  --surface-alt: #222730;
  --sh-dark:     rgba(0,0,0,.62);
  --sh-light:    rgba(255,255,255,.055);
  --text:        #d6dce5;
  --text-soft:   #97a1ae;
  --text-faint:  #87919f;   /* Fase 4: era #6b7683, 3.54:1 sobre --bg */
  --accent:      #46c2d3;
  --accent-soft: rgba(70,194,211,.15);
  --on-accent:   #0f2429;   /* Fase 4: el blanco sobre #46c2d3 daba 2.12:1 */
  --danger:      #e07b7f;
  --ok:          #5cb894;
  --ok-soft:     rgba(92,184,148,.17);
  --muted:       #a899e0;
  --muted-soft:  rgba(168,153,224,.17);
  /* Tintas AA (Fase 4, B6): en oscuro los tonos base ya pasan sobre sus
     propios fondos "-soft" (accent 5.81:1, ok 4.99:1, muted 4.76:1,
     danger 4.93:1, soft 5.73:1 — medidos), así que la tinta ES el tono
     base. La excepción es --faint-ink: --text-faint sobre --surface-alt
     daba 3.24:1, el único badge que fallaba AA también en oscuro. */
  --accent-ink:  var(--accent);
  --ok-ink:      var(--ok);
  --muted-ink:   var(--muted);
  --danger-ink:  var(--danger);
  --soft-ink:    var(--text-soft);
  --faint-ink:   #8390a0;   /* 4.61:1 sobre surface-alt */
  --danger-soft: rgba(224,123,127,.10);
  /* Corona: en oscuro el ámbar base ya da 5.53:1 sobre su propio fondo
     suave, así que la tinta ES el tono base (ver nota en :root). */
  --corona-soft: rgba(232,168,32,.18);
  --corona-ink:  #e8a820;
  --sep-line:    rgba(255,255,255,.14);  /* 1.55:1 vs 1.13:1 del gris fijo */

  --border-subtle:      rgba(255,255,255,.30);
  --border-line:        #6b7f88; /* gris-azul claro, opaco */
  --divider-highlight:  rgba(255,255,255,.10); /* luz del surco neumórfico en oscuro */
  --glass-bg:    rgba(40,46,55,.55);
  --glass-brd:   rgba(255,255,255,.09);

  /* Fase 4: navegación y secciones en oscuro. --nav-bg un paso más claro que
     el fondo (#1c2026) para que la barra se distinga como plano propio. */
  --nav-bg:          #26304d;
  --sec-radar:              #7fa6f5;
  --sec-radar-ink:          #7fa6f5;
  --sec-noticias:           #e889b0;
  --sec-noticias-ink:       #e889b0;
  --sec-oportunidades:      #9cc65a;
  --sec-oportunidades-ink:  #9cc65a;
  --linea-tenue:     rgba(255,255,255,.08);
  --borde-boton:     rgba(255,255,255,.15);
  --estatus-contactado: #46c2d3;
  --sector-industrial:      #e0a84a;
  --sector-hoteles:         #e889b0;
  --sector-hospitales:      #f0898d;
  --sector-infraestructura: #46c2d3;
  --sector-datacenter:      #7fa6f5;
  --sector-residencial:     #9cc65a;
  --sector-corporativo:     #b79cf0;
  /* PDF del pizarrón: los valores oscuros de antes de la Fase 4. */
  --pdf-accent:      #46c2d3;
  --pdf-text:        #d6dce5;
  --pdf-text-soft:   #97a1ae;
  --pdf-text-faint:  #6b7683;
  --pdf-surface:     #1c2026;
}

/* ─── Pares de contraste declarados (Fase 4) ─────────────────────────────
   tests/test_contraste_balam.py lee CADA línea "@contraste" de este bloque,
   resuelve los tokens en los dos temas (:root y [data-theme="dark"]),
   compone los fondos con transparencia ("A sobre B") y falla si alguna
   razón WCAG queda por debajo del mínimo: 4.5 texto normal, 3 texto
   grande / ícono / gráfico. Un par nuevo de texto sobre fondo se declara
   aquí, no en el test.

   @contraste --text                 sobre --bg                         4.5
   @contraste --text                 sobre --surface                    4.5
   @contraste --text                 sobre --surface-alt                4.5
   @contraste --text-soft            sobre --bg                         4.5
   @contraste --text-soft            sobre --surface                    4.5
   @contraste --text-soft            sobre --surface-alt                4.5
   @contraste --text-faint           sobre --bg                         4.5
   @contraste --text-faint           sobre --surface                    4.5
   @contraste --text-faint           sobre --surface-alt                4.5
   @contraste --accent               sobre --bg                         4.5
   @contraste --accent               sobre --surface                    4.5
   @contraste --accent               sobre --surface-alt                4.5
   @contraste --on-accent            sobre --accent                     4.5
   @contraste --accent-ink           sobre --accent-soft sobre --surface 4.5
   @contraste --ok-ink               sobre --ok-soft sobre --surface    4.5
   @contraste --muted-ink            sobre --muted-soft sobre --surface 4.5
   @contraste --danger-ink           sobre --danger-soft sobre --surface 4.5
   @contraste --corona-ink           sobre --corona-soft sobre --surface 4.5
   @contraste --soft-ink             sobre --surface-alt                4.5
   @contraste --faint-ink            sobre --surface-alt                4.5
   @contraste --nav-text             sobre --nav-bg                     4.5
   @contraste --nav-text-soft        sobre --nav-bg                     4.5
   @contraste --nav-text             sobre --nav-ind sobre --nav-bg     4.5
   @contraste --nav-text-soft        sobre --nav-ind sobre --nav-bg     4.5
   @contraste --nav-acc-radar         sobre --nav-ind sobre --nav-bg    4.5
   @contraste --nav-acc-noticias      sobre --nav-ind sobre --nav-bg    4.5
   @contraste --nav-acc-oportunidades sobre --nav-ind sobre --nav-bg    4.5
   @contraste --nav-focus            sobre --nav-bg                     3
   @contraste --sec-radar-ink        sobre --surface                    4.5
   @contraste --sec-noticias-ink     sobre --surface                    4.5
   @contraste --sec-oportunidades-ink sobre --surface                   4.5
   @contraste --sec-radar            sobre --surface                    3
   @contraste --sec-noticias         sobre --surface                    3
   @contraste --sec-oportunidades    sobre --surface                    3
   @contraste --estatus-contactado   sobre --surface                    3
   @contraste --sector-industrial      sobre --surface                  3
   @contraste --sector-hoteles         sobre --surface                  3
   @contraste --sector-hospitales      sobre --surface                  3
   @contraste --sector-infraestructura sobre --surface                  3
   @contraste --sector-datacenter      sobre --surface                  3
   @contraste --sector-residencial     sobre --surface                  3
   @contraste --sector-corporativo     sobre --surface                  3
   @contraste --sector-industrial      sobre --bg                       3
   @contraste --sector-hoteles         sobre --bg                       3
   @contraste --sector-hospitales      sobre --bg                       3
   @contraste --sector-infraestructura sobre --bg                       3
   @contraste --sector-datacenter      sobre --bg                       3
   @contraste --sector-residencial     sobre --bg                       3
   @contraste --sector-corporativo     sobre --bg                       3
   @contraste --sector-industrial      sobre --surface-alt              3
   @contraste --sector-hoteles         sobre --surface-alt              3
   @contraste --sector-hospitales      sobre --surface-alt              3
   @contraste --sector-infraestructura sobre --surface-alt              3
   @contraste --sector-datacenter      sobre --surface-alt              3
   @contraste --sector-residencial     sobre --surface-alt              3
   @contraste --sector-corporativo     sobre --surface-alt              3
   Fase 9 (versión final): --ok, --danger y --muted como TEXTO. Su valor
   base no llega a 4.5 en claro (3.20, 3.64 y 2.94 sobre --surface); se
   quedan para lo gráfico (puntos, franjas) y el texto usa su -ink, que en
   oscuro es el mismo color. tests/test_contraste_balam.py falla si vuelve
   a aparecer "color: var(--ok|--danger|--muted)".
   @contraste --ok-ink               sobre --surface                    4.5
   @contraste --ok-ink               sobre --bg                         4.5
   @contraste --ok-ink               sobre --surface-alt                4.5
   @contraste --danger-ink           sobre --surface                    4.5
   @contraste --danger-ink           sobre --bg                         4.5
   @contraste --danger-ink           sobre --surface-alt                4.5
   @contraste --danger-ink           sobre --danger-tenue sobre --surface 4.5
   @contraste --muted-ink            sobre --surface                    4.5
   @contraste --muted-ink            sobre --bg                         4.5
   @contraste --muted-ink            sobre --surface-alt                4.5
   --muted como GRÁFICO (franja "privado", su muestra en la leyenda, punto
   "declinado"): 3:1. La leyenda va sobre --bg; las tarjetas, sobre --surface.
   @contraste --muted                sobre --surface                    3
   @contraste --muted                sobre --bg                         3
   Fase 9: nombre de la sección abierta en la franja del nombre.
   @contraste --nav-acc-radar         sobre --nav-bg                    4.5
   @contraste --nav-acc-noticias      sobre --nav-bg                    4.5
   @contraste --nav-acc-oportunidades sobre --nav-bg                    4.5
   ───────────────────────────────────────────────────────────────────────── */

/* ─── Base ───────────────────────────────────────────────────────────────── */
*,*::before,*::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  transition: background var(--t), color var(--t);
}
h1,h2,h3 { margin: 0; font-weight: 650; letter-spacing: -.02em; line-height: 1.2; }
h3 {
  font-size: 12px; text-transform: uppercase; letter-spacing: .12em;
  color: var(--text-faint); font-weight: 600;
}
p { margin: 0; color: var(--text-soft); }
code { font-family: var(--mono); font-size: .85em; }
::selection { background: var(--accent-soft); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* ─── Primitivas ─────────────────────────────────────────────────────────── */
.neu-out { background: var(--surface); box-shadow: var(--neu-out); }
.neu-in  { background: var(--surface); box-shadow: var(--neu-in); }

/* ─── Contenedor / tarjeta (BALAM §4.1) ──────────────────────────────────── */
.card {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--neu-out);
  padding: var(--sp-4);
  transition: box-shadow var(--t), transform var(--t);
}
.glass {
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-brd);
}

@keyframes shake {
  0%,100% { transform: translateX(0); }
  18%     { transform: translateX(-7px); }
  38%     { transform: translateX(6px); }
  58%     { transform: translateX(-4px); }
  78%     { transform: translateX(3px); }
}
@keyframes fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  *,*::before,*::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─── Navbar ─────────────────────────────────────────────────────────────── */
.navbar {
  position: fixed;
  top: 18px; left: 50%; transform: translateX(-50%);
  z-index: 60;
  display: flex; align-items: center; gap: 4px;
  padding: 6px;
  border-radius: var(--r-pill);
  box-shadow: var(--nav-sombra);
  max-width: calc(100vw - 32px);
  overflow: hidden;
}
/* Fase 4: fondo oscuro sólido. Pisa el fondo translúcido de .glass (misma
   especificidad + 1) sin quitarle la clase al HTML. */
.navbar.glass { background: var(--nav-bg); border-color: var(--nav-brd); }
.navbar :focus-visible { outline-color: var(--nav-focus); }
.nav-indicator {
  position: absolute; top: 6px; bottom: 6px; left: 0; width: 0;
  border-radius: var(--r-pill);
  background: var(--nav-ind);
  transition: transform var(--t), width var(--t);
  pointer-events: none;
}
.nav-btn {
  position: relative; z-index: 1;
  border: 0; background: transparent; cursor: pointer;
  padding: 10px 18px; border-radius: var(--r-pill);
  font: inherit; font-size: 13px; font-weight: 550;
  color: var(--nav-text-soft);
  display: inline-flex; align-items: center; gap: 8px;
  white-space: nowrap;
  transition: color var(--t), transform var(--t);
  min-height: 44px;
}
.nav-btn svg {
  width: 16px; height: 16px; stroke: currentColor; fill: none;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.nav-btn:hover { color: var(--nav-text); }
.nav-btn:active { transform: scale(.94); }
/* Ítem activo con el acento de SU sección (Fase 4). */
.nav-btn.is-active { color: var(--nav-text); }
.nav-btn.is-active[data-sec="radar"]         { color: var(--nav-acc-radar); }
.nav-btn.is-active[data-sec="noticias"]      { color: var(--nav-acc-noticias); }
.nav-btn.is-active[data-sec="oportunidades"] { color: var(--nav-acc-oportunidades); }

/* navbar arriba en desktop, abajo en móvil */
@media (max-width: 640px) {
  .navbar {
    top: auto;
    bottom: calc(12px + env(safe-area-inset-bottom));
  }
  .nav-btn .txt { display: none; }
  .nav-btn { padding: 11px 14px; }
}

/* ─── Botones ─────────────────────────────────────────────────────────────── */
/* .btn se usa tanto en <button> como en <a href="..."> estilizados como
   botón (descargas, enlaces a fuente externa, acciones del modal de
   cliente). Sin text-decoration:none aquí, el navegador subraya el <a>
   por su estilo por defecto — <button> nunca lo necesita, así que el
   hueco solo se nota en los usos con <a>. Antes de esto, cada sitio que
   ponía .btn en un <a> tenía que repetir el reset a mano (ver el "Descargar
   PDF" de Reportes, que ya lo hacía inline) o quedaba roto en silencio
   (#pd-link-fuente, el botón "Ver fuente original" del panel de detalle,
   que no lo tenía). Puesto aquí una sola vez, cubre los tres de golpe y
   cualquier <a class="btn"> futuro. */
.btn {
  border: 0; cursor: pointer; font: inherit; font-size: 14px; font-weight: 550;
  color: var(--text-soft); background: var(--surface);
  padding: 10px 18px; border-radius: var(--r-md);
  box-shadow: var(--neu-out);
  display: inline-flex; align-items: center; gap: 8px;
  transition: all var(--t);
  min-height: 44px;
  text-decoration: none;
}
.btn svg {
  width: 17px; height: 17px; stroke: currentColor; fill: none;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.btn:hover { color: var(--accent); transform: translateY(-1px); }
.btn:active { box-shadow: var(--neu-in); transform: scale(.96); color: var(--accent); }
.btn--icon { padding: 10px; border-radius: 50%; }
.btn--pill { border-radius: var(--r-pill); }
.btn--ghost { box-shadow: none; background: transparent; }
.btn--ghost:hover { box-shadow: var(--neu-out-sm); }
.btn--accent {
  color: var(--on-accent);
  background: linear-gradient(145deg, var(--accent), color-mix(in srgb, var(--accent) 78%, var(--negro)));
}
.btn--accent:hover { color: var(--on-accent); filter: brightness(1.06); }
.btn--accent:active { box-shadow: var(--neu-in-sm); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn.is-active { box-shadow: var(--neu-in); color: var(--accent); }

/* ─── Inputs ─────────────────────────────────────────────────────────────── */
.input {
  border: 0; outline: 0; font: inherit; color: var(--text);
  background: var(--surface); border-radius: var(--r-md);
  padding: 12px 16px; width: 100%;
  box-shadow: var(--neu-in);
  transition: box-shadow var(--t), color var(--t);
  min-height: 44px;
}
.input::placeholder { color: var(--text-faint); }
.input:focus { box-shadow: var(--neu-in), 0 0 0 2px var(--accent-soft); }
select.input { cursor: pointer; appearance: none; -webkit-appearance: none; }

/* ─── Control segmentado ─────────────────────────────────────────────────── */
.seg {
  position: relative; display: inline-flex; padding: 5px;
  border-radius: var(--r-pill);
  background: var(--surface); box-shadow: var(--neu-in-sm);
}
.seg-ind {
  position: absolute; top: 5px; bottom: 5px; left: 0; width: 0;
  border-radius: var(--r-pill);
  background: var(--surface); box-shadow: var(--neu-out-sm);
  transition: transform var(--t), width var(--t);
  pointer-events: none;
}
.seg button {
  position: relative; z-index: 1;
  border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 550;
  color: var(--text-faint); padding: 7px 16px; border-radius: var(--r-pill);
  transition: color var(--t), transform var(--t);
  white-space: nowrap; min-height: 44px;
}
.seg button:active { transform: scale(.95); }
.seg button.is-active { color: var(--accent); }

/* ─── Tarjeta de proyecto ────────────────────────────────────────────────── */
.card-proyecto {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  cursor: pointer;
  transition: box-shadow var(--t), transform var(--t);
  position: relative;
  animation: fade-in .3s var(--ease);
  outline: 1px solid var(--border-line); outline-offset: -1px;
}
/* C: sin elevación, solo borde sutil → jerárquicamente inferior */
.card-proyecto[data-grado="C"] {
  box-shadow: inset 0 0 0 1px var(--border-subtle);
  opacity: .82;
}
/* B: elevación pequeña → medio */
.card-proyecto[data-grado="B"] { box-shadow: var(--neu-out-sm), inset 0 0 0 1px var(--border-subtle); }
/* A: elevación completa + franja de acento → el más prominente */
.card-proyecto[data-grado="A"] {
  box-shadow: var(--neu-out), inset 0 0 0 1px var(--border-subtle);
  border-left: 3px solid var(--accent);
}

.card-proyecto:hover { transform: translateY(-2px); }
.card-proyecto[data-grado="C"]:hover { opacity: 1; box-shadow: var(--neu-out-sm), inset 0 0 0 1px var(--border-subtle); }
.card-proyecto[data-grado="B"]:hover { box-shadow: var(--neu-out), inset 0 0 0 1px var(--border-subtle); }
.card-proyecto[data-grado="A"]:hover {
  box-shadow: var(--d) var(--d) calc(var(--b) * 1.4) var(--sh-dark),
              calc(var(--d) * -1) calc(var(--d) * -1) calc(var(--b) * 1.4) var(--sh-light),
              inset 0 0 0 1px var(--border-subtle);
}
.card-proyecto:active { transform: scale(.98); }

/* ─── Badge de prioridad (grado A/B/C presentado como Alta/Media/Baja) ────── */
.badge-grado {
  display: inline-flex; align-items: center; justify-content: center;
  height: 24px; padding: 0 var(--sp-2); border-radius: var(--r-pill);
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
  flex-shrink: 0; white-space: nowrap;
}
.badge-grado[data-grado="A"] {
  background: var(--accent);      /* único uso de --accent como fondo */
  color: var(--on-accent);
  box-shadow: 0 2px 8px var(--accent-soft);
}
.badge-grado[data-grado="B"] {
  background: var(--surface);
  color: var(--text-soft);
  box-shadow: var(--neu-out-sm);
}
.badge-grado[data-grado="C"] {
  background: var(--surface);
  color: var(--text-faint);
}

/* ─── Badge de cliente ───────────────────────────────────────────────────── */
.badge-cliente {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: var(--r-pill);
  font-size: 11px; font-weight: 600;
  background: var(--accent-soft); color: var(--accent-ink);
}

/* ─── Barra de etapa (seis muescas en canal inset) ──────────────────────── */
.etapa-rail {
  display: flex; gap: 3px; padding: 4px;
  border-radius: var(--r-sm);
  box-shadow: var(--neu-in-sm);
  background: var(--surface);
}
.etapa-notch {
  flex: 1; height: 5px; border-radius: 3px;
  background: transparent;
  transition: background var(--t);
}
.etapa-notch.past { background: var(--accent-soft); }
.etapa-notch.current {
  background: var(--accent);
  box-shadow: 0 0 6px var(--accent-soft);
}

/* ─── KPI bar ─────────────────────────────────────────────────────────────── */
.kpi-bar {
  display: flex; gap: var(--sp-3); flex-wrap: wrap;
}
.kpi-card {
  background: var(--surface);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  box-shadow: var(--neu-in-sm), inset 0 0 0 1px var(--border-subtle);
  flex: 1; min-width: 100px;
  outline: 1px solid var(--border-line); outline-offset: -1px;
}
.kpi-val {
  font-size: 28px; font-weight: 650; letter-spacing: -.03em;
  font-family: var(--mono); color: var(--text);
}
.kpi-lbl {
  font-size: 11px; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .1em; font-weight: 600;
}
.kpi-val.accent { color: var(--accent); }

/* ─── Grid de proyectos ──────────────────────────────────────────────────── */
.proyectos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--sp-4);
}

/* ─── Panel de detalle (glass, slide-in derecha) ─────────────────────────── */
.panel-detalle {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(480px, 100vw);
  border-radius: var(--r-lg) 0 0 var(--r-lg);
  z-index: 50;
  padding: var(--sp-5) var(--sp-4);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(100%);
  transition: transform var(--t);
  box-shadow: inset 0 0 0 1px var(--border-subtle);
  outline: 1px solid var(--border-line); outline-offset: -1px;
}
.panel-detalle.is-open { transform: translateX(0); }
.panel-backdrop {
  position: fixed; inset: 0; z-index: 49;
  background: var(--velo-panel-claro);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--t);
}
.panel-backdrop.is-open { opacity: 1; pointer-events: auto; }

/* ─── Acciones de contacto (junto al nombre del promovente) ─────────────── */
.panel-cliente-row {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex-wrap: wrap;
}
.btn-contacto {
  display: none;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  border: none; border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-faint);
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  transition: color var(--t-fast), box-shadow var(--t-fast);
}
.btn-contacto svg {
  width: 13px; height: 13px;
  stroke: currentColor; fill: none;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.btn-contacto:hover { color: var(--accent); box-shadow: var(--neu-out-sm); }
.btn-contacto:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-contacto.copiado { color: var(--ok-ink); }

/* ─── Notas ──────────────────────────────────────────────────────────────── */
.nota-item {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--neu-in-sm), inset 0 0 0 1px var(--border-subtle);
  font-size: 13px; color: var(--text-soft);
  margin-bottom: var(--sp-2);
  outline: 1px solid var(--border-line); outline-offset: -1px;
}
.nota-fecha { font-size: 11px; color: var(--text-faint); margin-bottom: var(--sp-1); }

/* ─── Mi Pizarrón ────────────────────────────────────────────────────────── */
.pizarron-card {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  box-shadow: var(--neu-out-sm), inset 0 0 0 1px var(--border-subtle);
  transition: box-shadow var(--t), transform var(--t);
  animation: fade-in .3s var(--ease);
  outline: 1px solid var(--border-line); outline-offset: -1px;
}
.pizarron-vacio {
  text-align: center; padding: var(--sp-6) var(--sp-4);
  color: var(--text-faint);
}
.pizarron-vacio svg {
  width: 48px; height: 48px; stroke: var(--text-faint);
  fill: none; stroke-width: 1.5;
  margin-bottom: var(--sp-3);
}

/* ─── Toast ───────────────────────────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; bottom: 100px;
  transform: translate(-50%, 14px);
  padding: 11px 20px; border-radius: var(--r-pill);
  font-size: 13px; font-weight: 550; color: var(--text);
  opacity: 0; pointer-events: none; z-index: 80;
  box-shadow: var(--sombra-toast);
  transition: opacity var(--t), transform var(--t);
  background: var(--surface);
  white-space: nowrap;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.ok   { color: var(--ok-ink); }
.toast.err  { color: var(--danger-ink); }

/* ─── Layout general ─────────────────────────────────────────────────────── */
.app-main {
  max-width: 1200px; margin: 0 auto;
  padding: calc(76px + var(--sp-5)) var(--sp-4) var(--sp-5);
}
@media (max-width: 640px) {
  .app-main {
    padding: var(--sp-4) var(--sp-3) calc(90px + env(safe-area-inset-bottom));
  }
}

.seccion { display: none; }
.seccion.is-active { display: block; }

/* ─── Filtros ─────────────────────────────────────────────────────────────── */
.filtros-wrap {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--neu-in), inset 0 0 0 1px var(--border-subtle);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-2);
  outline: 1px solid var(--border-line); outline-offset: -1px;
}
.filtros-row {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center;
}
.filtro-label {
  font-size: 11px; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .1em; font-weight: 600;
  white-space: nowrap; align-self: center;
}
/* Línea aclaratoria bajo una fila de filtro (p. ej. distinguir el eje
   "quién construye" del eje "de dónde salió el dato") — texto normal,
   sin mayúsculas, para no competir con .filtro-label. flex-basis:100%
   la empuja a su propia línea dentro de la .filtros-row con flex-wrap. */
.filtro-hint {
  flex-basis: 100%;
  font-size: 11.5px; font-weight: 400;
  color: var(--text-faint);
}
.busqueda-wrap {
  position: relative; flex: 1; min-width: 200px;
}
.busqueda-wrap svg {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; stroke: var(--text-faint);
  fill: none; stroke-width: 1.8; pointer-events: none;
}
.busqueda-wrap .input { padding-left: 40px; }

/* ─── Etiquetas de campo ─────────────────────────────────────────────────── */
.label { font-size: 11px; color: var(--text-faint); text-transform: uppercase;
         letter-spacing: .1em; font-weight: 600; display: block; margin-bottom: var(--sp-1); }

/* ─── Ventana comercial label ────────────────────────────────────────────── */
.ventana-label {
  font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase;
}
.ventana-label.abierta { color: var(--ok-ink); }
.ventana-label.proceso { color: var(--accent); }
.ventana-label.cerrada { color: var(--text-faint); }

/* ─── Estatus pizarrón ────────────────────────────────────────────────────── */
.estatus-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 6px; flex-shrink: 0;
}
.estatus-dot.por_contactar { background: var(--text-faint); }
.estatus-dot.contactado    { background: var(--estatus-contactado); }
.estatus-dot.cotizando     { background: var(--estatus-cotizando); }
.estatus-dot.ganado        { background: var(--ok); }
.estatus-dot.perdido       { background: var(--danger); }
.estatus-dot.declinado     { background: var(--muted); }

/* ─── Prioridad ──────────────────────────────────────────────────────────── */
.prioridad-btn {
  border: 0; cursor: pointer; font: inherit; font-size: 12px; font-weight: 600;
  font-family: var(--mono); color: var(--text-faint); background: var(--surface);
  padding: 5px 10px; border-radius: var(--r-sm);
  box-shadow: var(--neu-out-sm);
  transition: all var(--t); min-height: 44px; min-width: 44px;
}
.prioridad-btn.is-active { box-shadow: var(--neu-in-sm); color: var(--accent); }
.prioridad-btn:hover { color: var(--text); }

/* ─── Empty state ────────────────────────────────────────────────────────── */
.empty-state {
  text-align: center; padding: var(--sp-6) var(--sp-4);
  color: var(--text-faint);
}
.empty-state svg {
  width: 52px; height: 52px; stroke: var(--text-faint); fill: none;
  stroke-width: 1.4; margin-bottom: var(--sp-3);
}

/* ─── Filtros expandibles ───────────────────────────────────────────────── */
.filtros-ext {
  display: none;
  flex-direction: column;
  gap: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--borde-filtros);
  margin-top: var(--sp-1);
}
.filtros-ext.is-open { display: flex; }

.filtros-mas-btn {
  flex-shrink: 0; white-space: nowrap;
  position: relative;
}
.filtros-mas-btn svg {
  transition: transform var(--t);
}
.filtros-mas-btn[aria-expanded="true"] svg {
  transform: rotate(180deg);
}
.filtros-activos-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  font-size: 10px; font-weight: 700; font-family: var(--mono);
  position: absolute; top: 4px; right: 4px;
}

/* ─── Scroll overflow en filtros en móvil ───────────────────────────────── */
@media (max-width: 640px) {
  .filtros-row { flex-wrap: nowrap; overflow-x: auto; padding-bottom: var(--sp-1); }
  .filtros-row::-webkit-scrollbar { display: none; }
  .proyectos-grid { grid-template-columns: 1fr; }
}

/* ─── Sección Reportes ───────────────────────────────────────────────────── */
.reporte-form {
  max-width: 560px;
  margin: var(--sp-5) auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.reporte-titulo {
  font-size: 18px; font-weight: 650; color: var(--text);
  margin: 0;
}
.reporte-grupo { display: flex; flex-direction: column; gap: var(--sp-1); }
.reporte-lbl {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .08em; color: var(--text-faint);
}
.reporte-desc {
  font-size: 13px; color: var(--text-soft); line-height: 1.55;
  min-height: 36px;
}
.reporte-aviso-sel {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 13px;
}
.link-btn {
  background: none; border: none; cursor: pointer;
  color: var(--accent); font-size: 13px; font-weight: 600;
  padding: 0; text-decoration: underline;
}
.link-btn:hover { opacity: .75; }
.btn-generar {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--on-accent);
  font-size: 14px; font-weight: 600; font-family: var(--font);
  border: none; cursor: pointer;
  box-shadow: var(--sombra-acento);
  transition: opacity var(--t-fast), box-shadow var(--t-fast);
  align-self: flex-start;
}
.btn-generar:hover:not(:disabled) { opacity: .88; box-shadow: var(--sombra-acento-hover); }
.btn-generar:disabled { opacity: .5; cursor: not-allowed; }
.btn-generar:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ─── Control segmentado (origen / detalle) ──────────────────────────────── */
.seg-ctrl {
  display: inline-flex;
  border-radius: var(--r-md);
  box-shadow: var(--neu-in-sm);
  overflow: hidden;
}
.seg-btn {
  flex: 1; padding: var(--sp-2) var(--sp-3);
  font-size: 13px; font-weight: 500; font-family: var(--font);
  border: none; background: transparent; cursor: pointer;
  color: var(--text-soft);
  transition: background var(--t-fast), color var(--t-fast);
}
.seg-btn.active {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}
.seg-btn:hover:not(.active) { background: var(--accent-soft); color: var(--accent); }
.seg-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ─── Casilla de selección en tarjetas (modo reporte) ───────────────────── */
.card-check-wrap {
  display: none;
  position: absolute; top: var(--sp-2); left: var(--sp-2);
  width: 22px; height: 22px;
  cursor: pointer;
  z-index: 2;
}
.card-check-wrap input[type="checkbox"] {
  position: absolute; opacity: 0; width: 100%; height: 100%;
  margin: 0; cursor: pointer;
}
.card-check-ico {
  width: 22px; height: 22px;
  border: 2px solid var(--sh-dark);
  border-radius: 6px;
  background: var(--surface);
  stroke: transparent;
  stroke-width: 2.5;
  stroke-linecap: round;
  transition: background var(--t-fast), border-color var(--t-fast), stroke var(--t-fast);
  display: block;
}
.card-check-wrap input:checked + .card-check-ico {
  background: var(--accent);
  border-color: var(--accent);
  stroke: var(--on-accent);
}
/* Mostrar casillas solo en modo selección */
.modo-seleccion .card-check-wrap { display: flex; }
.modo-seleccion .card-proyecto { cursor: default; }
.card-proyecto { position: relative; }

/* ─── Separador ──────────────────────────────────────────────────────────── */
.sep {
  height: 1px; background: var(--sep-line);
  margin: var(--sp-3) 0;
}

/* ─── Puntaje visual en panel ────────────────────────────────────────────── */
.puntaje-ring {
  width: 72px; height: 72px; border-radius: 50%;
  background: var(--surface); box-shadow: var(--neu-out-sm);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  flex-shrink: 0;
}
.puntaje-ring .val {
  font-family: var(--mono); font-size: 18px; font-weight: 700;
  color: var(--accent); line-height: 1;
}
.puntaje-ring .lbl {
  font-size: 10px; color: var(--text-faint); font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
}

/* ─── Separador de noticias (surco neumórfico) ──────────────────────────────── */
.not-card { position: relative; }
.not-card::after {
  content: '';
  position: absolute;
  bottom: 0; left: 4%; right: 4%;
  height: 2px;
  background:
    linear-gradient(to right, transparent, var(--border-line) 20%, var(--border-line) 80%, transparent) top / 100% 1px no-repeat,
    linear-gradient(to right, transparent, var(--divider-highlight) 20%, var(--divider-highlight) 80%, transparent) bottom / 100% 1px no-repeat;
}
.not-card:last-child::after { display: none; }
