/* ── Fuentes alojadas en el propio servidor (fase 3, punto 2) ───────────────
   Antes venían del servicio de fuentes de Google con dos `preconnect`. Los .woff2 son los
   mismos que autoaloja next/font en myVPD (subconjunto `latin`), así que el
   dibujo de la letra no cambia. Schibsted Grotesk es variable: un solo archivo
   cubre de 400 a 800. `swap`: el texto se ve desde el primer pintado y cambia a
   la fuente definitiva al llegar, sin bloquear. */
/* Un bloque por peso, todos sobre el MISMO archivo variable: es como lo declara
   Google, y así el navegador instancia el eje wght exactamente igual. Con un solo
   bloque `font-weight: 400 800` los avances de glifo se desviaban 0,03 px en los
   pesos altos y las capturas dejaban de ser idénticas. */
@font-face {
  font-family: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/schibsted-grotesk-latin-var.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}
@font-face {
  font-family: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/schibsted-grotesk-latin-var.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}
@font-face {
  font-family: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/schibsted-grotesk-latin-var.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}
@font-face {
  font-family: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/schibsted-grotesk-latin-var.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}
@font-face {
  font-family: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("/static/fonts/schibsted-grotesk-latin-var.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/ibm-plex-mono-latin-400.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/ibm-plex-mono-latin-500.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/ibm-plex-mono-latin-700.woff2") format("woff2");
  unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc,
                 u+0304, u+0308, u+0329, u+2000-206f, u+20ac, u+2122, u+2191, u+2193,
                 u+2212, u+2215, u+feff, u+fffd;
}

/* ============================================================
 * myVPD Optimizador · estilos.css v1 (fase 2: maqueta = render real)
 * Sistema visual de myVPD: tokens de globals.css (mismos nombres) + tokens
 * nuevos de mapeo_color_v3.md. Solo modo claro. Sin rejilla, sin degradados
 * (ni lineales ni cónicos), sin sombras en tarjetas del interior.
 *
 * Hex fuera de tokens (con motivo):
 *   - ninguno: el blanco es --texto-inverso / --superficie; la pista de la barra de uso del plan usa
 *     --filete-sobre-navy; el gris de deshabilitado es --texto-deshabilitado (#767B99, el de main, 4,15:1).
 * Ronda 4 (decisión del dueño): color con función. Verde = bien, rojo = mal, ámbar = pide atención,
 * rosa = dinero bueno (como «venta real» en myVPD), índigo = acción. La versión sobria queda en html.v-sobrio
 * solo para comparar.
 * ============================================================ */
:root {
  --font-sans: "Schibsted Grotesk", "Helvetica Neue", Arial, system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Acción (índigo) */
  --accion: #3D43D9;
  --accion-hover: #2F34B5;
  --accion-suave: #EEF0FF;

  /* Texto */
  --navy: #0F1230;
  --tinta: #1B1E3A;
  --texto: #4A4F6A;
  --texto-suave: #5B6078;
  --texto-tenue: #8A8FAA;
  --texto-inverso: #FFFFFF;

  /* Superficies y líneas */
  --superficie: #FFFFFF;
  --papel: #F6F7FB;
  --papel-2: #FBFBFD;
  --papel-3: #F1F2F6;
  --linea: #E4E6F0;
  --linea-suave: #EEF0F5;
  --linea-fuerte: #D6D9E6;

  /* Estados */
  --exito: #17703F;
  --exito-suave: #E4F5EC;
  --error: #B3164B;
  --error-suave: #FDE8EF;
  --error-linea: #F5B8CC;

  /* Foco */
  --foco: rgba(61, 67, 217, 0.25);
  --foco-fuerte: rgba(61, 67, 217, 0.45);

  /* Sombras (solo flotantes y modales) */
  --sombra-1: 0 10px 30px rgba(15, 18, 48, 0.06);
  --sombra-2: 0 16px 40px rgba(15, 18, 48, 0.10);
  --sombra-3: 0 20px 50px rgba(15, 18, 48, 0.18);
  --sombra-toast: 0 10px 30px rgba(15, 18, 48, 0.25);
  --velo: rgba(15, 18, 48, 0.55);

  /* Radios y medidas */
  --radio-tarjeta: 18px;
  --radio-flotante: 14px;
  --radio-alerta: 12px;
  --radio-campo: 10px;
  --radio-caja: 5px;
  --radio-pildora: 999px;
  --alto-boton: 50px;
  --alto-boton-md: 44px;
  --alto-boton-sm: 36px;
  --alto-campo: 48px;
  --transicion: 150ms;

  /* Interior en color (dirección B): superficies navy y lo que va encima */
  --navy-2: #1B1F4A;
  --navy-activo: #232860;
  --navy-bloque: #14173D;
  --accion-claro: #8A8FF0;
  --fila-activa: #E4E7FA;
  --texto-sobre-navy: #C9CCE6;
  --rotulo-sobre-navy: #A3A8CC;
  --punto-sobre-navy: #6E73A8;
  --filete-sobre-navy: rgba(255, 255, 255, 0.14);

  /* Peligro (rojo verdadero) */
  --peligro: #B42318;
  --peligro-suave: #FCEBE7;
  --peligro-linea: #EFB4AC;
  /* Nuevo (mapeo v3 §10): peligro sobre navy */
  --peligro-claro: #F49A90;
  /* Texto de control deshabilitado (main: .btn-secondary[aria-disabled], 4,15:1 sobre blanco, exento ≥ 4) */
  --texto-deshabilitado: #767B99;
}
/* Color con función (decisión del dueño, ronda 4): rosa = dinero bueno, ámbar = pide atención */
:root {
  --venta: #E9366D;            /* decorativo (puntos) y texto ≥ 19 px negrita */
  --venta-relleno: #C9245A;    /* rellenos y texto chico (5,41:1 sobre blanco) */
  --venta-relleno-hover: #A81C4B;
  --venta-suave: #FDE8EF;
  --aviso: #92400E;   /* dorado · elección de Victor 24-sep */
  --aviso-suave: #FEF3C7;
  /* sobre navy (valores del modo oscuro de globals.css, mismo matiz) */
  --venta-claro: #F25C8A;      /* 5,68:1 sobre #0F1230 */
  --exito-claro: #6FD79A;      /* 10,1:1 */
  --aviso-claro: #FCD34D;      /* 12,67:1 sobre navy */
  --aviso-barra: #C2670B;      /* barra/relleno: ámbar vivo, 3,52:1 sobre la pista */
}

/* ── Base ── */
* { box-sizing: border-box; }
html, body { margin: 0; }
body { font-family: var(--font-sans); background: var(--accion-suave); color: var(--tinta);
       line-height: 1.5; font-size: 14px; -webkit-font-smoothing: antialiased; }
a { color: var(--accion); text-decoration: none; font-weight: 700; }
a:hover { color: var(--accion-hover); }
.mono { font-family: var(--font-mono); font-size: 0.93em; }
b, strong { font-weight: 700; }

/* ── Armazón ── */
.app { display: grid; grid-template-columns: 232px minmax(0, 1fr); min-height: 100vh; }
/* Cabecera, velo y barra inferior de móvil: no existen en escritorio (fase 3). */
.mm-cab, .mm-velo, .mm-barra { display: none; }
.sidebar { background: var(--navy); color: var(--texto-inverso); padding: 22px 14px 14px;
           display: flex; flex-direction: column; gap: 0; position: sticky; top: 0; height: 100vh;
           /* App-lista r11 P1.13 (UI11-5): en pantallas bajas (1366×768, 1280×720) «Salir» y la
              ayuda quedaban fuera; la barra se desplaza por dentro. */
           overflow-y: auto; overscroll-behavior: contain; }
.logo { display: flex; align-items: center; gap: 7px; padding: 0 6px 18px; min-width: 0; }
.logo img { height: 30px; width: auto; display: block; flex: none; }


/* Selector de cuenta: control --navy-2 (input estilizado; el JS no cambia) */
.combo { position: relative; margin-bottom: 10px; }
.combo > input { width: 100%; height: 44px; padding: 0 34px 0 14px; border-radius: var(--radio-campo);
  border: 1px solid transparent; background: var(--navy-2); color: var(--texto-inverso); font-weight: 700;
  font-size: 14px; text-overflow: ellipsis; }
.combo > input::placeholder { color: var(--rotulo-sobre-navy); font-weight: 600; }
/* Cierre de la fase 5 (juez 2): esta regla (0,2,1) le ganaba al anillo de foco y dejaba a
   `#accountSearch` como el único control con otro lenguaje. El anillo blanco sobre navy
   se restituye en `:focus-visible`, y el borde claro se conserva. */
.combo > input:focus { border-color: var(--accion-claro); box-shadow: none; outline: none; }
.combo > input:focus-visible { outline: 3px solid var(--texto-inverso); outline-offset: 2px; }
.combo::after { content: ""; position: absolute; right: 16px; top: 16px; width: 7px; height: 7px;
  border-right: 1.8px solid var(--rotulo-sobre-navy); border-bottom: 1.8px solid var(--rotulo-sobre-navy);
  transform: rotate(45deg); pointer-events: none; }
.combo-list { position: absolute; top: calc(100% + 6px); left: 0; width: 360px; max-width: calc(100vw - 28px); z-index: 30;
  background: var(--superficie); border: 1px solid var(--linea); border-radius: var(--radio-flotante); box-shadow: var(--sombra-2);
  max-height: 340px; overflow: auto; display: none; padding: 6px; color: var(--tinta); }
.combo-list.open { display: block; }
.combo-item { padding: 10px 12px; border-radius: var(--radio-campo); cursor: pointer; display: flex; justify-content: space-between;
  align-items: center; gap: 12px; font-size: 14px; min-height: 40px; }
.combo-item:hover, .combo-item.active { background: var(--accion-suave); }
.combo-item .nm { font-weight: 700; color: var(--navy); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo-item .cid { color: var(--texto-suave); font-family: var(--font-mono); font-size: 12px; flex: none; }
.combo-empty { padding: 12px; color: var(--texto-suave); font-size: 13px; }
.combo-head { padding: 6px 12px 8px; font-size: 12px; color: var(--texto-suave); border-bottom: 1px solid var(--linea-suave); margin-bottom: 4px; }

/* Menú: 15/600 gris de banda, punto de 7 px, activo píldora --navy-activo */
.nav { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.nav a { display: flex; align-items: center; gap: 10px; height: 44px; padding: 0 12px; border-radius: var(--radio-campo);
         color: var(--texto-sobre-navy); font-size: 15px; font-weight: 600; cursor: pointer; position: relative; }
.nav a::before { content: ""; width: 7px; height: 7px; border-radius: var(--radio-pildora); background: var(--punto-sobre-navy); flex: none; }
.nav a:hover { background: var(--navy-activo); color: var(--texto-inverso); }
.nav a.active { background: var(--navy-activo); color: var(--texto-inverso); font-weight: 700; }
.nav a.active::before { background: var(--accion-claro); }
.nav-badge { margin-left: auto; background: var(--accion-suave); color: var(--navy); font-size: 11px; font-weight: 800;
             min-width: 22px; height: 20px; padding: 0 7px; border-radius: var(--radio-pildora); display: inline-flex;
             align-items: center; justify-content: center; font-variant-numeric: tabular-nums; }
/* El display:inline-flex del badge pisa el [hidden]{display:none} del navegador:
   regla propia para que hidden lo oculte de verdad (juez B H-1). */
.nav-badge[hidden] { display:none !important; }

/* Bloque del plan al pie de la barra */
.side-foot { margin-top: auto; }
.plan-bloque { background: var(--navy-bloque); border-radius: var(--radio-flotante); padding: 14px 14px 12px; }
.plan-rotulo { font-size: 12px; font-weight: 700; color: var(--rotulo-sobre-navy); margin: 0 0 2px; }
/* R2-3 (juez 1, ronda 2): «Free · diagnóstico completo» medía 188 px dentro de una caja de
   176 px y se salía de la barra lateral en todos los anchos ≥1024. */
.plan-fila { display: flex; align-items: baseline; gap: 8px; font-size: 14px; font-weight: 700; color: var(--texto-inverso); flex-wrap: wrap; margin: 0; min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.plan-fila > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.plan-uso { margin-top: 8px; }
.uso-fila { display: flex; justify-content: space-between; align-items: baseline; font-size: 12px; color: var(--rotulo-sobre-navy); }
.uso-fila strong { color: var(--texto-inverso); font-weight: 700; }
.uso-barra { height: 4px; border-radius: var(--radio-pildora); background: var(--filete-sobre-navy); overflow: hidden; margin-top: 4px; }
.uso-barra > span { display: block; height: 100%; border-radius: var(--radio-pildora); background: var(--texto-sobre-navy); }
.uso-barra[data-estado="limite"] > span { background: var(--peligro-claro); }
.plan-enlaces { display: flex; flex-direction: column; gap: 0; margin-top: 8px; }
.enlace-navy { display: inline-flex; align-items: center; min-height: 36px; font-size: 13px; font-weight: 700; color: var(--accion-claro); cursor: pointer; }
.enlace-navy:hover { color: var(--texto-inverso); }
.side-user { display: flex; align-items: center; gap: 8px; padding: 12px 6px 0; min-width: 0; }
.usuario { font-size: 13px; font-weight: 600; color: var(--texto-sobre-navy); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
.side-user .more { color: var(--accion-claro); font-size: 13px; font-weight: 700; cursor: pointer; margin: 0; }
.side-user .more:hover { color: var(--texto-inverso); }

/* Cabecera clara: sin filete, sin primario */
.main { display: flex; flex-direction: column; min-width: 0; }
.topbar { display: flex; align-items: center; gap: 12px; padding: 18px 28px 0; }
.titulo-barra { font-size: 22px; font-weight: 800; color: var(--navy); letter-spacing: -0.02em; margin: 0; line-height: 1.2; }
.view > h1, .view > .titulo-vista { display: none; }
.topbar .spacer { flex: 1; }
/* r15 P5.9 (UI15-6): «Analizar la cuenta» y la inicial, siempre juntos. */
.topbar-acciones { display: inline-flex; align-items: center; gap: 12px; flex-wrap: nowrap; flex-shrink: 0; }
#status .btn-sm { margin-left: 6px; }
.avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--superficie); color: var(--accion);
          font-size: 13px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--linea); }
.content { padding: 14px 28px 40px; max-width: 1120px; width: 100%; margin: 0 auto; }

/* ── Controles ── */
input, select, button { font: inherit; font-size: 14px; color: var(--tinta); outline: none; }
input:where(:not([type="checkbox"]):not([type="hidden"])), select { height: var(--alto-campo); padding: 0 14px; border-radius: var(--radio-campo);
          border: 1px solid var(--linea-fuerte); background: var(--superficie); width: 100%; }
/* Fase 4: --texto-tenue (#8A8FAA) mide 3,19:1 sobre blanco y el marcador de un campo es
   texto: pasa a --texto-suave (6,20:1). El del selector de cuenta, sobre navy, tiene su
   propia regla y no cambia. */
input::placeholder { color: var(--texto-suave); font-weight: 400; }
/* final-2 (juez dueño 4): «Sector» del perfil, texto de 2 líneas que crece. */
textarea.campo-texto { font: inherit; font-size: 14px; color: var(--tinta); width: 100%; min-height: var(--alto-campo);
  padding: 10px 14px; border-radius: var(--radio-campo); border: 1px solid var(--linea-fuerte);
  background: var(--superficie); resize: vertical; line-height: 1.4; overflow: hidden; }
textarea.campo-texto::placeholder { color: var(--texto-suave); font-weight: 400; }
textarea.campo-texto:focus { border-color: var(--accion); box-shadow: 0 0 0 3px var(--foco); outline: none; }
/* App-lista r4 P5.3 (ui): el rótulo `label.field` va en 600 y el campo lo hereda; el marcador
   iba igual de grueso y un campo vacío parecía lleno. Solo el marcador baja a 400. */
input:where(:not([type="checkbox"])):focus, select:focus { border-color: var(--accion); box-shadow: 0 0 0 3px var(--foco); }
input[type="checkbox"] { width: 18px; height: 18px; margin: 0; accent-color: var(--accion); border-radius: var(--radio-caja); cursor: pointer; vertical-align: middle; }
button { cursor: pointer; font-weight: 700; height: var(--alto-boton-md); padding: 0 20px; border-radius: var(--radio-pildora);
         border: 1px solid transparent; background: var(--superficie); color: var(--navy); white-space: nowrap;
         display: inline-flex; align-items: center; justify-content: center; gap: 6px; transition: background-color var(--transicion), color var(--transicion), border-color var(--transicion); }
button.primary, button.brand { background: var(--accion); color: var(--texto-inverso); border-color: var(--accion); }
button.primary:hover, button.brand:hover { background: var(--accion-hover); border-color: var(--accion-hover); }
button.ghost { background: var(--superficie); color: var(--accion); border-color: var(--linea-fuerte); }
button.ghost:hover { background: var(--accion-suave); color: var(--accion-hover); }
button.danger { background: var(--superficie); color: var(--peligro); border-color: var(--peligro-linea); }
button.danger:hover { background: var(--peligro-suave); }
button.fantasma { background: transparent; color: var(--navy); border-color: transparent; }
button.fantasma:hover { background: var(--accion-suave); }
button.btn-blanco { background: var(--superficie); color: var(--navy); border-color: var(--superficie); font-weight: 800; }
button.btn-blanco:hover { background: var(--accion-suave); }
button:disabled { opacity: 1; cursor: default; }
button.ghost:disabled, button.btn-blanco:disabled { color: var(--texto-deshabilitado); border-color: var(--linea-fuerte); background: var(--superficie); }
button.primary:disabled, button.brand:disabled { background: var(--accion-suave); border-color: var(--accion-suave); color: var(--accion); }
button.danger:disabled { color: var(--texto-deshabilitado); border-color: var(--linea-fuerte); }
/* R2-1 (juez 1, ronda 2): los botones bloqueados de la bandeja usan `aria-disabled` en vez de
   `disabled` para no caerse del orden de tabulación (con `disabled` el motivo no se leía nunca
   con teclado). Como `:disabled` ya no aplica, el aspecto inactivo se repite aquí, y el `:hover`
   se neutraliza para que no simule que responde. */
button[aria-disabled="true"] { cursor: default; }
button.primary[aria-disabled="true"], button.brand[aria-disabled="true"],
button.primary[aria-disabled="true"]:hover, button.brand[aria-disabled="true"]:hover {
  background: var(--accion-suave); border-color: var(--linea-fuerte); color: var(--texto-suave); }
/* Ronda 3 (juez 2, R1): con `aria-disabled` los tres siguen en el Tab y responden al clic,
   así que la exención de «componente inactivo» de WCAG 1.4.3 ya no es limpia. Los tres usan
   --texto-suave (6,20:1 sobre blanco) en vez de --texto-deshabilitado (4,15:1), que además es
   lo que decía el acta de la ronda 2 que se había hecho. */
button.ghost[aria-disabled="true"], button.ghost[aria-disabled="true"]:hover {
  color: var(--texto-suave); border-color: var(--linea-fuerte); background: var(--superficie); }
button.danger[aria-disabled="true"], button.danger[aria-disabled="true"]:hover {
  color: var(--texto-suave); border-color: var(--linea-fuerte); background: var(--superficie); }
.btn-lg { height: var(--alto-boton); padding: 0 22px; font-size: 15px; }
.btn-sm { height: var(--alto-boton-sm); padding: 0 14px; font-size: 13px; }
.btn-cta { height: var(--alto-boton); padding: 0 24px; font-size: 15px; }
.iconbtn { padding: 0 10px; }
.more { color: var(--accion); font-weight: 700; font-size: 13px; cursor: pointer; display: inline-block; }
.more:hover { color: var(--accion-hover); }
/* App-lista r4 P5.8: «Ver detalle (N filas)» es un botón (aria-expanded) con aspecto de enlace. */
button.boton-enlace { height: auto; min-height: 24px; padding: 0; border: 0; border-radius: 0; background: none; color: var(--accion); white-space: normal; }
button.boton-enlace:hover { background: none; color: var(--accion-hover); }
button.boton-enlace:focus-visible { box-shadow: 0 0 0 3px var(--foco); border-radius: 4px; }
/* Solo para lectores de pantalla (arreglos 2 y 6: caption de la tabla y conteo anunciado) */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
           clip-path: inset(50%); white-space: nowrap; border: 0; }
/* Foco: anillo opaco 3 px; blanco dentro de navy */
/* Fase 5 (juez 2, defecto 3): los campos usaban borde de 1 px + halo y el resto anillo de
   3 px con separación — dos lenguajes de foco. El anillo se aplica también a campos y
   selectores, y el borde se conserva. */
a:focus-visible, button:focus-visible, summary:focus-visible, [tabindex]:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid var(--accion); outline-offset: 2px; }
.sidebar a:focus-visible, .sidebar button:focus-visible, .banda a:focus-visible, .banda button:focus-visible,
.plan.destacada button:focus-visible { outline-color: var(--texto-inverso); }
input[type="checkbox"]:focus-visible { outline: 3px solid var(--accion); outline-offset: 2px; }

/* ── Tarjetas, títulos, texto ── */
.card { background: var(--superficie); border: 1px solid var(--linea); border-radius: var(--radio-tarjeta); padding: 20px 24px; }
h1 { font-size: 22px; font-weight: 800; color: var(--navy); letter-spacing: -0.02em; margin: 0 0 4px; line-height: 1.2; }
h2 { font-size: 18px; font-weight: 800; color: var(--navy); letter-spacing: -0.015em; margin: 0 0 2px; line-height: 1.25; }
h2 .conteo { font-weight: 500; color: var(--texto-suave); font-size: 15px; letter-spacing: 0; }
h3 { font-size: 15px; font-weight: 700; color: var(--navy); margin: 22px 0 10px; }
.titulo-vista { font-size: 22px; font-weight: 800; color: var(--navy); letter-spacing: -0.02em; margin: 0 0 4px; line-height: 1.2; }
.card-titulo { font-size: 16px; font-weight: 700; color: var(--navy); margin: 0; }
.sub { color: var(--texto-suave); margin: 0 0 18px; font-size: 14px; }
.section { margin-bottom: 18px; }
.seccion-titulo { margin: 26px 0 12px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.seccion-titulo h2 { margin: 0; }
.seccion-nota { color: var(--texto-suave); font-size: 13px; }
.area-muted { color: var(--texto-suave); font-size: 13px; }
.area-muted.mini { font-size: 12px; }
.empty { color: var(--texto-suave); padding: 48px 24px; text-align: center; }
.vacio-titulo { font-size: 16px; font-weight: 700; color: var(--navy); margin-bottom: 6px; }
/* Fase 4 §10.1: las tres partes obligatorias del Vacío. La frase lleva medida de
   lectura (rúbrica D02) y el botón va pegado a ella, sin margen propio. */
.empty p { max-width: 52ch; margin: 0 auto 14px; }
.empty button { margin-top: 0; }
.empty .vacio-extra { margin-top: 12px; }
.nota-suave { color: var(--texto-suave); font-size: 13px; }
.texto-navy { color: var(--navy); font-weight: 700; }

/* Rótulos en mayúsculas 11-12 px: SOLO dentro de banda, tarjeta o thead */
.th, thead th, .bandeja-cab { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--navy); }
table { width: 100%; border-collapse: collapse; font-size: 14px; margin-top: 8px; display: none; }
thead tr { background: var(--accion-suave); }
th { text-align: left; padding: 10px 16px; white-space: nowrap; }
td { padding: 12px 16px; border-top: 1px solid var(--linea-suave); color: var(--tinta); vertical-align: middle; }
td.num, th.num { text-align: right; }
td.num { font-weight: 700; color: var(--navy); }
td.ag { color: var(--texto-suave); }
td.term { font-weight: 600; color: var(--navy); }
tbody tr:hover td { background: var(--papel); }

/* ── Chips ── */
.chip { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: var(--radio-pildora);
        font-size: 12px; font-weight: 700; white-space: nowrap; line-height: 1; background: var(--papel-3); color: var(--texto-suave); }
.chip.info { background: var(--accion-suave); color: var(--navy); }
.chip.media, .chip.aviso { background: var(--aviso-suave); color: var(--aviso); }
.chip.venta { background: var(--venta-suave); color: var(--navy); }
.chip.venta::before { content: ""; width: 6px; height: 6px; border-radius: var(--radio-pildora); background: var(--venta); }
.chip.venta-relleno { background: var(--venta-relleno); color: var(--texto-inverso); }
.chip.revisar { background: var(--accion-suave); color: var(--accion-hover); border: 1px solid var(--accion); }
.chip.exito, .chip.baja { background: var(--exito-suave); color: var(--exito); }
.chip.peligro, .chip.alta { background: var(--peligro-suave); color: var(--peligro); }
.chip.gris, .chip.muted { background: var(--papel-3); color: var(--texto-suave); }
/* Plan del pie de la barra: el chip que pinta paintPlan() se lee como texto blanco («Free · diagnóstico completo») */
/* R2-3: el chip del plan hereda `white-space: nowrap` de .chip, y «Free · diagnóstico
   completo» no cabía en los 176 px de la barra lateral. Aquí es texto corrido, no píldora. */
.side-foot .plan-fila .chip, .side-foot .plan-fila .chip.media, .side-foot .plan-fila .chip.baja { display: inline; background: none; color: var(--texto-inverso); padding: 0; height: auto; font-size: 14px; font-weight: 700; border: 0; line-height: 1.4; white-space: normal; overflow-wrap: anywhere; }
/* Severidad baja / informativa: palabra, no chip */
.sev-palabra { font-size: 12px; font-weight: 700; color: var(--texto-suave); white-space: nowrap; }


/* ── Alertas ── */
/* Fase 4 §9: las siete piezas de aviso del frontend usan UNA clase, `.alerta`, con
   cinco tonos (error > aviso > listo > info > neutro) y siempre la misma anatomía:
   punto de 8 px del tono + texto --tinta + .spacer + botón `ghost` a la derecha.
   La clase «banner», que tenía la misma definición base, se retira. */
.alerta { display: flex; align-items: flex-start; gap: 10px; padding: 12px 16px; border-radius: var(--radio-alerta); font-size: 14px;
          margin-bottom: 14px; color: var(--tinta); background: var(--accion-suave); border: 1px solid transparent; }
.alerta::before { content: ""; width: 8px; height: 8px; border-radius: var(--radio-pildora); background: var(--accion); flex: none; margin-top: 7px; }
.alerta.listo { background: var(--exito-suave); }
.alerta.listo::before { background: var(--exito); }
.alerta.error { background: var(--peligro-suave); border-color: var(--peligro-linea); }
.alerta.error::before { background: var(--peligro); }
.alerta.neutro { background: var(--papel-3); }
.alerta.neutro::before { background: var(--texto-suave); }
.alerta .more { margin-left: 4px; }
/* El botón del aviso no crece ni se estira, y se alinea con la primera línea del texto */
.alerta > button { flex: none; align-self: flex-start; }
.alerta > .spacer { min-width: 8px; }
.alerta > span.alerta-txt { flex: 1; min-width: 0; }
/* Ficha de gasto evitado (patrón «Ventas marcadas» de myVPD): rótulo con punto rosa, cifra grande rosa oscuro (6,13:1) */
.ficha-dinero { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; }
.ficha-dinero .cifra { color: var(--venta-relleno-hover); }
.ficha-dinero .meta { font-size: 13px; color: var(--texto-suave); flex: 1; min-width: 240px; }
.alerta.aviso { background: var(--aviso-suave); } .alerta.aviso::before { background: var(--aviso); }
/* Synsation fila 1: el aviso de un Deshacer que falló va en una fila propia, justo debajo de la tocada. */
table.terms tr.fila-aviso td { padding: 4px 0 10px; border: 0; white-space: normal; }
table.terms tr.fila-aviso:hover td { background: transparent; }
/* Synsation fila 4: pasado el tope, bajo «Deshaciendo… Van 2 min.», qué hacer. Vacía, no ocupa lugar. */
.nota-tope { display: block; margin-top: 4px; font-size: 13px; color: var(--texto-suave); white-space: normal; max-width: 32ch; }
.nota-tope:empty { display: none; }
/* Impl r1 (juez ux M1): el tope de Aplicar y Comprobar va en el estado del pie, que en el celular queda
   pegado abajo, junto a «Van 2 min 10 s.»; así se ve sin bajar la tabla. Vacío no ocupa lugar, pero no
   se oculta con display:none: es la región que el lector de pantalla anuncia al llenarse. */
.modal-foot .modal-estado .pv-tope { display: block; margin-top: 4px; font-size: 13px; color: var(--texto); }
.modal-foot .modal-estado .pv-tope:empty { margin: 0; }

/* ── Banda navy de Inicio ── */
.banda { background: var(--navy); border-radius: var(--radio-flotante); color: var(--texto-inverso); padding: 26px 28px 0; margin-bottom: 16px; }
.banda-cab { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
.banda h1 { font-size: 26px; line-height: 1.15; letter-spacing: -0.025em; font-weight: 800; color: var(--texto-inverso); margin: 0; }
.banda-cuenta { font-weight: 600; color: var(--texto-sobre-navy); }
.banda-meta { font-size: 13px; line-height: 1.5; color: var(--texto-sobre-navy); margin: 6px 0 0; max-width: 720px; }
.banda-meta .more { color: var(--accion-claro); } .banda-meta .more:hover { color: var(--texto-inverso); }
.banda-meta strong { color: var(--texto-inverso); }
.banda-acciones { flex: none; display: flex; gap: 10px; align-items: center; }
.kpis-banda { display: grid; grid-template-columns: 1.08fr 0.89fr 1.06fr 0.99fr; margin-top: 22px; border-top: 1px solid var(--filete-sobre-navy); }
.kpi-b { display: flex; flex-direction: column; gap: 6px; padding: 22px 18px 24px; min-width: 0; }
.kpi-b + .kpi-b { border-left: 1px solid var(--filete-sobre-navy); }
.kpi-b:first-child, .kpi-b.kpi-gasto { padding-left: 0; }
.kpi-b.kpi-hallazgos { padding-right: 0; }
.kpi-b .th-n { color: var(--rotulo-sobre-navy); display: inline-flex; align-items: center; gap: 6px; }
.kpi-b .th-n.con-punto { color: var(--texto-sobre-navy); }
.kpi-b .th-n.con-punto::before { content: ""; width: 6px; height: 6px; border-radius: var(--radio-pildora); background: var(--rotulo-sobre-navy); flex: none; }
.kpi-b[data-estado="fugas"] .th-n.con-punto::before, .kpi-b[data-estado="mal"] .th-n.con-punto::before { background: var(--peligro-claro); }
.kpi-b[data-estado="sin-fugas"] .th-n.con-punto::before, .kpi-b[data-estado="bien"] .th-n.con-punto::before { background: var(--exito-claro); }
.kpi-b[data-estado="atencion"] .th-n.con-punto::before { background: var(--aviso-claro); }
.kpi-b[data-estado="dinero"] .th-n.con-punto::before { background: var(--venta-claro); }
.kpi-b[data-estado="accion"] .th-n.con-punto::before { background: var(--accion-claro); }
.kpi-b[data-estado="sin-medir"] .th-n.con-punto::before { background: var(--rotulo-sobre-navy); }
.banda .mejora { color: var(--exito-claro); } .banda .empeora { color: var(--peligro-claro); }
.banda .peligro-n { color: var(--peligro-claro); } .banda .venta-n { color: var(--venta-claro); } .banda .exito-n { color: var(--exito-claro); } .banda .aviso-n { color: var(--aviso-claro); }
.kpi-b.kpi-desperdicio[data-estado="fugas"] .cifra-n { color: var(--peligro-claro); }
.cifra-n { font-size: 30px; font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; color: var(--texto-inverso); overflow-wrap: anywhere; }
.cifra-n.vacio, .cifra.vacio, .verdict .big.vacio { font-size: 20px; font-weight: 500; letter-spacing: 0; color: var(--texto-suave); line-height: 1.65; }
.cifra-n.vacio { color: var(--texto-sobre-navy); }
.cifra-n small { font-size: 15px; font-weight: 700; letter-spacing: 0; color: var(--rotulo-sobre-navy); }
.meta-n { font-size: 13px; line-height: 1.5; color: var(--texto-sobre-navy); margin: 0; }
.meta-n strong { font-weight: 700; color: var(--texto-inverso); }
/* P2 decidida en A (arreglo 23): la franja lleva CUATRO cifras de rendimiento —Gasto ·
   Conversiones (CPA) · Desperdicio · Hallazgos— y la Salud se queda en su tarjeta blanca
   debajo, con su barra y la fecha de la última auditoría. Las variantes B (v-kpi-salud) y
   C (v-kpi-cinco) y sus medias queries se retiran de aquí; el bloque de Salud de la banda
   sigue en el HTML, oculto, y el script run/banda3/capturar_banda3.mjs se inyecta las
   reglas de B y C si alguna vez hay que volver a medirlas. */
.kpi-b.kpi-salud { display: none; }

/* ── Cifras y salud sobre el lienzo ── */
.cifra { font-size: 30px; font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; color: var(--navy); white-space: nowrap; }
.cifra small { font-size: 15px; font-weight: 700; letter-spacing: 0; color: var(--texto-suave); }
.cifra-xl { font-size: 40px; }
.salud-card { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 28px; align-items: center; }
.salud-cab { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.barra { height: 8px; border-radius: var(--radio-pildora); background: var(--linea-suave); overflow: hidden; margin-top: 10px; }
.barra > span { display: block; height: 100%; border-radius: var(--radio-pildora); background: var(--accion); }
.barra[data-estado="bien"] > span { background: var(--exito); } .barra[data-estado="atencion"] > span { background: var(--aviso-barra); } .barra[data-estado="mal"] > span { background: var(--peligro); }
.estado-bien { color: var(--exito) !important; } .estado-atencion { color: var(--aviso) !important; } .estado-mal { color: var(--peligro) !important; } .estado-dinero { color: var(--venta-relleno) !important; }
.barra[data-estado="sin-medir"] > span { display: none; }
/* Arreglo 22 (juez 1 D7): la barra de ritmo ya no se confunde con la de salud.
   Distinta en las tres cosas que se ven: 26 px de alto contra 8, el rótulo DENTRO
   («Ritmo: 67,4 % del objetivo», navy sobre la pista) y una marca de objetivo al
   80 % del recorrido, porque la pista abarca el 125 % del objetivo — así una cuenta
   por encima del objetivo se ve pasar la marca. El relleno es una banda baja de
   6 px en el tono oscuro del estado, no la barra entera en dorado. */
.pacing-bar { position: relative; height: 26px; border-radius: var(--radio-pildora); background: var(--linea-suave); margin-top: 12px; overflow: hidden; }
.pacing-lbl { position: absolute; left: 12px; top: 0; height: 20px; line-height: 20px; font-size: 12px; font-weight: 700; color: var(--navy); white-space: nowrap; z-index: 1; }
.pacing-bar::after { content: ""; position: absolute; left: 80%; top: 0; bottom: 0; width: 2px; background: var(--navy); }
.pacing-fill { position: absolute; left: 0; bottom: 0; height: 6px; background: var(--accion); border-radius: var(--radio-pildora); }
.pacing-bar[data-estado="sobre_ritmo"] .pacing-fill { background: var(--peligro); }
.pacing-bar[data-estado="en_camino"] .pacing-fill { background: var(--exito); }
.pacing-bar[data-estado="bajo_ritmo"] .pacing-fill { background: var(--aviso); }
.pacing-estado { display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: var(--radio-pildora); font-size: 12px; font-weight: 700; }
.pacing-estado.baja { background: var(--exito-suave); color: var(--exito); }
.pacing-estado.media { background: var(--aviso-suave); color: var(--aviso); }
.pacing-estado.alta { background: var(--peligro-suave); color: var(--peligro); }
.pacing-estado.neutro { background: var(--papel-3); color: var(--texto-suave); }
.pacing-bar[data-estado="neutro"] .pacing-fill { background: var(--texto-suave); }   /* 5,43:1 sobre la pista */
.pacing-bar[data-estado="neutro"]::after { background: var(--texto-suave); }
/* App-lista r2 P6.13 (UI2-7): en el celular la marca del 100 % cruzaba el rótulo, que va dentro
   de la barra con `nowrap`. A 640 px o menos el rótulo sube arriba de la barra, la barra se
   angosta y la marca lleva su leyenda «100 %» debajo. */
/* App-lista r8 P5.8 (UI8-4): la leyenda «100 %» va bajo la marca en todos los anchos. Está en una
   franja aparte, debajo de la barra (que sigue con `overflow: hidden` en escritorio), alineada con la
   marca al 80 %. */
.pacing-escala { position: relative; height: 16px; margin-top: 3px; }
.pacing-marca-lbl { display: block; position: absolute; left: 80%; top: 0; transform: translateX(-50%);
                    font-size: 11px; line-height: 14px; color: var(--texto-suave); white-space: nowrap; }
@media (max-width: 640px) {
  .pacing-bar { height: 10px; margin-top: 30px; overflow: visible; }
  .pacing-lbl { top: -24px; left: 0; right: 0; height: auto; line-height: 18px; white-space: normal; }
}
/* App-lista r2 P6.1 y P6.8: «al menos» delante del gasto sin resultados, la línea de cuánto
   revisó la IA, la estimación unida a la tarjeta de presupuesto y las líneas de estado. */
.al-menos { font-size: .45em; font-weight: 600; color: var(--texto-suave); letter-spacing: 0; }
.ficha .cifra .al-menos { font-size: .6em; }
.cobertura { margin-top: 6px; font-size: 13px; }
.det-unido { margin-top: 6px; }
.lineas-estado { margin-top: 4px; }
.linea-estado { margin: 0 0 6px; font-size: 14px; color: var(--texto-suave); }
.mejora { color: var(--exito); } .empeora { color: var(--peligro); }
.dinero-recuperado { color: var(--venta-relleno); }
/* Fase 4 §6.1: la cifra de gasto evitado de Informes usaba --venta (#E9366D, 4,03:1).
   Pasa al mismo tono que la ficha de Inicio, --venta-relleno-hover (#A81C4B, 6,13:1),
   con la clase del sistema: `.ficha-dinero .cifra`. `.cifra-evitado` y `.evitado-total`
   se retiran. #E9366D queda solo como punto decorativo de 6 px. */
.cifra.cifra-dinero { color: var(--venta-relleno-hover); }
.importe { font-weight: 700; color: var(--navy); } .importe .estimado { font-weight: 500; color: var(--texto-suave); }
.spark { display: block; width: 100%; height: 44px; margin-top: 8px; }
.spark path { fill: none; stroke: var(--accion); stroke-width: 2; }
.spark .fillarea { fill: var(--accion-suave); stroke: none; }
.spark .dot { fill: var(--accion); }
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 18px; }
.kpi { min-width: 0; }
.kpi .v { font-size: 24px; font-weight: 800; color: var(--navy); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kpi .v.danger { color: var(--navy); } .kpi .v.success { color: var(--exito); }
.kpi .k { color: var(--texto-suave); font-size: 12px; margin-top: 2px; }

/* KPI claros (tarjeta blanca con filetes; Auditoría y resto de vistas) */
.kpis-clara { display: grid; grid-template-columns: repeat(4, 1fr); padding: 4px 0; }
.kpi-c { padding: 14px 20px; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.kpi-c + .kpi-c { border-left: 1px solid var(--linea-suave); }
.kpi-c:first-child { padding-left: 0; }
.kpi-c .cifra { font-size: 26px; white-space: normal; overflow-wrap: anywhere; }
.kpi-c .cifra small, .ficha .cifra small { font-size: 15px; font-weight: 700; letter-spacing: 0; color: var(--texto-suave); }
.kpi-c .th { color: var(--texto-suave); }
.kpi-c .meta { font-size: 13px; color: var(--texto-suave); }
/* Fase 4 §7.3: la banda de consumo del plan son TRES fichas, no cuatro */
.kpis-tres { grid-template-columns: repeat(3, 1fr); }
.kpis-dos { grid-template-columns: repeat(2, 1fr); }
.kpi-c .barra { margin-top: 8px; max-width: 200px; }
.plan-nombre { font-size: 18px; font-weight: 700; color: var(--navy); }

/* ── Veredicto (Auditoría) ── */
.verdict { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 32px; align-items: start; padding: 28px 32px; }
.verdict .lead { font-size: 14px; color: var(--texto-suave); font-weight: 600; }
.verdict .big { font-size: 46px; font-weight: 800; line-height: 1.02; letter-spacing: -0.03em; margin: 4px 0 6px; color: var(--peligro); }
.verdict .big .cur { font-size: 22px; font-weight: 700; color: var(--texto-suave); letter-spacing: 0; }
.verdict .big.sin-fugas { color: var(--exito); }
.verdict .big.sin-medir { color: var(--navy); }
/* r11 P1.2 (F11-4): «No lo pudimos revisar con IA» es una frase, no una cifra. */
.verdict .big.sin-ia { font-size: 32px; letter-spacing: -0.02em; }
.verdict .sub2 { color: var(--texto-suave); font-size: 14px; margin-bottom: 16px; }
.verdict .opp { font-size: 14px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--linea-suave); color: var(--tinta); }
.verdict .opp b { color: var(--venta-relleno); font-size: 14px; }
.verdict-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.fichas { display: flex; flex-direction: column; gap: 0; border-left: 1px solid var(--linea-suave); padding-left: 28px; }
.ficha { padding: 6px 0 14px; }
.ficha + .ficha, .ficha.ficha-salud { border-top: 1px solid var(--linea-suave); padding-top: 14px; }
.ficha .th { color: var(--texto-suave); display: block; margin-bottom: 4px; }
.ficha .cifra { color: var(--navy); }
/* T3 (arbitraje de la fase 5, los tres jueces): el veredicto de 46 px y esta ficha de 30 px
   son el MISMO dinero (mensual x 12) dicho dos veces; dos rojos no doblan la urgencia, la
   reparten. Se queda en rojo el titular; la ficha pasa a navy y conserva su punto rojo. */
.ficha.ficha-desperdicio .cifra:not(.cero):not(.vacio) { color: var(--navy); }
.th.punto::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: var(--radio-pildora); margin-right: 6px; vertical-align: 1px; background: var(--texto-suave); }
.th.punto-mal::before { background: var(--peligro); } .th.punto-bien::before { background: var(--exito); } .th.punto-atencion::before { background: var(--aviso); } .th.punto-dinero::before { background: var(--venta); } .th.punto-accion::before { background: var(--accion); }
.ficha .meta { font-size: 13px; color: var(--texto-suave); margin-top: 4px; }

/* Benchmark: pista gris, marcas de texto, marcador navy */
.bench { margin: 14px 0 4px; max-width: 560px; }
.bench .track { position: relative; height: 8px; border-radius: var(--radio-pildora); background: var(--linea-suave); }
.bench .marca { position: absolute; top: -3px; width: 1px; height: 14px; background: var(--texto-suave); }
.bench .mark { position: absolute; top: -5px; width: 3px; height: 18px; background: var(--navy); border-radius: 2px; margin-left: -1px; }
.bench .scale { display: flex; justify-content: space-between; font-size: 12px; color: var(--texto-suave); margin-top: 8px; }
.bench .you { font-weight: 700; color: var(--navy); }

/* ── Listas de hallazgos (Empieza por aquí · Tu plan) ── */
.lista { background: var(--superficie); border: 1px solid var(--linea); border-radius: var(--radio-tarjeta); overflow: hidden; }
.lista-fila { display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; gap: 18px; align-items: center; padding: 16px 24px; border-top: 1px solid var(--linea-suave); }
.lista-fila:first-child { border-top: 0; }
.lista-fila.step { min-height: 72px; }
.st-ttl { font-weight: 700; font-size: 15px; color: var(--navy); }
.st-why { color: var(--texto-suave); font-size: 13px; margin-top: 2px; }
.lista-fila .st-imp { text-align: right; min-width: 120px; }
.lista-fila .st-imp .n { font-weight: 700; font-size: 16px; white-space: nowrap; color: var(--navy); }
.lista-fila .st-imp .l { font-size: 12px; color: var(--texto-suave); }
.lista-fila .st-imp .n.good { color: var(--venta-relleno); }
.lista-fila .st-imp .n.warn { color: var(--peligro); }
.reco .imp.good { color: var(--venta-relleno); }
.verdict .opp .chip { vertical-align: 2px; margin-right: 4px; }
.lista-fila .st-imp .n.sin { font-weight: 500; color: var(--texto-suave); font-size: 13px; }
.plan-bloque .more { color: var(--accion-claro); }
.card > table th:first-child, .card > table td:first-child { padding-left: 24px; }
.card > table th:last-child, .card > table td:last-child { padding-right: 24px; }
.ficha .cifra.cero, .kpi-c .cifra.cero { color: var(--texto-suave); }

/* ── Hallazgos por cadencia (Auditoría) ── */
.grupo-area { padding: 0; }
.grupo-area + .grupo-area { border-top: 1px solid var(--linea-suave); }
.grupo-area > .area-titulo { font-size: 14px; font-weight: 700; color: var(--navy); padding: 16px 24px 0; }
.grupo-area > .area-titulo .count { color: var(--texto-suave); font-weight: 500; }
.reco { padding: 14px 24px 18px; border-top: 1px solid var(--linea-suave); }
.reco:first-of-type { border-top: 0; }
.grupo-area > .area-titulo + .reco { border-top: 0; padding-top: 8px; }
.reco .top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.reco .ttl { font-weight: 700; font-size: 15px; color: var(--navy); flex: 1; min-width: 200px; }
.reco .imp { font-weight: 700; color: var(--peligro); white-space: nowrap; }
.reco .det { color: var(--tinta); font-size: 14px; margin: 6px 0 0; }
.reco .body { min-width: 0; }
.why { font-size: 13px; color: var(--texto-suave); margin-top: 8px; line-height: 1.5; }
.why b { color: var(--navy); }
.where { font-size: 13px; color: var(--tinta); margin-top: 6px; }
.where b { color: var(--navy); }
.reco-cta { margin-top: 10px; }
.criteria-foot { font-size: 13px; color: var(--texto-suave); border: 1px solid var(--linea); border-radius: var(--radio-alerta); padding: 14px 16px; margin-top: 8px; line-height: 1.6; background: var(--superficie); }
.criteria-foot b { color: var(--navy); }

/* Patrones */
.patterns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.pat { display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px; border-radius: var(--radio-pildora); border: 1px solid var(--linea-fuerte); background: var(--superficie); font-size: 13px; color: var(--tinta); }
.pat b { font-weight: 700; color: var(--navy); } .pat .pc { color: var(--peligro); font-weight: 700; }
.pat .pn { color: var(--texto-suave); font-size: 12px; }
/* Lenguaje L9: el aviso del motor debajo de cada palabra suelta; la píldora crece en alto */
.pat.con-nota { height: auto; min-height: 36px; flex-wrap: wrap; row-gap: 2px; padding: 6px 14px; border-radius: var(--radio-alerta); max-width: 100%; }
.pat .pnota { flex-basis: 100%; font-size: 12px; color: var(--texto-suave); line-height: 1.35; }

/* ── Segmentado (SelectorCiclo) ── */
.seg { display: inline-flex; background: var(--superficie); border: 1px solid var(--linea-fuerte); border-radius: var(--radio-pildora); padding: 3px; gap: 2px; }
.seg-btn { border: 0; background: transparent; color: var(--navy); font-weight: 700; font-size: 13px; height: 36px; padding: 0 14px; border-radius: var(--radio-pildora); }
.seg-btn.active { background: var(--navy); color: var(--texto-inverso); }
.seg-btn .rec { font-size: 12px; color: var(--texto-suave); font-weight: 500; margin-left: 6px; }
.seg-btn.active .rec { color: var(--texto-sobre-navy); }
.seg-btn:disabled { opacity: 1; color: var(--texto-suave); }
/* Menú G1 (propuesta menu/r3, paso 1): filtros «Todas · Búsquedas · Presupuesto» de Optimizaciones.
   El filtro oculta bloques con `hidden`; varias filas llevan su propio display (grid, flex) que pisaría
   el [hidden]{display:none} del navegador. */
#optBody [data-ver][hidden] { display: none !important; }
.filtro-opt-fila { margin: 0 0 14px; }
.filtro-linea { margin: 0 0 14px; }
@media (max-width: 399px) { .seg.filtro-opt .seg-btn { padding: 0 6px; } .seg.filtro-opt .seg-btn .rec { margin-left: 4px; } }

/* ── Tablas de entidades ── */
.tscroll { overflow-x: auto; margin-top: 10px; border-radius: var(--radio-alerta); border: 1px solid var(--linea); background: var(--superficie); }
table.terms { width: 100%; border-collapse: collapse; font-size: 13px; display: table; min-width: 520px; margin: 0; }
table.terms th, table.terms td { padding: 10px 14px; white-space: normal; }
table.terms th.num, table.terms td.num, table.terms td.pv-st { white-space: nowrap; }
table.terms th { position: sticky; top: 0; z-index: 1; }
table.terms td.term { font-weight: 600; overflow-wrap: anywhere; }
table.terms td.ag { overflow-wrap: anywhere; }
/* r16 P5.6 (UI16-4): el grupo de anuncios de la exclusión, bajo la campaña, en la vista previa. */
table.terms td.ag .pv-grupo { display: block; margin-top: 2px; font-size: 13px; }
table.terms td.ag .pv-grupo[hidden] { display: none; }
table.terms th.chk, table.terms td.chk { width: 36px; padding-right: 0; }
.applybar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 14px 0 0; }
.applybar .nota-suave { margin-left: auto; }
.rule-cite { font-size: 14px; color: var(--tinta); margin-top: 10px; line-height: 1.55; }
.rule-cite b { color: var(--navy); }
/* r9 P6.4 (UI9-3): la remisión a otra fila, dentro de la frase, se ve como enlace. */
.rule-cite a.enlace-remision { text-decoration: underline; text-underline-offset: 2px; }
details.regla { margin-top: 4px; font-size: 13px; color: var(--texto-suave); }
details.regla > summary { cursor: pointer; list-style: none; color: var(--accion); font-weight: 700; display: inline-block; min-height: 28px; line-height: 28px; }
details.regla > summary::-webkit-details-marker { display: none; }
details.regla > summary::after { content: ""; display: inline-block; width: 6px; height: 6px; margin-left: 8px; border-right: 1.8px solid var(--accion); border-bottom: 1.8px solid var(--accion); transform: rotate(45deg); vertical-align: 3px; }
details.regla[open] > summary::after { transform: rotate(-135deg); vertical-align: -1px; }
details.regla > div { margin-top: 4px; line-height: 1.55; }
details.regla b { color: var(--navy); }

/* ── Bandeja: details/summary en grid ── */
.bandeja-cab { display: grid; grid-template-columns: minmax(0, 1fr) 190px 110px 100px 150px; gap: 14px; padding: 10px 24px; background: var(--accion-suave); border-radius: var(--radio-alerta); margin-bottom: 8px; }
.bandeja-cab > span:nth-child(3) { text-align: right; }
/* Fase 4 §5.3: en Historial la cuarta columna es «Estado» y lleva chip + meta («y 3 en
   otro estado»), que no caben en los 100 px de la bandeja. Misma pieza, otra reparto. */
.cab-historial, details.fila-historial > summary { grid-template-columns: minmax(0, 1fr) 160px 130px 180px 120px; }
/* El chip dominante y su «y 3 en otro estado» se apilan: en 170 px la frase envolvía
   dentro de la propia celda y partía en tres líneas. */
details.fila-historial .bj-sev { flex-direction: column; align-items: flex-start; gap: 3px; }
details.bandeja-fila { padding: 0; margin-bottom: 8px; overflow: visible; }
/* r14 P5.4 (UI14-1): al saltar a una fila (`goToReco`, block "start") el título queda debajo de la
   cabecera fija del celular (52 px) y no tapado por ella. */
details.bandeja-fila, details.bloque-dudas { scroll-margin-top: 64px; }
details.bandeja-fila > summary { display: grid; grid-template-columns: minmax(0, 1fr) 190px 110px 100px 150px; gap: 14px; align-items: center;
  padding: 14px 24px; min-height: 56px; cursor: pointer; list-style: none; border-radius: var(--radio-tarjeta); }
details.bandeja-fila > summary::-webkit-details-marker { display: none; }
details.bandeja-fila[open] { background: var(--fila-activa); border-color: var(--fila-activa); }
details.bandeja-fila[open] > summary { border-radius: var(--radio-tarjeta) var(--radio-tarjeta) 0 0; }
.bj-titulo { font-weight: 700; font-size: 15px; color: var(--navy); display: flex; align-items: center; gap: 10px; min-width: 0; }
.bj-titulo::before { content: ""; width: 7px; height: 7px; border-right: 1.8px solid var(--texto-suave); border-bottom: 1.8px solid var(--texto-suave); transform: rotate(-45deg); flex: none; transition: transform var(--transicion); margin-right: 2px; }
details.bandeja-fila[open] .bj-titulo::before { transform: rotate(45deg); }
.bj-titulo span { min-width: 0; }
/* App-lista r11 P1.3 (decisión 3): bloque plegado «La IA duda de estas N búsquedas» en Búsquedas.
   Misma flecha que las filas de la lista; el monto va en la misma línea. */
details.bloque-dudas > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
details.bloque-dudas > summary::-webkit-details-marker { display: none; }
details.bloque-dudas[open] .bj-titulo::before { transform: rotate(45deg); }
details.bloque-dudas .dudas-nota { margin: 12px 0 0; }
/* r14 P5.10 (UI14-4): el separador del gasto va aquí y no en el texto. Solo en ancho, donde el
   gasto queda en la misma línea que el título; en el celular baja de línea sin «·». */
/* Juez r14 P5 (código 4): el corte es el de 760 px, donde la fila se apila y `.bj-ent` deja de
   recortarse en 2 líneas; por encima, el «·» separa y el gasto sigue en la misma línea. */
@media (min-width: 761px) { details.bloque-dudas .gasto-dudas::before, .bj-ent .monto-marcadas::before { content: "· "; } }
.bj-ent .monto-marcadas { white-space: nowrap; }
@media (max-width: 760px) { .bj-ent .monto-marcadas { display: block; } details.bloque-dudas .gasto-dudas { flex-basis: 100%; } }
/* Con las dudas marcadas, «X y N más · $monto» puede ocupar 3 líneas: no se corta el monto. */
details.bandeja-fila[data-dudas="1"] .bj-ent { -webkit-line-clamp: 3; }
/* App-lista r12 P5.2-P5.4: el grupo de dudas con casillas en Optimizaciones, su aviso de perfil
   vacío y el botón que lleva a él desde Búsquedas. */
details.bloque-dudas-opt .dudas-nota { margin: 0 0 10px; }
.aviso-perfil-dudas { margin: 12px 0 0; }
details.bloque-dudas-opt .aviso-perfil-dudas { margin: 0 0 12px; }
/* r12 P5.5 (C12-3): en el Historial, con rótulos distintos, cada cifra dice el suyo. */
.rotulo-fila { display: block; font-size: 12px; font-weight: 400; line-height: 1.3; }
.bj-ent { font-size: 13px; color: var(--navy); font-weight: 600; min-width: 0; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* T2 (arbitraje de la fase 5, los tres jueces): el monto de una fila es dinero RECUPERABLE,
   no una pérdida ya contabilizada, y 18 filas rojas convierten el rojo en papel pintado. Va
   navy 700 en las tres pantallas —mapeo v3 regla 2 y spec §3.5—; el color de la fila lo pone
   el chip de severidad. Se conservan `.ganar` (rosa, dinero bueno) y `.sin` (gris). */
.bj-imp { text-align: right; font-weight: 700; color: var(--navy); white-space: nowrap; }
.bj-imp.ganar { color: var(--venta-relleno); }
/* Barra de resumen de pantalla (misma pieza que la de Optimizaciones) */
.resumen-barra { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
/* «sin importe estimado» y «sin gasto evitado» no caben en los 110 px de la columna y se
   salían de su celda (juez 1, F4: 128 > 110). Sin `nowrap` envuelven dentro de la columna. */
.bj-imp.sin { font-weight: 500; color: var(--texto-suave); font-size: 13px; white-space: normal; }
/* Lo mismo con «Se resolvió sola» en la columna de estado del Historial (112 > 100) */
.bj-sev { display: flex; align-items: center; min-width: 0; }
.bj-sev .chip { white-space: normal; height: auto; min-height: 24px; padding: 3px 10px; line-height: 1.25; }
.bj-acc { font-size: 13px; color: var(--texto-suave); display: flex; align-items: center; justify-content: flex-end; gap: 8px; white-space: nowrap; }
/* Fila abierta: el botón del resumen pasa a «Cerrar» (el «Aplicar…» vive en la barra de acciones) */
/* App-lista r3 P6.10 (UI3-9): el <summary> es el único control de la fila. Lo que parece un
   botón dentro de él es un <span aria-hidden> con el mismo aspecto que `button.ghost.btn-sm`. */
.boton-fila { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--alto-boton-sm);
              padding: 0 14px; font-size: 13px; font-weight: 700; border-radius: var(--radio-pildora); white-space: nowrap;
              border: 1px solid var(--linea-fuerte); background: var(--superficie); color: var(--accion); cursor: pointer;
              transition: background-color var(--transicion), color var(--transicion); }
summary:hover .boton-fila { background: var(--accion-suave); color: var(--accion-hover); }
/* App-lista r3 P6.10 (UI3-3): la ruta larga del chip «Lo cambias tú en Google Ads · …» baja de línea
   en vez de salirse de la pantalla (a 390 px la página medía 578 px de ancho). */
.como-aplica .chip { white-space: normal; height: auto; min-height: 24px; padding: 4px 10px; line-height: 1.35; max-width: 100%; }
.ap-cerrar { display: none; }
details.bandeja-fila[open] > summary .ap-abrir { display: none; }
details.bandeja-fila[open] > summary .ap-cerrar { display: inline; }
.cambio { font-size: 12px; font-weight: 700; color: var(--accion-hover); margin-left: 6px; }
.bj-detalle { padding: 2px 24px 20px; }
/* Arreglo 5 (juez 1 D4, juez 3 defecto 10): con muchas entidades la fila abierta
   medía 5.103 px y «Aplicar» quedaba a 5.039 px de scroll. La lista se acota y se
   desplaza dentro de la fila; es una región alcanzable por teclado y con nombre. */
.bj-detalle .tscroll { background: var(--superficie); max-height: 420px; overflow-y: auto; }
/* P6.10: la tabla de tipos de recomendaciones de Google es corta; sin tope no corta la última fila. */
.bj-detalle .tscroll.sin-tope { max-height: none; }
/* Arreglo 6: la casilla, dentro de un <label> de 24 × 24 px (WCAG 2.2 SC 2.5.8, buena práctica) */
.chkbox { display: inline-flex; align-items: center; justify-content: center;
          width: 24px; height: 24px; padding: 3px; cursor: pointer; }
.bj-detalle .rule-cite { margin-top: 2px; }
.snooze-menu { position: relative; display: inline-block; }
.snooze-list { position: absolute; left: 0; top: calc(100% + 6px); z-index: 40; background: var(--superficie);
               border: 1px solid var(--linea); border-radius: var(--radio-flotante); box-shadow: var(--sombra-2);
               min-width: 240px; padding: 6px; display: none; }
.snooze-list.open { display: block; }
/* G2 r1 (juez ux U3): «Posponiendo 3 de 12…» no mueve la barra con cada número. */
.snooze-menu > button[aria-busy="true"] { font-variant-numeric: tabular-nums; min-width: 12.5em; }
.snooze-item { display: flex; width: 100%; justify-content: flex-start; height: 44px; padding: 0 12px; border: 0; border-radius: var(--radio-campo); background: transparent; font-size: 14px; color: var(--navy); font-weight: 600; }
.snooze-item:hover { background: var(--accion-suave); color: var(--accion-hover); }
.bj-status { font-size: 13px; color: var(--texto-suave); }
/* Arreglo 4 (juez 1 D8, juez 2 defecto 4): a ≤640 px el thead se oculta y con él
   desaparecía «Seleccionar todas», de la pantalla y del recorrido con Tab. El mismo
   control vive encima de la lista, visible SOLO en móvil — ahí arriba y no en la barra
   de acciones para que en el Tab vaya ANTES de las casillas, como el thead en escritorio
   (juez 2, ronda 2). */
.bj-todas-m { display: none; }
.bj-todas-m .bj-todas-n { color: var(--texto-suave); font-weight: 500; }
.pospuestas { margin-top: 14px; }
.pospuesta-fila { display: flex; align-items: center; gap: 12px; padding: 12px 24px; border-top: 1px solid var(--linea-suave); font-size: 14px; }
.pospuesta-fila:first-child { border-top: 0; }
.pospuesta-fila .ttl { flex: 1; font-weight: 600; color: var(--navy); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Arreglo 2: el número de lo marcado SIEMPRE se ve en el botón (antes .ap-n estaba
   en display:none porque solo se encendía en la variante que Victor descartó). */
/* P4 (variante): sin casillas en la fila; «Aplicar las n» y elegir en el modal */
html.v-casillas-modal .bj-detalle .chk, html.v-casillas-modal .bj-detalle .bjchk { display: none; }
.pv-chk { display: none; }
html.v-casillas-modal .pv-chk { display: table-cell; }

/* ── Planes (TarjetaPlan + SelectorCiclo) ── */
/* Arreglo 11 (juez 1 D5, juez 2 defecto 5): con repeat(5, minmax(0,1fr)) las tarjetas
   llegaban a 136 px entre 761 y 1023 px y los botones y la cabecera se salían de su caja.
   Con auto-fit + un mínimo, la rejilla baja sola de columnas cuando no caben — y a 1440,
   1280 y 1180 siguen siendo CINCO en fila (la elección de Victor), medido. */
.planes-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; align-items: stretch; }
html.v-planes-4-1 .planes-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
html.v-planes-4-1 .plan.plan-pro { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 28px; }
html.v-planes-4-1 .plan.plan-pro .rasgos { columns: 2; }
/* R2-2 (juez 1 y juez 2, ronda 2): donde la rejilla no da para cinco columnas, el reflujo
   dejaba Pro sola abajo a la izquierda con tres cuartos de fila vacíos, y el destacado
   «Escala» pasaba a leerse como el tope del catálogo. Pro pasa a ocupar la fila entera,
   igual que ya hace la variante v-planes-4-1. Son dos tramos porque la barra lateral
   desaparece a ≤1023 px y la rejilla vuelve a cinco: medido, 4 columnas en 761-887 px y
   en 1024-1143 px, cinco en 888-1023 y desde 1144. */
@media (min-width: 761px) and (max-width: 887px), (min-width: 1024px) and (max-width: 1143px) {
  .plan.plan-pro { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 28px; }
  .plan.plan-pro .rasgos { columns: 2; column-gap: 28px; }
  .plan.plan-pro > div:first-child, .plan.plan-pro > div:nth-child(2) { flex: none; }
  .plan.plan-pro button { width: auto; min-width: 180px; }
}
.plan { display: flex; flex-direction: column; gap: 10px; padding: 22px 20px; min-width: 0; }
.plan .plan-cab { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.plan .plan-cab > * { min-width: 0; max-width: 100%; }
/* El chip de la cabecera («Para tu gasto», «Tu plan») hereda `white-space: nowrap` de .chip y
   con tarjetas de 160-170 px se salía de su propia píldora: aquí puede partirse en dos líneas. */
.plan .plan-cab .chip { white-space: normal; height: auto; min-height: 24px; padding: 4px 10px; line-height: 1.25; text-align: center; }
.plan h2 { margin: 0; font-size: 17px; }
.plan .precio { font-size: 30px; font-weight: 800; color: var(--navy); letter-spacing: -0.03em; }
.plan .precio-meta { color: var(--texto-suave); font-size: 13px; }
/* Arreglo 11: con line-height 1.9 y sin separación, un rasgo de dos líneas se leía
   pegado al siguiente en TODOS los anchos (juez 2). */
.rasgos { color: var(--texto); font-size: 13px; display: grid; gap: 6px; line-height: 1.45; flex: 1; }
.rasgos > * { line-height: 1.45; }
.plan.destacada { background: var(--navy); border-color: var(--navy); color: var(--texto-inverso); }
.plan.destacada h2, .plan.destacada .precio { color: var(--texto-inverso); }
.plan.destacada .precio-meta, .plan.destacada .rasgos { color: var(--texto-sobre-navy); }
.plan.destacada .chip.info { background: var(--accion-suave); color: var(--navy); }
.plan.plan-actual { border-color: var(--linea); }
/* Pago anual: selector mensual/anual arriba de las tarjetas y la línea de lo que se ahorra. */
.selector-periodo { margin: 0 0 12px; }
.plan .precio-ahorro { display: block; margin-top: 2px; }
/* «A medida»: fuera de la rejilla de cinco (que está medida para cinco tarjetas), a lo ancho. */
.plan-a-medida { display: flex; align-items: center; gap: 16px 28px; flex-wrap: wrap; margin-top: 14px; padding: 18px 20px; }
.plan-a-medida .a-medida-texto { flex: 1 1 280px; min-width: 0; }
.plan-a-medida h2 { margin: 0 0 4px; font-size: 17px; }
.plan-a-medida .plan-cab { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.plan-a-medida .plan-cab h2 { margin: 0; }
.plan-a-medida p { margin: 0; font-size: 13px; color: var(--texto); line-height: 1.45; }
.plan-a-medida button { white-space: normal; height: auto; min-height: var(--alto-boton); max-width: 100%; overflow-wrap: anywhere; }
/* Arreglo 11: el texto del botón se parte en vez de derramarse fuera de la tarjeta
   (mismo mecanismo que fallaría con el texto al 200 %, WCAG 1.4.4). */
.plan button { width: 100%; white-space: normal; padding: 0 12px; height: auto; min-height: var(--alto-boton); }
.plan .plan-cab, .plan h2, .plan .precio { overflow-wrap: anywhere; }
.planes-cab { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.planes-pie { text-align: center; color: var(--texto-suave); font-size: 13px; margin-top: 28px; }

/* ── Modales ── */
.modal-overlay { position: fixed; inset: 0; background: var(--velo); z-index: 60; display: grid; place-items: center; padding: 24px; }
.modal-overlay[hidden] { display: none; }
.modal-box { background: var(--superficie); border-radius: var(--radio-tarjeta); box-shadow: var(--sombra-3); max-width: 760px; width: 100%; max-height: 86vh; overflow: auto; padding: 24px 28px; }
.modal-box h2 { margin-bottom: 8px; }
/* Fase 4 §8.4: el hueco vertical entre el párrafo y el pie del modal venía del margen de
   `.sub`, que en un diálogo sobra: el pie ya trae su propia separación y su filete. */
.modal-box h2 + .sub { margin-bottom: 0; }
/* La caja recibe el foco al abrir el diálogo, como el panel del menú móvil: no es un control
   y nadie tabula hasta ella, así que el anillo se queda en lo que hay dentro. */
#modalBox:focus, #modalBox:focus-visible { outline: none; }
.modal-foot { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--linea-suave); }
.modal-foot .spacer { flex: 1; }
/* App-lista r11 P1.13 (UI11-3): en portátiles de 1366×768 y 1280×720 «Aplicar» y «Comprobar»
   quedaban debajo del borde de la ventana. El pie queda pegado abajo, con fondo, también en
   escritorio (como ya pasaba en ≤640 px). Los márgenes negativos cubren el relleno de la caja. */
.modal-overlay:not(.pantalla-plena) .modal-foot { position: sticky; bottom: -24px; z-index: 1;
  background: var(--superficie); margin: 18px -28px -24px; padding: 12px 28px 24px; }
/* La nota de reversibilidad va a la izquierda del botón de aplicar y se lleva el hueco
   sobrante: sin esto, con «Validar sin aplicar» + «Cancelar» + «Aplicar n cambios» la fila
   se pasaba de los 760 px del diálogo y el primario caía a una segunda línea. */
.modal-foot .nota-suave { flex: 1 1 180px; text-align: right; }
.modal-foot .msg-peligro, .modal-foot #pvStatus { min-width: 0; }
/* U3 (P6.2): el resultado de «Comprobar» y la nota van en su propia línea, arriba de los
   botones; así «Aplicar» no se descuelga a otra línea cuando el resumen es largo. */
.modal-foot .modal-estado { flex: 1 1 100%; margin: 0; text-align: right; }
.modal-foot .modal-estado:empty { display: none; }
.modal-foot .modal-estado .nota-suave { text-align: inherit; display: block; }
/* El display:block de arriba pisa el [hidden]{display:none} del navegador: sin esto,
   «Queda en el Historial y se puede deshacer.» se seguía viendo al comprobar y cuando
   Aplicar se cortaba, aunque la página la marcara oculta (visual synsation r2, M1). */
.modal-foot .modal-estado .nota-suave[hidden] { display: none !important; }
.modal-foot .modal-estado #pvStatus:empty { display: none; }
/* U2 (P6.3): «Cerrar» arriba en todos los diálogos; queda visible al desplazar la hoja. */
.modal-cerrar { float: right; position: sticky; top: 0; z-index: 2; width: 44px; height: 44px; margin: -12px -14px 0 8px;
  display: inline-grid; place-items: center; padding: 0; border: 0; border-radius: var(--radio-pildora);
  background: var(--superficie); color: var(--texto-suave); cursor: pointer; }
.modal-cerrar:hover { color: var(--navy); background: var(--papel); }
.modal-cerrar svg { width: 20px; height: 20px; }
/* Visual r1 B4: mientras se desconecta, «Cancelar» y la ✕ se ven inactivos (y no cambian al pasar el mouse). */
button.fantasma:disabled, .modal-cerrar:disabled { color: var(--texto-deshabilitado); background: transparent; cursor: not-allowed; }
/* P6.19: el CPA objetivo o el ROAS objetivo, junto a la estrategia */
.linea-objetivo { margin: 4px 0 8px; font-size: 13px; }
.msg-peligro { color: var(--peligro); font-weight: 600; } .msg-aviso { color: var(--tinta); }
.texto-error { color: var(--peligro); }

/* ── Formularios y campos ── */
label.field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--texto-suave); font-weight: 600; }
/* Fase 4 §7.3: la aclaración larga baja del rótulo a un texto de ayuda de 12 px, para que
   los rótulos quepan en una línea y las dos columnas no se desalineen. */
.field-ayuda { font-size: 12px; font-weight: 500; color: var(--texto-suave); line-height: 1.4; }
.campos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.campos .ancho-total { grid-column: 1 / -1; }
.grupo-campos + .grupo-campos { border-top: 1px solid var(--linea-suave); margin-top: 20px; padding-top: 18px; }
.grupo-campos > h3 { margin: 0 0 12px; }
.card-pie { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; border-top: 1px solid var(--linea-suave); margin-top: 20px; padding-top: 16px; }

/* ── Login y 404: las dos pantallas sin panel (fase 4 §1 y §12) ── */
/* El login era un modal de 420 px sobre un velo translúcido y detrás se veía la aplicación
   vacía. Ahora es una pantalla: fondo del lienzo opaco y tarjeta blanca sin sombra. */
.pantalla-plena { background: var(--accion-suave); z-index: 80; }
.pantalla-plena .caja-centrada { box-shadow: none; max-width: 420px; width: 100%; text-align: center; }
.marca-centrada { height: 30px; width: auto; display: block; margin: 0 auto 14px; }
.pie-endoso { color: var(--texto-suave); font-size: 12px; text-align: center; margin: 18px 0 0; }
/* El estado del login: nota gris mientras entra, alerta a la izquierda cuando falla */
#loginStatus .alerta { text-align: left; margin: 14px 0 0; }
#loginStatus .area-muted { margin: 12px 0 0; }

/* ── Selector de cuentas post-OAuth (fase 4 §2.5) ── */
.sel-buscar { margin-bottom: 10px; }
.sel-lista { border: 1px solid var(--linea); border-radius: var(--radio-campo); }
.sel-cab { grid-template-columns: minmax(0, 1fr) 140px 36px; gap: 12px; padding: 8px 14px; margin-bottom: 6px; }
.sel-cab > span:nth-child(2) { text-align: right; }
.sel-cab > span:nth-child(3) { text-align: left; }
.sel-fila { display: grid; grid-template-columns: minmax(0, 1fr) 140px 36px; gap: 12px; align-items: center;
            padding: 10px 14px; border-bottom: 1px solid var(--linea-suave); cursor: pointer; }
.sel-fila:last-child { border-bottom: 0; }
/* Ya conectada se dice con un chip gris, no con opacidad: la fila conserva su contraste
   y solo la casilla queda inerte (antes `opacity:.5` tumbaba nombre e importe bajo AA). */
.sel-fila.conectada { cursor: default; }
.sel-nombre { font-weight: 600; font-size: 15px; color: var(--navy); overflow-wrap: anywhere;
              display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sel-importe { text-align: right; font-weight: 700; color: var(--navy); }
.sel-importe.sin { font-weight: 500; font-size: 13px; color: var(--texto-suave); }
.sel-pager { display: flex; justify-content: center; align-items: center; gap: 8px; margin: 10px 0 4px; }

/* ── Cuentas conectadas (Configuración §7.3) ── */
.cuenta-fila { display: flex; align-items: center; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--linea-suave); }
.cuenta-fila:first-of-type { padding-top: 4px; }
.cuenta-nombre { font-weight: 600; font-size: 15px; color: var(--navy); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cuenta-error { color: var(--peligro); font-size: 13px; margin-top: 2px; }
.cuenta-acciones { display: flex; gap: 8px; flex-wrap: wrap; flex: none; }
.cuenta-pie { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; border-top: 1px solid var(--linea-suave); margin-top: 6px; padding-top: 14px; }

/* ── Pasos del arranque (fase 4 §2.1): tres FILAS desiguales dentro de una `.lista`,
   no tres columnas iguales con cuadrado numerado (rúbrica B06), y sin `opacity:.55`
   (que tumbaba el contraste del texto gris del paso pendiente). ── */
.paso-fila { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px; align-items: center;
             padding: 16px 0; border-top: 1px solid var(--linea-suave); }
.paso-fila:first-child { border-top: 0; }
.card.plan-actual { border-color: var(--linea); }
.precio { font-size: 30px; font-weight: 800; color: var(--navy); }
/* Visual r1 B6: sobre el fondo lavanda (--accion-suave) el gris claro (--papel-3) casi no se veía; con
   --linea-fuerte y sin bajar tanto la opacidad, los bloques se distinguen también sobre las tarjetas blancas. */
.skel { height: 14px; border-radius: 7px; background: var(--linea-fuerte); animation: sk 1.2s infinite alternate; margin: 10px 0; }
@keyframes sk { 0% { opacity: 1 } 100% { opacity: .6 } }
.view { display: none; } .view.active { display: block; }
.glifo { display: inline-block; vertical-align: -2px; }
.reco-flash { animation: recoflash 1.6s ease-out; }
@keyframes recoflash { 0%, 15% { outline: 3px solid var(--accion); outline-offset: 2px; } 100% { outline: 3px solid transparent; } }
.spacer { flex: 1; }

/* ── Responsive (la barra móvil completa llega en la fase 3) ── */
/* ── Menú de móvil (< 1024 px) · fase 3 ────────────────────────────────────
   Antes, por debajo de 1024 la barra lateral se apilaba arriba y el menú quedaba
   en una fila larga. Ahora hay cabecera compacta con el lockup, panel navy que
   abre la hamburguesa —que ES la barra lateral, con su selector de cuenta y su
   bloque de plan— y barra inferior con los cuatro destinos del hábito. */
/* Synsation fila 8 (6-oct-2026): textos que nombran dónde está algo. En computadora el selector está en
   la barra de la izquierda; en el celular esa barra vive dentro del menú. Se escriben los dos y cada
   pantalla muestra el suyo (oculto con display:none, el lector de pantalla tampoco lo lee). */
.solo-movil { display: none; }
@media (max-width: 1023px) {
  .app { grid-template-columns: 1fr; }
  .filtro-opt .seg-btn { min-height: 44px; }   /* Menú G1: los filtros de Optimizaciones, 44 px para tocar */
  .solo-escritorio { display: none; }
  .solo-movil { display: inline; }

  .mm-cab { display: flex; align-items: center; justify-content: space-between; gap: 12px;
            position: fixed; inset: 0 0 auto 0; z-index: 50; height: 52px; padding: 0 14px;
            background: var(--superficie); border-bottom: 1px solid var(--linea-suave); }
  body.mm-abierto .mm-cab { background: var(--navy); border-bottom-color: transparent; }
  .mm-marca { display: flex; align-items: center; min-width: 0; }
  /* r14 P5.5 (UI14-2): la cuenta activa, entre el logo y el menú. Ocupa lo que queda y se recorta. */
  .mm-cuenta { flex: 1 1 auto; min-width: 0; height: 44px; padding: 0 8px; border: 0; background: transparent;
               color: var(--navy); font: inherit; font-size: 14px; font-weight: 700; text-align: right; cursor: pointer;
               border-radius: var(--radio-pildora); }
  .mm-cuenta[hidden] { display: none; }
  .mm-cab .mm-marca, .mm-cab .mm-boton { flex: 0 0 auto; }   /* el logo y el menú no se achican: se recorta el nombre */
  .mm-cuenta:hover { background: var(--papel-3); }
  .mm-cuenta-nombre { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Juez r14 P5 (texto 8): con el menú abierto el selector ya está a la vista; el nombre no se repite
     ni queda un botón que no hace nada. */
  body.mm-abierto .mm-cuenta { visibility: hidden; }
  /* Los dos selectores llevan la clase del contenedor: si no, `.mm-marca img` (0,1,1)
     le gana a `.mm-logo-oscuro` (0,1,0) y se ven los dos lockups a la vez. */
  .mm-marca img { height: 26px; width: auto; display: block; }
  .mm-marca .mm-logo-oscuro { display: none; }
  body.mm-abierto .mm-marca .mm-logo-claro { display: none; }
  body.mm-abierto .mm-marca .mm-logo-oscuro { display: block; }
  /* 44 × 44 de objetivo táctil; el margen negativo deja el icono en su sitio */
  .mm-boton { width: 44px; height: 44px; margin-right: -8px; padding: 0; border: 0; background: transparent;
              color: var(--navy); border-radius: var(--radio-pildora); cursor: pointer;
              display: inline-flex; align-items: center; justify-content: center; }
  .mm-boton:hover { background: var(--papel-3); }
  body.mm-abierto .mm-boton { color: var(--texto-inverso); }
  body.mm-abierto .mm-boton:hover { background: var(--navy-activo); }
  body.mm-abierto .mm-boton:focus-visible { outline-color: var(--texto-inverso); }
  .mm-hamburguesa { display: flex; flex-direction: column; gap: 4px; }
  .mm-hamburguesa > span { display: block; width: 18px; height: 2px; background: currentColor; border-radius: 2px; }
  .mm-aspa { display: none; }
  body.mm-abierto .mm-hamburguesa { display: none; }
  body.mm-abierto .mm-aspa { display: block; }

  .mm-velo { display: block; position: fixed; inset: 52px 0 0; z-index: 45; background: var(--velo); }
  .mm-velo[hidden] { display: none; }

  /* El panel es la barra lateral de siempre, desplegada bajo la cabecera */
  /* El panel recibe el foco al abrirse, como un diálogo: no lleva anillo porque no es un
     control y nadie puede tabular hasta él; el anillo se queda en lo que hay dentro. */
  #mmPanel:focus, #mmPanel:focus-visible { outline: none; }
  .sidebar { display: none; position: fixed; inset: 52px 0 auto 0; z-index: 48;
             height: auto; max-height: calc(100dvh - 52px); overflow-y: auto;
             padding: 14px 14px 20px; box-shadow: var(--sombra-3);
             border-radius: 0 0 var(--radio-flotante) var(--radio-flotante); }
  body.mm-abierto .sidebar { display: flex; }
  .sidebar .logo { display: none; }      /* el lockup ya está en la cabecera */
  /* Menú G3 (paso 7, D2): las 5 secciones están en la barra de abajo; el panel no las repite. */
  .sidebar .nav { display: none; }
  .side-foot { margin-top: 14px; }
  .combo-list { width: 100%; max-width: none; }

  /* Por debajo del velo (z 45): con el menú abierto la barra queda tapada, como el resto
     de la página, y no se puede pulsar un destino «a través» del menú. */
  .mm-barra { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
              position: fixed; inset: auto 0 0 0; z-index: 40; min-height: 56px;
              background: var(--superficie); border-top: 1px solid var(--linea-suave);
              padding-bottom: env(safe-area-inset-bottom, 0px); }
  /* Menú G3 (paso 7): 5 botones de 1/5 del ancho (72 px a 360). El nombre se parte solo por el guion
     escrito (&shy;), nunca a mitad de sílaba; arriba queda lugar para el globo. */
  .mm-barra a { position: relative; display: flex; align-items: center; justify-content: center; min-height: 56px;
                padding: 14px 2px 4px; text-align: center; font-size: 11px; font-weight: 700; line-height: 1.2;
                color: var(--texto-suave); overflow-wrap: normal; hyphens: manual; -webkit-hyphens: manual; }
  .mm-globo { position: absolute; top: 3px; left: 50%; margin-left: 4px; min-width: 18px; height: 16px; padding: 0 5px;
              border-radius: var(--radio-pildora); background: var(--accion); color: var(--texto-inverso);
              font-size: 10px; font-weight: 800; line-height: 16px; font-variant-numeric: tabular-nums; }
  .mm-globo[hidden] { display: none; }
  .mm-barra a:hover { color: var(--navy); }
  /* Menú visual r1 (B2): la sección activa no se marca solo con el color: lleva una raya de 3 px
     arriba del botón. */
  .mm-barra a.active { color: var(--accion); box-shadow: inset 0 3px 0 var(--accion); }

  .main { padding-top: 52px; }
  .topbar { padding: 14px 16px 0; flex-wrap: wrap; row-gap: 8px; }
  /* r15 P5.9 (UI15-6): bajo 1024 px el título ocupa su fila y el botón con la inicial va en la de
     abajo, a la derecha, en todas las vistas (antes dependía del largo del título). */
  .topbar .titulo-barra { flex: 1 0 100%; }
  .topbar .spacer { display: none; }
  /* Jueces r15 P5 (código 1): la línea de estado va debajo, en su fila, para que el botón no se mueva. */
  .topbar-acciones { margin-left: auto; order: 1; }
  .topbar #status { order: 2; flex: 1 0 100%; min-width: 0; }
  .topbar #status:empty { display: none; }
  .content { padding: 14px 16px 88px; }   /* 88 = 56 de la barra inferior + aire */
}
@media (max-width: 640px) {
  /* Fase 4 §8: el modal es una hoja completa —nace arriba, sin radio y con el pie visible—
     en vez de una caja flotante de 86vh con el velo asomando por los cuatro lados.
     El login y el 404 quedan fuera: son pantallas, no diálogos, y llevan su propio margen. */
  .modal-overlay:not(.pantalla-plena) { padding: 0; place-items: stretch; }
  .modal-overlay:not(.pantalla-plena) > .modal-box { max-width: none; width: 100%;
     max-height: 100dvh; min-height: 100dvh; border-radius: 0; padding: 18px 16px 24px; }
  .pantalla-plena { padding: 24px 16px; }
  /* Un aviso con botón: el botón baja a su propia línea ENTERA. Con el botón a su lado,
     el texto se comprimía hasta una palabra por línea (min-width:0 + flex-basis 0). */
  .alerta { flex-wrap: wrap; }
  .alerta > span.alerta-txt { flex: 1 1 calc(100% - 18px); }   /* el punto de 8 px + su hueco de 10 */
  .alerta > .spacer { display: none; }
  .alerta > button { flex: 0 0 auto; margin-left: 18px; }
  /* La barra de resumen no empuja su botón a una línea suelta */
  .resumen-barra > .spacer { display: none; }
  /* Fase 4 §5.7: cinco opciones de filtro no caben en una línea de 390 px */
  .seg { flex-wrap: wrap; }
  /* Menú G1: los 3 filtros de Optimizaciones en una línea; si no entran, relleno de 10 px solo aquí.
     Juez dueño r1 (D1): a 360 px, con números de 2 o 3 cifras, 10 px no alcanzaban; debajo de 400 px
     el relleno baja a 6 px, y si aun así no entran el último botón baja de línea (nunca se sale de
     la pantalla). */
  .filtro-opt .seg-btn { padding: 0 10px; }
  /* Selector de cuentas: nombre + chip / ID · divisa / gasto con su rótulo */
  .sel-cab { display: none; }
  .sel-fila { grid-template-columns: minmax(0, 1fr) 36px; gap: 6px 12px; }
  .sel-fila > .sel-datos { grid-column: 1; grid-row: 1; }
  .sel-fila > .chkbox { grid-column: 2; grid-row: 1; }
  .sel-fila > .sel-importe { grid-column: 1 / -1; grid-row: 2; text-align: left; }
  .sel-fila > .sel-importe::before { content: "30 días: "; color: var(--texto-suave); font-weight: 500; font-size: 13px; }
  .sel-fila > .sel-importe.sin::before { content: none; }
  .sel-fila > .sel-importe .mini { display: none; }
  /* Cuentas conectadas: los botones abajo, a ancho completo y con 44 px de alto */
  .cuenta-fila { display: grid; grid-template-columns: 1fr; gap: 10px; }
  .cuenta-acciones { display: grid; grid-template-columns: 1fr; }
  .cuenta-acciones > button { width: 100%; }
  /* Tablas de entidades apiladas por fila: nada queda fuera de pantalla (juez E O9) */
  .tscroll { overflow: visible; border: 0; background: transparent; }
  /* Arreglo 5: acotada también apilada (con 60 entidades la fila medía 8.429 px) */
  .bj-detalle .tscroll { max-height: 60vh; overflow-x: hidden; overflow-y: auto; }
  /* Arreglo 4: aquí sí se ve el control «Marcar todas» */
  .bj-todas-m { display: inline-flex; align-items: center; gap: 8px; font-size: 13px;
                font-weight: 700; color: var(--navy); min-height: 44px; cursor: pointer;
                margin-top: 10px; }
  /* el menú flotante nunca se sale de la pantalla: a 390 px el desplegable nacía en
     x=205 con 230 px de ancho y llegaba a 434 (la página desbordaba a 434/390). El
     bloque de «Posponer» ocupa la línea entera, así que el menú abre desde el borde
     izquierdo de la barra y entra completo. */
  .snooze-menu { flex: 1 0 100%; }
  .snooze-list { min-width: 0; width: max-content; max-width: calc(100vw - 48px); }
  .tscroll table.terms, .tscroll table.terms tbody, .tscroll table.terms tr, .tscroll table.terms td { display: block; min-width: 0; white-space: normal; }
  .tscroll table.terms thead { display: none; }
  .tscroll table.terms tr { background: var(--superficie); border: 1px solid var(--linea); border-radius: var(--radio-alerta); padding: 10px 14px; margin-bottom: 8px; position: relative; }
  .tscroll table.terms td { padding: 3px 0; border: 0; text-align: left; max-width: none; }
  .tscroll table.terms td.chk { position: absolute; right: 12px; top: 12px; width: auto; }
  .tscroll table.terms td.term { padding-right: 32px; }
  .tscroll table.terms td[data-th]:not(.term)::before { content: attr(data-th) ": "; color: var(--texto-suave); font-weight: 500; }
  .tscroll table.terms td.num { text-align: left; }
  /* U4 (P6.3): una celda sin dato no deja su rótulo solo («Campaña:» sin valor) */
  .tscroll table.terms td[data-th]:empty { display: none; }
  /* r12 P5.5: a 390 px el rótulo de la fila ya va delante de la cifra (data-th). */
  .tscroll table.terms .rotulo-fila { display: none; }
  /* Juez r12 (ronda 3): a 390 px cada fila es una tarjeta; el fondo de «hover» quedaba como un
     recuadro suelto dentro de ella (en pantallas táctiles no hay hover). */
  .tscroll table.terms tr:hover td { background: transparent; }
  /* Juez r12 (ronda 4): sin motivo concreto la tarjeta no repite «Por qué duda: —»; la línea de
     arriba ya dice en cuántas pasa. En escritorio la celda sigue con «—». */
  .tscroll table.terms td.sin-motivo { display: none; }
  /* Synsation fila 1: la fila del aviso no es otra tarjeta, es el aviso solo. */
  .tscroll table.terms tr.fila-aviso { background: transparent; border: 0; padding: 0; margin-bottom: 8px; }
  /* U2 (P6.3): el pie de la hoja queda pegado abajo, con el botón principal primero y a
     ancho completo; antes, con 8 filas, los botones quedaban debajo de toda la lista. */
  .modal-overlay:not(.pantalla-plena) .modal-foot { position: sticky; bottom: -24px; z-index: 1;
     background: var(--superficie); margin: 18px -16px -24px; padding: 12px 16px 16px; }
  .modal-foot > .spacer { display: none; }
  .modal-foot > button { flex: 1 1 100%; justify-content: center; }
  .modal-foot > button.primary, .modal-foot > button.danger { order: -1; }
  .modal-foot .modal-estado { order: -2; text-align: left; }
  .modal-cerrar { margin: -6px -8px 0 8px; }
  /* App-lista r7 P5.10 (UI7-6): con el relleno inferior de la hoja, el pie fijo no llegaba al
     borde de abajo y una fila de la tabla asomaba debajo de «Cancelar». La hoja no lleva relleno
     abajo; el pie, pegado al borde (bottom 0), pone su fondo y el hueco de la barra del iPhone. */
  .modal-overlay:not(.pantalla-plena) > .modal-box { padding-bottom: 0; }
  .modal-overlay:not(.pantalla-plena) .modal-foot { bottom: 0; margin-bottom: 0;
     padding-bottom: max(16px, env(safe-area-inset-bottom));
     /* el pie queda a una fracción de píxel del borde (su `top` cae en x,5 px) y por esa rendija
        asomaba la fila de abajo: la sombra sólida, del color del fondo, la tapa. */
     box-shadow: 0 6px 0 var(--superficie); }
}
@media (max-width: 760px) {
  .card { padding: 16px; }
  .banda { padding: 20px 18px 0; }
  .banda-cab { flex-direction: column; }
  .kpis-banda { grid-template-columns: 1fr 1fr; }
  .kpi-b { padding: 16px 12px; }
  .kpi-b:first-child, .kpi-b.kpi-gasto { padding-left: 0; }
.kpi-b.kpi-hallazgos { padding-right: 0; }
  .kpi-b:nth-child(odd) { border-left: 0; padding-left: 0; }
  .kpi-b:nth-child(n+3) { border-top: 1px solid var(--filete-sobre-navy); }
  .cifra-n { font-size: 24px; }
  th { white-space: normal; }
  .card > table th:first-child, .card > table td:first-child { padding-left: 16px; }
  .card > table th:last-child, .card > table td:last-child { padding-right: 16px; }
  .kpis-clara { grid-template-columns: 1fr 1fr; }
  /* La tercera ficha del consumo del plan ocupa la fila entera (§7.6) */
  .kpis-tres > .kpi-c:nth-child(3) { grid-column: 1 / -1; }
  .kpi-c { padding: 12px 14px; }
  .kpi-c .cifra { font-size: 22px; }
  .kpi-c:nth-child(odd) { border-left: 0; padding-left: 0; }
  .kpi-c:nth-child(n+3) { border-top: 1px solid var(--linea-suave); }
  .verdict { grid-template-columns: 1fr; padding: 20px 18px; }
  .verdict .big { font-size: 36px; }
  .verdict .big.sin-ia { font-size: 26px; }
  .fichas { border-left: 0; padding-left: 0; border-top: 1px solid var(--linea-suave); padding-top: 12px; }
  .salud-card { grid-template-columns: 1fr; gap: 12px; }
  .lista-fila { grid-template-columns: 1fr 1fr; padding: 14px 16px; }
  .lista-fila > :first-child { grid-column: 1 / -1; }
  .lista-fila .st-imp { text-align: left; min-width: 0; }
  /* U11 (P6.3): el chip de prioridad no se estira y el botón queda a la izquierda */
  .lista-fila > .chip { justify-self: start; }
  .lista-fila .btn-sm { justify-self: start; }
  .bandeja-cab { display: none; }
  /* Fase 4 §7.6 y §2.1: las rejillas de dos columnas y las filas de paso pasan a una */
  .campos { grid-template-columns: 1fr; }
  .campos .ancho-total { grid-column: auto; }
  .paso-fila { grid-template-columns: 1fr; gap: 8px; padding: 14px 0; }
  .paso-fila > :last-child { justify-self: start; }
  .card-pie > button, .empty button { width: 100%; }
  /* Synsation visual r1 (B3): con un nombre de cuenta largo, «Analizar …» se cortaba por los dos lados.
     El botón crece en alto y el texto pasa a la línea siguiente. */
  .card-pie > button { white-space: normal; height: auto; min-height: var(--alto-boton-md); padding-top: 10px; padding-bottom: 10px; text-align: center; overflow-wrap: anywhere; }
  details.bandeja-fila > summary, details.fila-historial > summary { grid-template-columns: 1fr 1fr; padding: 14px 16px; gap: 8px 12px; }
  details.bandeja-fila > summary > .bj-titulo { grid-column: 1 / -1; white-space: normal; }
  .bj-titulo span { white-space: normal; }
  .bj-ent, .bj-imp { text-align: left; white-space: normal; }
  .bj-ent::before { content: "Cambios: "; color: var(--texto-suave); font-weight: 500; }
  /* App-lista r6 P6.6 (UI6-5): en las filas «Lo cambias tú» esa columna ya no es siempre un «dónde»
     («Faltan 5 datos», «Apagadas en la cuenta», una fecha): va sin rótulo. El texto no se corta
     con puntos suspensivos (r3 P6.10). */
  details.bandeja-fila[data-manual="1"] .bj-ent::before { content: none; }
  /* Juez r12 (texto 4): el grupo de dudas no son cambios propuestos. */
  details.bandeja-fila[data-dudas="1"] .bj-ent::before { content: none; }
  .bj-ent { display: block; -webkit-line-clamp: unset; overflow: visible; }
  /* Arreglo 9 (juez 2 defecto 6): a 390 px el importe salía como un «—» suelto sin rótulo */
  .bj-imp::before { content: "Gasto al mes: "; color: var(--texto-suave); font-weight: 500; }
  /* U4 (P6.3): sin monto no va el rótulo solo («Gasto al mes:» vacío) */
  .bj-imp:empty { display: none; }
  /* En Historial esa columna es el gasto evitado, no el importe del mes */
  details.fila-historial .bj-imp::before { content: "Gastaban en 30 días: "; }
  .bj-acc { justify-content: flex-start; }
  .bj-acc { white-space: normal; }
  .bj-detalle { padding: 0 16px 16px; }
  .applybar .nota-suave { margin-left: 0; }
  .reco, .grupo-area > .area-titulo { padding-left: 16px; padding-right: 16px; }
  .planes-grid, html.v-planes-4-1 .planes-grid { grid-template-columns: 1fr; }
  html.v-planes-4-1 .plan.plan-pro { flex-direction: column; }
  .modal-box { padding: 20px 16px; max-height: 90vh; }
  .topbar { flex-wrap: wrap; }
}
/* r11 P1.13: entre 641 y 760 px la caja tiene 20 px × 16 px de relleno; el pie fijo lo cubre igual.
   (En ≤640 px manda la hoja de abajo, con su propio pie.) */
@media (min-width: 641px) and (max-width: 760px) {
  .modal-overlay:not(.pantalla-plena) .modal-foot { bottom: -20px; margin: 18px -16px -20px; padding: 12px 16px 20px; }
}

/* ── v-sobrio: la maqueta contenida de las rondas 1-3 (solo para comparar) ── */
html.v-sobrio .chip.media { background: var(--accion-suave); color: var(--navy); }
html.v-sobrio .chip.sev-baja { background: none; padding: 0; height: auto; color: var(--texto-suave); }
html.v-sobrio .ficha-dinero .cifra { color: var(--navy); } html.v-sobrio .ficha-dinero .th.punto::before { display: none; }
html.v-sobrio .kpi-b.kpi-desperdicio[data-estado="fugas"] .cifra-n { color: var(--texto-inverso); }
html.v-sobrio .kpi-b .th-n.con-punto::before { display: none; } html.v-sobrio .kpi-b[data-estado="fugas"] .th-n.con-punto::before { display: inline-block; background: var(--peligro-claro); }
html.v-sobrio .banda .mejora, html.v-sobrio .banda .empeora { color: var(--texto-inverso); }
html.v-sobrio .barra > span { background: var(--accion) !important; }
html.v-sobrio .estado-bien, html.v-sobrio .estado-atencion, html.v-sobrio .estado-mal, html.v-sobrio .estado-dinero { color: var(--navy) !important; }
html.v-sobrio .pacing-estado.media { background: none; padding: 0; color: var(--texto-suave); } html.v-sobrio .pacing-estado.alta { background: none; padding: 0; color: var(--peligro); }
html.v-sobrio .pacing-bar .pacing-fill { background: var(--accion); } html.v-sobrio .pacing-bar[data-estado="sobre_ritmo"] .pacing-fill { background: var(--peligro); }
html.v-sobrio .th.punto::before { display: none; }
html.v-sobrio .verdict .opp b { color: var(--exito); }
html.v-sobrio .lista-fila .st-imp .n.good { color: var(--exito); } html.v-sobrio .lista-fila .st-imp .n.warn { color: var(--navy); }
html.v-sobrio .reco .imp, html.v-sobrio .pat .pc, html.v-sobrio .reco .imp.good, html.v-sobrio .bj-imp.ganar { color: var(--navy); }
html.v-sobrio .verdict .opp .chip { display: none; }
html.v-sobrio .pacing-estado.baja { background: var(--exito-suave); }
html.v-sobrio .chip.venta { background: var(--accion-suave); } html.v-sobrio .chip.venta::before { display: none; }
html.v-sobrio .chip.oportunidad { display: none; }

/* Una cifra de dinero nunca se parte entre líneas (cifraMoney). */
.nowrap { white-space: nowrap; }

/* Término con explicación al pasar el cursor o tocarlo (glosario A2: «resultados»). */
abbr.termino { text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }
/* Vista previa: el motivo de «no se aplicó» puede ser una frase larga; que parta en líneas. */
td.pv-st, td.pv-st .msg-peligro { white-space: normal; min-width: 220px; }

/* IA-6 (P6.20): sin selector de cuenta en el perfil, el primer grupo no lleva filete arriba */
#p_cuentaFila[hidden] + .grupo-campos { border-top: 0; margin-top: 0; padding-top: 0; }

/* App-lista r3 P6.7 (UI3-4): el motivo de la IA debajo de cada búsqueda, en gris. */
.motivo-ia { display: block; margin-top: 2px; font-size: 12.5px; font-weight: 400; line-height: 1.35;
             color: var(--texto-suave); white-space: normal; }
/* App-lista r3 P6.12: el error del servidor junto al campo del perfil. */
.campo-error { display: block; margin-top: 4px; font-size: 12.5px; font-weight: 600; color: var(--peligro); }
/* App-lista r3 P6.2: «al menos» también en la banda navy de Inicio. */
.banda .al-menos { color: var(--texto-sobre-navy); font-size: .5em; }

/* App-lista r5 P5.1 (UI5-1): las tablas «Ver detalle» de Análisis van en su propio contenedor con
   desplazamiento horizontal. Antes la tabla quedaba suelta en la tarjeta y `.lista{overflow:hidden}`
   la recortaba: a 390 px se veían 3 de 9 columnas. No se reusa `.tscroll`, que a 640 px o menos
   pasa a `overflow:visible`. */
.tabla-detalle { overflow-x: auto; max-width: 100%; margin-top: 8px; border: 1px solid var(--linea-suave);
                 border-radius: var(--radio-alerta); -webkit-overflow-scrolling: touch; }
.tabla-detalle > table.detalle { display: table; margin-top: 0; width: 100%; }
.tabla-detalle th.col-larga, .tabla-detalle td.col-larga { min-width: 220px; white-space: normal; }
.tabla-detalle td { overflow-wrap: break-word; }
/* r18 P4.6 (UI18-3): a 1440 px las tablas de 8 y 9 columnas de TuTag y Repro se cortaban a la
   derecha. Los encabezados se parten en dos líneas como mucho (antes `nowrap` los hacía más anchos
   que su cifra), en 11 px (el mínimo de los rótulos en mayúsculas); el relleno lateral baja de 16
   a 10 px, y la primera columna (campaña, grupo o búsqueda) tiene 180 px para que no quede en 4
   líneas. Las cifras siguen en una línea. Medido a 1440 px con las 13 tablas de TuTag y Repro
   (r18/arreglo_4.md). A 640 px o menos manda la vista de tarjetas de abajo. */
.tabla-detalle th { white-space: normal; vertical-align: bottom; padding: 10px 10px; font-size: 11px; letter-spacing: .02em; }
.tabla-detalle td { padding: 12px 10px; }
.tabla-detalle td.num { white-space: nowrap; }
.tabla-detalle th:first-child, .tabla-detalle td:first-child { min-width: 180px; padding-left: 14px; }
.tabla-detalle td.vacia { color: var(--texto-suave); font-weight: 400; }
/* App-lista r6 P6.5 (UI6-2): sombra en el borde cuando queda contenido a la derecha (o a la
   izquierda, si ya se desplazó). Las dos primeras capas tapan la sombra al llegar al borde,
   porque se mueven con el contenido (`local`). En macOS la barra de desplazamiento está oculta. */
.tabla-detalle {
  background:
    linear-gradient(to right, var(--superficie) 30%, rgba(255, 255, 255, 0)) left center / 40px 100% no-repeat local,
    linear-gradient(to left, var(--superficie) 30%, rgba(255, 255, 255, 0)) right center / 40px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(15, 18, 48, 0.16), rgba(15, 18, 48, 0)) left center / 14px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(15, 18, 48, 0.16), rgba(15, 18, 48, 0)) right center / 14px 100% no-repeat scroll,
    var(--superficie);
}
@media (max-width: 640px) {
  /* A 390 px, cada fila es una tarjeta con el rótulo de cada dato, como en Optimizaciones. */
  .tabla-detalle { border: 0; background: none; }
  .tabla-detalle > table.detalle, .tabla-detalle > table.detalle tbody,
  .tabla-detalle > table.detalle tr, .tabla-detalle > table.detalle td { display: block; min-width: 0; width: auto; }
  .tabla-detalle > table.detalle thead { display: none; }
  .tabla-detalle > table.detalle tr { background: var(--superficie); border: 1px solid var(--linea);
     border-radius: var(--radio-alerta); padding: 10px 14px; margin-bottom: 8px; }
  .tabla-detalle > table.detalle td { padding: 3px 0; border: 0; text-align: left; white-space: normal;
     overflow-wrap: anywhere; }
  .tabla-detalle > table.detalle td.col-larga { min-width: 0; }
  .tabla-detalle > table.detalle td[data-th]::before { content: attr(data-th) ": "; color: var(--texto-suave); font-weight: 500; }
  .tabla-detalle > table.detalle td:first-child { font-weight: 700; color: var(--navy); }
  .tabla-detalle > table.detalle td:first-child::before { content: none; }
  .tabla-detalle > table.detalle tbody tr:hover td { background: transparent; }
}

/* App-lista r5 P5.15 (UI5-11): las definiciones de «resultados» y «Sin confirmar» eran solo un
   `title`: no se abrían con el teclado ni con el dedo. Ahora son un botón con un globo, que se abre
   al tocarlo, con el foco del teclado o al pasar el cursor, y lo lee el lector de pantalla
   (`aria-describedby`). */
.termino-caja { position: relative; display: inline; }
button.termino { font: inherit; color: inherit; background: none; border: 0; padding: 0; margin: 0;
  min-height: 0; height: auto; cursor: help; text-decoration: underline dotted; text-underline-offset: 3px; }
button.termino.chip { text-decoration: none; height: 24px; padding: 0 10px; }
.termino-globo { display: none; position: absolute; left: 0; top: calc(100% + 6px); z-index: 20;
  width: max-content; max-width: min(300px, calc(100vw - 48px)); padding: 8px 10px; border-radius: var(--radio-alerta);
  background: var(--navy); color: var(--texto-inverso); font-size: 12.5px; font-weight: 500; line-height: 1.4;
  white-space: normal; text-transform: none; letter-spacing: 0; text-align: left; }
.termino-caja:hover > .termino-globo, button.termino:focus-visible + .termino-globo,
button.termino[aria-expanded="true"] + .termino-globo { display: block; }
.bj-acc .termino-globo, .bj-sev .termino-globo { left: auto; right: 0; }

/* App-lista r6 P6.1 y P6.2 (UI6-1, UI6-4): adónde escribir y los enlaces legales. */
.side-ayuda { padding: 10px 6px 0; font-size: 12px; line-height: 1.5; color: var(--texto-sobre-navy); overflow-wrap: anywhere; }
.side-ayuda p { margin: 0 0 4px; }
.side-ayuda a { color: var(--accion-claro); font-weight: 700; }
.side-ayuda a:hover { color: var(--texto-inverso); }
.linea-soporte { margin: 16px 0 0; }
.pie-legal { color: var(--texto-suave); font-size: 12px; text-align: center; margin: 6px 0 0; }
.pie-legal[hidden] { display: none; }
a.enlace-soporte { color: var(--accion); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.side-ayuda a.enlace-soporte { color: var(--accion-claro); }

.rule-cite .nota-clics { margin: 6px 0 0; }

/* App-lista r7 P5.8 (M7-6): el ritmo bajo por el CPA u ROAS objetivo, con su explicación. */
.nota-ritmo { margin: 10px 0 0; }
/* Menú G2 (paso 3): la tarjeta completa del ritmo en Inicio. «Míralo en Inicio →» la deja bajo la
   cabecera fija del celular (52 px), como las filas de la bandeja; el aviso del plan gratis, dentro. */
#ritmoInicio { scroll-margin-top: 64px; }
#ritmoInicio .ritmo-plan { margin: 14px 0 0; }
/* G2 r1 (juez dueño D4): «Ver planes» en Inicio se toca con el dedo: 44 px. */
#ritmoInicio .ritmo-plan button { min-height: 44px; }
/* Menú G2 (paso 4): «Qué entra en esta cifra» bajo el resumen del Historial, cerrado; 44 px para tocar. */
.hist-cifra-nota { margin: 12px 0 0; }
details.hist-entra { margin-top: 8px; }
details.hist-entra > summary { cursor: pointer; list-style: none; color: var(--accion); font-weight: 700; display: inline-flex; align-items: center; min-height: 44px; }
details.hist-entra > summary::-webkit-details-marker { display: none; }
details.hist-entra > summary::after { content: ""; display: inline-block; width: 6px; height: 6px; margin-left: 8px; border-right: 1.8px solid var(--accion); border-bottom: 1.8px solid var(--accion); transform: rotate(45deg); }
details.hist-entra[open] > summary::after { transform: rotate(-135deg); }
details.hist-entra .lista { margin-top: 4px; }

/* App-lista r8 P5.3 (UI8-1): el monto de la vista previa del presupuesto que no vale se marca y dice
   el rango debajo del campo. */
.pv-amt[aria-invalid="true"] { border-color: var(--peligro); }
.pv-amt-err { display: block; margin-top: 4px; font-size: 12px; line-height: 1.35; text-align: left; white-space: normal; }
.pv-amt-err[hidden] { display: none; }
/* App-lista r8 P5.1 (C8-1): la marca «sin la revisión de la IA» en la línea de la cuenta de Inicio. */
.banda-sin-ia { font-size: .55em; font-weight: 600; letter-spacing: 0; color: var(--rotulo-sobre-navy); }

/* ── Esperas G1: el avance del análisis (barra por tramos + lista de pasos) ──
   Cada tramo es una parte del análisis que corre; se llena solo con partes terminadas. */
.av-panel { margin-bottom: 14px; }
.av-titulo { font-size: 18px; line-height: 1.3; font-weight: 700; color: var(--tinta); margin: 0 0 12px; overflow-wrap: anywhere; }
.av-barra { display: flex; gap: 4px; height: 10px; margin: 0 0 10px; }
/* Juez ux r1 U6: el borde (--texto-tenue, 3,2:1 sobre blanco) deja ver los tramos vacíos (WCAG 1.4.11). */
.av-tramo { flex: 1 1 0; min-width: 0; height: 100%; background: var(--papel-3); border: 1px solid var(--texto-tenue); border-radius: var(--radio-pildora); overflow: hidden; box-sizing: border-box; }
.av-ahora:empty { display: none; }
.av-lleno { display: block; height: 100%; background: var(--accion); border-radius: var(--radio-pildora); transition: width 400ms ease-out; }
.av-van { font-size: 14px; color: var(--texto-suave); margin: 0 0 14px; }
.av-demora { margin-bottom: 14px; }
.av-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.av-linea { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; color: var(--texto); }
.av-cuerpo { flex: 1; min-width: 0; }
.av-txt { display: flex; gap: 10px; justify-content: space-between; color: var(--tinta); overflow-wrap: anywhere; }
.av-cuenta { flex: none; color: var(--texto-suave); font-variant-numeric: tabular-nums; }
.av-nota { font-size: 13px; color: var(--texto-suave); margin-top: 2px; overflow-wrap: anywhere; }
.av-icono { flex: none; width: 18px; text-align: center; font-weight: 700; line-height: 20px; }
.av-hecha .av-icono { color: var(--exito); }
.av-pendiente .av-icono, .av-omitida .av-icono { color: var(--texto-tenue); }
.av-pendiente .av-txt, .av-omitida .av-txt { color: var(--texto-suave); }
.av-aviso .av-icono { color: var(--aviso); }
.av-fallo .av-icono { color: var(--peligro); }
.av-activa .av-txt { font-weight: 600; }
/* La línea activa lleva un punto que late: se ve movimiento sin fingir avance. */
.av-punto { flex: none; width: 18px; height: 20px; position: relative; }
.av-punto::before { content: ""; position: absolute; left: 4px; top: 5px; width: 10px; height: 10px; border-radius: var(--radio-pildora);
                    background: var(--accion); animation: avlate 1.1s ease-in-out infinite alternate; }
@keyframes avlate { 0% { opacity: 1; transform: scale(1); } 100% { opacity: .35; transform: scale(.75); } }
@media (prefers-reduced-motion: reduce) {
  .av-punto::before { animation: none; }
  .av-lleno { transition: none; }
}
@media (max-width: 600px) {
  .av-titulo { font-size: 16px; }
  .av-txt { flex-wrap: wrap; gap: 2px 10px; }
}

/* Esperas G2 (6-oct-2026): la nota antes de ir a Google y el enlace «Deshaciendo…» bloqueado. */
.onb-welcome .nota-conectar { margin: 8px 0 0; }
a.more.ocupado { color: var(--texto-suave); cursor: default; pointer-events: none; text-decoration: none; }
