/* =========================================================================
   Pi Management — Sistema de diseño
   Marca: π roja + serif elegante. Paleta: rojo / carbón / crema.
   ========================================================================= */

:root {
  /* Marca */
  --red:        #C1272D;
  --red-600:    #A81F26;
  --red-700:    #8A181D;
  --red-tint:   #FBECED;
  /* El rojo en rgba (halos, filas seleccionadas, foco): token para que el tema despachos lo cambie. */
  --red-rgb:    193,39,45;

  /* Tinta / neutros cálidos */
  --ink:        #1B1714;
  --ink-2:      #39322C;
  --muted:      #6E655C;
  /* Se oscureció de #9B9086 a #767068. El anterior daba 3.12 de contraste sobre
     blanco y el mínimo para texto pequeño es 4.5: es el color del renglón que va
     debajo del logotipo —«Consultoría Fiscal, Contable y Tecnológica»— y salía
     así en 26 de las 29 páginas. Se leía, pero se leía mal, y es lo primero que
     mira alguien que llega. Ahora da 4.9. De sus nueve usos, ocho son texto y
     uno un borde, así que el cambio va donde tenía que ir. */
  --muted-2:    #767068;

  /* EL ROJO DE LA LETRA, SEPARADO DEL ROJO DEL RELLENO.
   *
   * Son dos trabajos distintos y no hay un solo tono que haga los dos. Medido:
   *
   *              letra sobre oscuro    blanco encima
   *   #C1272D          2.82                5.84
   *   #E4626A          4.91                3.36
   *
   * El de marca es perfecto para un botón —blanco sobre rojo— y malo como letra
   * en modo oscuro. Aclararlo para que se lea arruinaría los botones. Por eso
   * son dos: `--red` sigue siendo el relleno y no cambia nunca; `--red-tinta` es
   * el que se usa cuando el rojo es LETRA, y en oscuro se aclara.
   *
   * En claro valen lo mismo, así que este cambio no altera un solo píxel del
   * tema claro. Sigue el nombre que ya usaban `--ok-tinta` y `--aviso-tinta`. */
  --red-tinta:  #C1272D;
  --line:       #EAE3DA;
  --line-2:     #DED5C9;

  /* Fondos */
  --bg:         #FFFFFF;
  --cream:      #FBF8F3;
  --cream-2:    #F4EDE3;
  --ink-band:   #17130F;
  --surface:    #FFFFFF;
  /* El realce: «lo mismo, pero un punto distinto». Es lo que pinta el renglón bajo el
     cursor, el encabezado de una tabla o una tecla.
     Existe porque ese trabajo lo hacía --surface, y en tema claro --surface y --bg son el
     MISMO blanco: como las tarjetas están pintadas de #fff, el realce caía sobre blanco
     contra blanco y no se veía nada. Pasar el ratón por una fila no hacía nada visible, y
     el encabezado de las tablas no se distinguía del cuerpo. */
  --realce:     #F4F0E9;
  /* El fondo de una tarjeta. Existe porque estaba escrito «#fff» a mano en veintisiete
     reglas, y cada una necesitaba su propia excepción para el tema oscuro. Cuatro se
     quedaron sin ella —entre otras la tarjeta del lanzador— y se veían blancas sobre
     fondo oscuro. Con un token no hay excepción que olvidar. */
  --tarjeta:    #FFFFFF;

  /* Estado: bien, ojo, mal, dato, nada. Son cinco cosas que decir, no veintiuna maneras
     de decirlas. Estaban escritas a mano en dieciséis reglas de DOS familias que hacen el
     mismo trabajo —.tb-pill--* y .status-*— y ni siquiera coincidían: «pendiente» era
     #b7791f en una y #B98A3E en la otra.
     El fondo va en rgba sobre lo que haya debajo, y no en un pastel sólido: así la misma
     pastilla funciona sobre una tarjeta clara y sobre una oscura. Las de .tb-pill--*
     usaban pastel sólido y en tema oscuro quedaban como manchas claras. */
  /* La tinta va más oscura que el tono «bonito» de cada estado. Medido sobre la tarjeta,
     los originales daban 3.10 (pendiente) y 3.47 (pagada): por debajo del 4.5 que pide
     un texto pequeño, y estas pastillas van en .78rem. Con estos valores pasan de 5. */
  --ok-tinta:     #17724A;  --ok-fondo:     rgba(31,157,97,.14);
  --aviso-tinta:  #8A6520;  --aviso-fondo:  rgba(184,138,62,.18);
  --mal-tinta:    var(--red); --mal-fondo:  var(--red-tint);
  --info-tinta:   #2A5BC4;  --info-fondo:   rgba(26,86,219,.12);
  --neutro-tinta: var(--muted); --neutro-fondo: var(--cream-2);

  --header-bg:  rgba(255,255,255,.86);

  /* LA BANDA DEL ENCABEZADO DE LAS TABLAS.
   *
   * En claro es la tinta de la marca con letra blanca: es lo que la separa de un cuerpo
   * que tambien es claro. En oscuro NO se invierte a blanco —una banda blanca sobre una
   * pantalla oscura deslumbra y es lo primero que ve el ojo, cuando lo que importa son
   * los datos—: se sube un escalon sobre el fondo de la tarjeta y basta. */
  /* El circulo con la «i» del aviso. Va como token y en `mask`, no como imagen de fondo,
   * para que tome el color del tema sin duplicar el archivo. */
  --ico-info: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.2" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5"/><path d="M12 7.6h.01"/></svg>');

  --tabla-cab:        #2A231D;
  --tabla-cab-tinta:  #F2EAE0;

  /* Tipografía */
  --font-display: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-sans:    "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;

  /* Radios / sombras */
  --r-sm: 10px;
  --r:    16px;
  --r-lg: 24px;
  --shadow-sm: 0 1px 2px rgba(27,23,20,.06), 0 2px 8px rgba(27,23,20,.05);
  --shadow:    0 8px 24px rgba(27,23,20,.08), 0 2px 6px rgba(27,23,20,.05);
  --shadow-lg: 0 24px 60px rgba(27,23,20,.14), 0 8px 20px rgba(27,23,20,.08);

  /* Layout */
  --container: 1160px;
  --gap: clamp(1rem, 3vw, 2rem);
  --section-y: clamp(3.5rem, 8vw, 7rem);
}

/* ---------- Tema oscuro ---------- */
:root[data-theme="dark"] {
  /* Campos sin clase propia (textarea de pegar XML, año del presupuesto, redes en
     Configuración) salían blancos con letra negra: el navegador los pinta en claro
     si no se le dice que la página es oscura. */
  color-scheme: dark;
  --ink: #F2EAE0; --ink-2: #D6CCC0; --muted: #A99E92;
  /* #857B70 daba 4.17 y el mínimo para texto pequeño es 4.5. Ahora 5.18. */
  --muted-2: #968B7E;
  /* Ver el comentario de `--red-tinta` arriba: aquí es donde sirve de algo. */
  --red-tinta: #E4626A;
  --line: #302A24; --line-2: #3E362E;
  --bg: #15120F; --cream: #1C1815; --cream-2: #241E19; --ink-band: #0E0C0A;
  --surface: #1E1A16; --realce: #2B2520; --tarjeta: #241E19; --header-bg: rgba(21,18,15,.9);
  /* Los fondos en rgba valen igual sobre oscuro. La tinta sí sube de luminosidad: los
     tonos del tema claro se apagan sobre una tarjeta oscura y dejan de leerse. */
  --ok-tinta: #4FC28C; --aviso-tinta: #D9A85C; --info-tinta: #7BA6F5;
  /* El rojo de marca sobre una tarjeta oscura daba 2.82: se lee mal. Aquí la tinta de
     «mal» se aclara. La marca no se toca —sigue siendo #C1272D donde es marca— porque
     esto es sólo el color del texto de una pastilla de estado. */
  --mal-tinta: #F0757B;
  --red-tint: #2C1618;
  /* Ver arriba: en oscuro la banda NO se invierte. Un blanco aqui deslumbra. */
  --tabla-cab: #342C24;
  --tabla-cab-tinta: #E4DACE;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4), 0 2px 8px rgba(0,0,0,.3);
  --shadow: 0 8px 24px rgba(0,0,0,.45); --shadow-lg: 0 24px 60px rgba(0,0,0,.55);
}
:root[data-theme="dark"] .trust__logos img { filter: grayscale(1) invert(.9) brightness(1.1); }
:root[data-theme="dark"] .footer__logo { filter: brightness(0) invert(1); }

/* ---------- Reset ---------- */
*,*::before,*::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  font-family: var(--font-sans);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.65;
  font-size: 1.05rem;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img,svg,video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
ul { list-style: none; padding: 0; }

/* ---------- Tipografía ---------- */
h1,h2 { font-family: var(--font-display); font-weight: 600; line-height: 1.05; letter-spacing: -.015em; color: var(--ink); }
h3,h4 { font-family: var(--font-sans); font-weight: 700; line-height: 1.2; letter-spacing: -.01em; color: var(--ink); }
h1 { font-size: clamp(2.4rem, 6vw, 4.3rem); line-height: 1.02; }
h2 { font-size: clamp(1.9rem, 4vw, 3rem); }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem); }
p  { color: var(--ink-2); }
.lead { font-size: clamp(1.05rem, 1.6vw, 1.28rem); color: var(--ink-2); line-height: 1.6; }
strong { font-weight: 700; color: var(--ink); }

/* ---------- Utilidades ---------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: clamp(1.1rem, 4vw, 2rem); }
.section { padding-block: var(--section-y); }
.section--cream { background: var(--cream); }
.section--ink { background: var(--ink-band); color: #F3ECE3; }
.section--ink h1,.section--ink h2,.section--ink h3 { color: #FFF; }
.section--ink p { color: #C9BEB2; }
.center { text-align: center; }
.eyebrow {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--font-sans); font-weight: 600; font-size: .78rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--red-tinta);
}
.eyebrow::before { content: ""; width: 26px; height: 2px; background: var(--red); border-radius: 2px; }
.section--ink .eyebrow { color: #E8A0A3; }
.section--ink .eyebrow::before { background: #E8A0A3; }
.section-head { max-width: 720px; }
.section-head.center { margin-inline: auto; }
.section-head h2 { margin-top: .8rem; }
.section-head p { margin-top: 1rem; }

/* π decorativa */
.pi-mark { font-family: var(--font-display); color: var(--red-tinta); font-weight: 600; }

/* ---------- Botones ---------- */
.btn {
  --bg: var(--red); --fg: #fff;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .85rem 1.5rem; border-radius: 999px; border: 1.5px solid transparent;
  background: var(--bg); color: var(--fg);
  font-weight: 600; font-size: .98rem; letter-spacing: .01em;
  transition: transform .18s ease, box-shadow .2s ease, background .2s ease, color .2s ease;
  /* Una sombra de apoyo, no un resplandor.
   *
   * Tenía `0 6px 18px rgba(var(--red-rgb),.22)`: un halo rojo de dieciocho píxeles
   * bajo CADA botón. Con cuatro botones en una barra, la pantalla se llena de
   * manchas rosas y todo parece flotar. Un botón no flota: está puesto sobre la
   * página, y una sombra de un píxel es lo que dice eso. */
  box-shadow: 0 1px 2px rgba(27,23,20,.13);
}
/* Al pasar el ratón se oscurece, no se levanta.
 *
 * El `translateY(-2px)` movía el botón bajo el cursor: en una barra de cuatro,
 * pasar el ratón los hacía saltar uno tras otro. Está bien en la portada del
 * sitio, donde hay un botón cada dos pantallas; en un panel donde se trabaja
 * ocho horas, cansa. */
.btn:hover { background: var(--red-600); box-shadow: 0 2px 6px rgba(27,23,20,.16); }
.btn:active { transform: translateY(1px); }
/* El secundario es blanco con borde, y al pasar el ratón se marca el borde.
 *
 * Antes se invertía a tinta sólida: el botón de «Cancelar» se volvía el más
 * negro de la pantalla justo cuando el cursor pasaba por encima, y el ojo iba a
 * él en vez de a la acción principal. */
/* El botón secundario NO pinta fondo, y esto es a prueba de balas por una razón.
 *
 * Le puse `background: var(--tarjeta)` para que en el panel se viera como una
 * tarjeta. `--tarjeta` es BLANCO, y este botón también se usa dentro de bandas
 * oscuras —la de precios de la portada, la barra del panel—, donde la regla de
 * la banda ajusta el color del texto y el borde pero no el fondo: nunca había
 * hecho falta. Resultado: pastilla blanca con letra crema encima. Invisible, en
 * la portada, en el botón de «Empezar gratis».
 *
 * Transparente, el botón toma el fondo de donde esté puesto y funciona en los
 * dos sitios sin que nadie tenga que acordarse de nada. Un componente que hay
 * que corregir en cada fondo donde se usa está mal hecho. */
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line-2); box-shadow: none; }
.btn--ghost:hover { background: var(--realce); color: var(--ink); border-color: var(--muted-2); box-shadow: none; }
/* El tercero: lo que se puede ignorar no lleva ni borde. Tres pesos —relleno,
 * borde, nada— son suficientes para decir qué importa, y más de tres no se
 * distinguen. */
.btn--plano { background: none; color: var(--muted); border-color: transparent; box-shadow: none; }
.btn--plano:hover { background: var(--realce); color: var(--ink); box-shadow: none; }
.btn--light { background: #F5EFE7; color: #1B1714; box-shadow: var(--shadow-sm); }
.btn--light:hover { background: #FFFFFF; color: var(--red-tinta); box-shadow: var(--shadow); }
.btn--lg { padding: 1rem 1.9rem; font-size: 1.05rem; }
.btn--block { width: 100%; }

.link-arrow { display: inline-flex; align-items: center; gap: .4rem; color: var(--red-tinta); font-weight: 600; }
.link-arrow svg { transition: transform .2s ease; }
.link-arrow:hover svg { transform: translateX(4px); }

/* ---------- Top bar ---------- */
.topbar { background: var(--ink-band); color: #E8DFD4; font-size: .84rem; }
.topbar .container { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding-block: .5rem; }
.topbar a { color: #E8DFD4; display: inline-flex; align-items: center; gap: .4rem; }
.topbar a:hover { color: #fff; }
.topbar .sep { color: #6c6259; }
.topbar__right { display: flex; gap: 1.2rem; align-items: center; }
@media (max-width: 720px){ .topbar__left .hide-sm { display:none; } .topbar__right .hide-sm{ display:none; } }

/* ---------- Header / nav ---------- */
.header { position: sticky; top: 0; z-index: 60; background: var(--header-bg); backdrop-filter: saturate(180%) blur(12px); border-bottom: 1px solid transparent; transition: border-color .25s ease, box-shadow .25s ease; }
.header.is-stuck { border-color: var(--line); box-shadow: 0 6px 24px rgba(27,23,20,.06); }
.nav { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; padding-block: .85rem; }

.brand { display: inline-flex; align-items: center; gap: .6rem; }
.brand__pi { font-family: var(--font-display); font-weight: 600; font-size: 2rem; color: var(--red-tinta); line-height: 1; }
.brand__txt { display: flex; flex-direction: column; line-height: 1; }
.brand__txt b { font-family: var(--font-display); font-weight: 600; font-size: 1.18rem; color: var(--ink); letter-spacing: -.01em; }
.brand__txt small { font-family: var(--font-sans); font-weight: 600; font-size: .58rem; letter-spacing: .22em; color: var(--muted-2); text-transform: uppercase; margin-top: 2px; }

.nav__links { display: flex; align-items: center; gap: .35rem; }
.nav__links > li > a { display: inline-flex; align-items: center; gap: .3rem; padding: .55rem .7rem; border-radius: 8px; font-weight: 500; font-size: .95rem; color: var(--ink-2); transition: color .18s ease, background .18s ease; }
.nav__links > li > a:hover { color: var(--red-tinta); background: var(--red-tint); }
.nav__cta { display: flex; align-items: center; gap: .6rem; }

/* Dropdown */
.has-menu { position: relative; }
.dropdown { position: absolute; top: calc(100% + 10px); left: 0; min-width: 300px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-lg); padding: .5rem; opacity: 0; visibility: hidden; transform: translateY(8px); transition: opacity .18s ease, transform .18s ease, visibility .18s; }
.has-menu:hover .dropdown, .has-menu:focus-within .dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.dropdown a { display: flex; flex-direction: column; gap: 1px; padding: .6rem .7rem; border-radius: 10px; }
.dropdown a:hover { background: var(--cream); }
.dropdown a b { font-family: var(--font-sans); font-weight: 600; font-size: .93rem; color: var(--ink); }
.dropdown a span { font-size: .8rem; color: var(--muted); }
.caret { width: 14px; height: 14px; opacity: .6; }

/* Hamburguesa */
.nav__toggle { display: none; width: 44px; height: 44px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); align-items: center; justify-content: center; }
.nav__toggle svg { width: 22px; height: 22px; }

/* ---------- Hero ---------- */
.hero { position: relative; background:
    radial-gradient(1100px 500px at 82% -8%, var(--red-tint), transparent 60%),
    radial-gradient(800px 400px at 0% 110%, var(--cream-2), transparent 55%),
    var(--bg);
  overflow: hidden; }
.hero .container { display: grid; grid-template-columns: 1.15fr .85fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; padding-block: clamp(3rem, 7vw, 6rem); }
.hero__eyebrow { margin-bottom: 1.2rem; }
.hero h1 { max-width: 12ch; }
.hero h1 em { font-style: italic; color: var(--red-tinta); }
.hero__lead { margin-top: 1.4rem; max-width: 46ch; }
.hero__cta { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2rem; }
.hero__trust { margin-top: 1.8rem; display: flex; align-items: center; gap: .6rem; font-size: .9rem; color: var(--muted); }
.hero__trust svg { color: var(--red-tinta); flex: none; }

/* Panel visual del hero */
.hero__panel { position: relative; }
.hero-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); padding: 1.4rem; }
.hero-card__top { display: flex; align-items: center; justify-content: space-between; padding-bottom: 1rem; border-bottom: 1px solid var(--line); }
.hero-card__top b { font-family: var(--font-display); font-size: 1.05rem; }
.dot { width: 9px; height: 9px; border-radius: 50%; background: #26c281; box-shadow: 0 0 0 4px rgba(38,194,129,.16); }
.kpis { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin-top: 1.1rem; }
/* La tarjeta del indicador: fondo de tarjeta y borde, no un bloque crema.
 *
 * Sobre una pantalla ya crema, un indicador crema no es una tarjeta: es una
 * mancha un poco más oscura. Con el fondo de tarjeta y un borde de un píxel se
 * ve dónde empieza y dónde acaba, que es lo que hace que una fila de seis se lea
 * como seis cosas y no como una. */
.kpi { background: var(--tarjeta); border: 1px solid var(--line); border-radius: var(--r);
  padding: 1rem 1.05rem; box-shadow: var(--shadow-sm); }
.kpi span { font-size: .74rem; color: var(--muted); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.kpi b { display: block; font-family: var(--font-display); font-size: 1.5rem; margin-top: .2rem; color: var(--ink); }
.kpi.up b { color: #1f9d61; }

/* Las dos clases que faltaban.
 *
 * `kpi__label` y `kpi__value` se usaban en DIECINUEVE sitios del panel y no
 * tenían una sola regla: el rótulo salía del tamaño del texto normal y la cifra
 * igual, así que un indicador se leía como un párrafo suelto dentro de una caja
 * beige. No daba error en ningún lado —una clase sin estilo no se queja— y
 * afectaba a todos los tableros a la vez.
 *
 * Son las mismas medidas que `.kpi span` y `.kpi b`, que es lo que estas dos
 * vinieron a sustituir cuando alguien dejó de usar etiquetas y empezó a usar
 * divs. */
.kpi__label { display: block; font-size: .69rem; color: var(--muted); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.kpi__value { display: block; font-family: var(--font-display); font-size: 1.8rem; margin-top: .18rem; color: var(--ink); line-height: 1.08;
  /* Los dígitos de ancho fijo: sin esto, una columna de cifras baila al cambiar
   * de mes porque el 1 es más angosto que el 8. */
  font-variant-numeric: tabular-nums; letter-spacing: -.025em; }

/* El cuadro de color del indicador.
 *
 * Es el cambio que más se nota por lo poco que cuesta. Sin él, una fila de seis
 * indicadores se lee palabra por palabra: hay que ir leyendo los rótulos hasta
 * dar con el que se busca. Con él, el ojo va directo por el color — rojo lo
 * facturado, verde lo cobrado, ámbar lo que está en riesgo, azul lo que se
 * cuenta— y el rótulo sólo confirma.
 *
 * El color va por FAMILIA de dato, no por tarjeta: dos indicadores de dinero
 * cobrado llevan el mismo verde aunque estén en pantallas distintas. Un color
 * por tarjeta sería decoración; por familia, es información. */
.kpi__chip { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center;
  font-size: 1rem; margin-bottom: .7rem; background: var(--cream-2); color: var(--muted); }
.kpi__chip svg { width: 17px; height: 17px; }
.kpi__chip--dinero { background: var(--red-tint); color: var(--red-tinta); }
.kpi__chip--bien   { background: var(--ok-fondo); color: var(--ok-tinta); }
.kpi__chip--ojo    { background: var(--aviso-fondo); color: var(--aviso-tinta); }
.kpi__chip--dato   { background: var(--info-fondo); color: var(--info-tinta); }
/* La comparación va debajo y en pequeño: es contexto de la cifra, no otra cifra. */
.kpi .tb-sub { display: block; margin-top: .25rem; font-size: .76rem; font-weight: 600; }
.bars { display: flex; align-items: flex-end; gap: .5rem; height: 84px; margin-top: 1.1rem; padding: 0 .2rem; }
.bars i { flex: 1; background: linear-gradient(var(--red), var(--red-600)); border-radius: 5px 5px 0 0; opacity: .85; }
.hero-badge { position: absolute; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); padding: .7rem .9rem; display: flex; align-items: center; gap: .6rem; font-size: .84rem; font-weight: 600; }
.hero-badge svg { color: var(--red-tinta); }
.hero-badge--tl { top: -18px; left: -22px; }
.hero-badge--br { bottom: -20px; right: -14px; }

/* ---------- Trust strip ---------- */
.trust { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--surface); }
.trust .container { padding-block: 1.6rem; display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; justify-content: center; }
.trust__label { font-size: .8rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted-2); }
.trust__logos { display: flex; align-items: center; gap: clamp(1.4rem, 4vw, 3rem); flex-wrap: wrap; justify-content: center; }
.trust__logos img { height: 30px; width: auto; opacity: .72; filter: grayscale(1); transition: opacity .2s, filter .2s; }
.trust__logos img:hover { opacity: 1; filter: grayscale(0); }

/* ---------- Grid de servicios ---------- */
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; margin-top: 3rem; }
.card { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 1.7rem; transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease; display: flex; flex-direction: column; }
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color: var(--line-2); }
.card__icon { width: 52px; height: 52px; border-radius: 13px; background: var(--red-tint); color: var(--red-tinta); display: grid; place-items: center; margin-bottom: 1.1rem; }
.card__icon svg { width: 26px; height: 26px; }
.card h3 { font-size: 1.28rem; }
.card p { margin-top: .6rem; font-size: .97rem; color: var(--muted); flex: 1; }
.card__list { margin-top: 1rem; display: flex; flex-direction: column; gap: .5rem; }
.card__list li { display: flex; gap: .55rem; align-items: flex-start; font-size: .92rem; color: var(--ink-2); }
.card__list svg { color: var(--red-tinta); flex: none; margin-top: 3px; }
.card__link { margin-top: 1.2rem; }

/* ---------- Franja valor / por qué ---------- */
.why { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem,5vw,4rem); align-items: center; }
.why__list { display: grid; gap: 1.1rem; margin-top: 1.6rem; }
.why__item { display: flex; gap: .9rem; }
.why__item .ico { flex: none; width: 44px; height: 44px; border-radius: 12px; background: var(--surface); border: 1px solid var(--line); color: var(--red-tinta); display: grid; place-items: center; }
.why__item h4 { font-family: var(--font-sans); font-weight: 700; font-size: 1rem; color: var(--ink); }
.why__item p { font-size: .95rem; color: var(--muted); margin-top: .15rem; }
.quote-card { background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--red); border-radius: var(--r); padding: 1.8rem; box-shadow: var(--shadow-sm); }
.quote-card p { font-family: var(--font-display); font-size: 1.35rem; line-height: 1.4; color: var(--ink); font-style: italic; }
.quote-card .by { margin-top: 1.1rem; font-family: var(--font-sans); font-style: normal; font-weight: 600; font-size: .9rem; color: var(--muted); }

/* ---------- Banda CFO ---------- */
.cfo { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem,5vw,4rem); align-items: center; }
.cfo__badges { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.6rem; }
.chip { display: inline-flex; align-items: center; gap: .45rem; padding: .5rem .9rem; border-radius: 999px; background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14); font-size: .88rem; font-weight: 500; }
.chip svg { color: #E8A0A3; }
.dashboard-mock { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.12); border-radius: var(--r-lg); padding: 1.3rem; }
.dashboard-mock .row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: .8rem; }
.dashboard-mock .cell { background: rgba(255,255,255,.06); border-radius: 12px; padding: .9rem; }
.dashboard-mock .cell span { font-size: .72rem; color: #B6ABA0; text-transform: uppercase; letter-spacing: .05em; }
.dashboard-mock .cell b { display: block; font-family: var(--font-display); font-size: 1.4rem; color: #fff; margin-top: .25rem; }
.dashboard-mock .chart { margin-top: .9rem; height: 120px; border-radius: 12px; background:
    linear-gradient(180deg, rgba(232,160,163,.22), transparent),
    rgba(255,255,255,.03);
  border: 1px solid rgba(255,255,255,.08); display: flex; align-items: flex-end; gap: 6px; padding: 10px; }
.dashboard-mock .chart i { flex: 1; background: linear-gradient(#E8A0A3, var(--red)); border-radius: 4px 4px 0 0; }

/* ---------- Proceso ---------- */
.steps { display: grid; grid-template-columns: repeat(3,1fr); gap: 1.4rem; margin-top: 3rem; counter-reset: step; }
.step { position: relative; padding: 1.7rem; border-radius: var(--r); background: var(--cream); border: 1px solid var(--line); }
.step__num { counter-increment: step; font-family: var(--font-display); font-size: 2.6rem; color: var(--red-tinta); line-height: 1; opacity: .9; }
.step__num::before { content: "0" counter(step); }
.step h3 { font-size: 1.2rem; margin-top: .6rem; }
.step p { margin-top: .5rem; font-size: .95rem; color: var(--muted); }

/* ---------- CTA final ---------- */
.cta-final { position: relative; overflow: hidden; background:
    radial-gradient(700px 340px at 85% -10%, rgba(232,160,163,.28), transparent 60%),
    var(--ink-band); border-radius: clamp(20px, 3vw, 34px); padding: clamp(2.4rem, 6vw, 4.5rem); text-align: center; }
.cta-final h2 { color: #fff; max-width: 22ch; margin-inline: auto; }
.cta-final p { color: #CBC0B4; margin-top: 1rem; max-width: 52ch; margin-inline: auto; }
.cta-final .hero__cta { justify-content: center; margin-top: 2rem; }

/* ---------- Footer ---------- */
.footer { background: var(--ink-band); color: #C4B9AD; padding-block: clamp(3rem,6vw,4.5rem) 2rem; }
.footer__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 2rem; }
.footer__logo { height: 46px; width: auto; margin-bottom: 1.1rem; filter: brightness(0) invert(1); opacity: .95; }
.footer p { color: #A79C90; font-size: .93rem; max-width: 34ch; }
.footer h5 { font-family: var(--font-sans); color: #fff; font-size: .82rem; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 1rem; }
.footer__col a { display: block; padding: .3rem 0; color: #BCB1A5; font-size: .94rem; }
.footer__col a:hover { color: #fff; }
.footer__contact li { display: flex; gap: .6rem; align-items: flex-start; padding: .3rem 0; font-size: .94rem; }
.footer__contact svg { color: #E8A0A3; flex: none; margin-top: 3px; }
.footer__bottom { border-top: 1px solid rgba(255,255,255,.1); margin-top: 2.5rem; padding-top: 1.5rem; display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; font-size: .86rem; color: #8E8478; }
.footer__bottom a:hover { color: #fff; }
.footer__social { display: flex; gap: .6rem; }
.footer__social a { width: 38px; height: 38px; border-radius: 10px; border: 1px solid rgba(255,255,255,.14); display: grid; place-items: center; color: #C4B9AD; }
.footer__social a:hover { background: var(--red); border-color: var(--red); color: #fff; }

/* ---------- Reveal on scroll ---------- */
/* El contenido se ve SIEMPRE, salvo que el JS haya dicho que sabe revelarlo.
 *
 * Antes `.reveal` empezaba en opacidad 0 y sólo el JS la subía. Cualquier tropiezo en
 * main.js —un error, un bloque que no corre, un elemento inyectado después que nadie
 * observa— dejaba secciones enteras invisibles, con el contenido ahí. Fue justo lo que
 * pasó en la tienda: los tres planes en el DOM y la sección en blanco.
 *
 * Una animación no puede ser la razón por la que algo no se ve.
 */
html.revelable .reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1); }
html.revelable .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce){ .reveal{ opacity:1; transform:none; transition:none; } html{ scroll-behavior:auto; } }

/* ---------- Responsive ---------- */
@media (max-width: 940px){
  .hero .container { grid-template-columns: 1fr; }
  .hero__panel { order: -1; max-width: 460px; }
  .why, .cfo { grid-template-columns: 1fr; }
  .cards, .steps { grid-template-columns: 1fr 1fr; }
  .footer__grid { grid-template-columns: 1fr 1fr; }
  .footer__brand { grid-column: 1 / -1; }
}
@media (max-width: 860px){
  .nav__links, .nav__cta .btn { display: none; }
  .nav__toggle { display: inline-flex; }
  /* Menú móvil */
  .nav__links.open {
    display: flex; flex-direction: column; align-items: stretch; gap: .2rem;
    position: absolute; top: 100%; left: 0; right: 0;
    background: var(--surface); border-bottom: 1px solid var(--line); box-shadow: var(--shadow);
    padding: .8rem clamp(1.1rem,4vw,2rem) 1.2rem;
  }
  .nav__links.open > li > a { padding: .8rem .4rem; font-size: 1.05rem; border-bottom: 1px solid var(--cream-2); }
  .nav__links.open .dropdown { position: static; opacity: 1; visibility: visible; transform: none; box-shadow: none; border: none; padding: .2rem 0 .6rem 1rem; min-width: 0; display: none; }
  .nav__links.open .has-menu.open .dropdown { display: block; }
}
@media (max-width: 560px){
  .cards, .steps { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: 1fr; }
  .kpis { grid-template-columns: 1fr 1fr; }
  .dashboard-mock .row { grid-template-columns: 1fr; }
}

/* =========================================================================
   v2 — Tipografía fina + animaciones de scroll + componentes nuevos
   ========================================================================= */

/* Ajuste Didone del hero */
.hero h1 { font-weight: 600; letter-spacing: -.02em; line-height: 1.02; }
.hero h1 em { font-style: italic; font-weight: 600; color: var(--red-tinta); }
.card h3 { font-size: 1.28rem; }

/* Barra de progreso de scroll */
.scroll-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 100;
  background: linear-gradient(90deg, var(--red), #E86A63);
  box-shadow: 0 0 10px rgba(var(--red-rgb),.45);
  transition: width .08s linear;
}

/* Marca de agua π del hero (con parallax) */
.hero__pi {
  position: absolute; top: 50%; margin-top: -.44em; right: -3%;
  font-family: var(--font-display); font-weight: 600; font-size: min(58vw, 760px);
  line-height: 1; color: var(--red-tinta); opacity: .045; pointer-events: none;
  z-index: 0; user-select: none;
}
.hero .container { position: relative; z-index: 1; }
[data-parallax] { will-change: transform; }

/* Variantes de reveal */
.reveal--left  { transform: translateX(-34px); }  .reveal--left.in  { transform: none; }
.reveal--right { transform: translateX(34px); }    .reveal--right.in { transform: none; }
.reveal--scale { transform: scale(.95); }          .reveal--scale.in { transform: none; }

/* Barras que crecen al entrar en pantalla */
.bars i, .dashboard-mock .chart i {
  transform: scaleY(0); transform-origin: bottom;
  transition: transform 1.05s cubic-bezier(.2,.8,.2,1);
}
.bars.in i, .dashboard-mock .chart.in i { transform: scaleY(1); }

/* Banda de estadísticas */
.stats-band { border-top: 1px solid var(--line); padding-block: clamp(2.6rem,5vw,4rem); }
.stats { display: grid; grid-template-columns: repeat(4,1fr); gap: 1.5rem; text-align: center; }
.stat b {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(2.3rem, 4.6vw, 3.5rem); color: var(--ink); line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat b .u { color: var(--red-tinta); }
.stat span { display: block; margin-top: .55rem; font-size: .92rem; color: var(--muted); font-weight: 500; }
.stat + .stat { border-left: 1px solid var(--line); }
@media (max-width: 640px){
  .stats { grid-template-columns: 1fr 1fr; gap: 1.8rem 1rem; }
  .stat:nth-child(odd) { border-left: none; }
}

/* Wordmark de partner (logo en texto, editable desde config.js) */
.trust__logos .wordmark {
  font-family: var(--font-sans); font-weight: 700; font-size: 1.12rem; letter-spacing: -.02em;
  color: var(--muted-2); opacity: .8; filter: grayscale(1); transition: opacity .2s, filter .2s; white-space: nowrap;
}
.trust__logos .wordmark:hover { opacity: 1; filter: none; }
.trust__logos .wordmark .a { color: var(--ink); }
.trust__logos .wordmark em { font-style: normal; color: var(--red-tinta); }

/* Entrada del hero al cargar */
.hero__copy > * { opacity: 0; transform: translateY(18px); animation: heroIn .85s cubic-bezier(.2,.7,.2,1) forwards; }
.hero__copy > *:nth-child(1){ animation-delay:.06s; }
.hero__copy > *:nth-child(2){ animation-delay:.16s; }
.hero__copy > *:nth-child(3){ animation-delay:.26s; }
.hero__copy > *:nth-child(4){ animation-delay:.36s; }
.hero__copy > *:nth-child(5){ animation-delay:.46s; }
.hero__panel { opacity: 0; animation: heroIn 1s cubic-bezier(.2,.7,.2,1) .4s forwards; }
@keyframes heroIn { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce){
  .hero__copy > *, .hero__panel { animation: none; opacity: 1; transform: none; }
  .bars i, .dashboard-mock .chart i { transform: none; transition: none; }
  [data-parallax] { transform: none !important; }
  .scroll-progress { display: none; }
}

/* =========================================================================
   v3 — Componentes de páginas internas
   ========================================================================= */

/* Nav activo */
.nav__links > li > a.is-active { color: var(--red-tinta); }

/* Hero de página interna */
.page-hero { position: relative; overflow: hidden;
  background: radial-gradient(1000px 460px at 82% -12%, var(--red-tint), transparent 60%),
              radial-gradient(700px 360px at -5% 120%, var(--cream-2), transparent 55%), var(--cream);
  border-bottom: 1px solid var(--line); }
.page-hero .container { padding-block: clamp(2.6rem, 6vw, 4.6rem); position: relative; z-index: 1; }
.page-hero .inner { max-width: 780px; }
.page-hero h1 { margin-top: 1rem; }
.page-hero .lead { margin-top: 1.2rem; max-width: 62ch; }
.page-hero .hero__cta { margin-top: 1.9rem; }
.page-hero__pi { position: absolute; top: 50%; margin-top: -.44em; right: -2%; font-family: var(--font-display);
  font-weight: 600; font-size: min(46vw, 520px); line-height: 1; color: var(--red-tinta); opacity: .05; pointer-events: none; z-index: 0; }

/* Breadcrumb */
.crumbs { font-size: .86rem; color: var(--muted); }
.crumbs a:hover { color: var(--red-tinta); }
.crumbs span { margin: 0 .4rem; opacity: .5; }

/* Split dos columnas */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.6rem, 4vw, 3rem); align-items: start; }
.split--wide { grid-template-columns: 1.1fr .9fr; }
@media (max-width: 820px){ .split, .split--wide { grid-template-columns: minmax(0, 1fr); } }

/* Panel / tarjeta de contenido */
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 1.9rem; box-shadow: var(--shadow-sm); }
.panel + .panel { margin-top: 1.2rem; }
.panel h3 { font-size: 1.2rem; margin-bottom: .3rem; }
.panel .eyebrow { margin-bottom: .8rem; }

/* Lista con check roja (independiente) */
.check-list { display: grid; gap: .7rem; margin-top: 1.1rem; }
.check-list li { position: relative; padding-left: 1.7rem; color: var(--ink-2); font-size: .97rem; }
.check-list li::before { content: "✓"; position: absolute; left: 0; top: 0; color: var(--red-tinta); font-weight: 800; }

/* Lista de audiencia (chips en bloque) */
.audience { display: grid; grid-template-columns: repeat(2,1fr); gap: .8rem; margin-top: 1.2rem; }
.audience li { position: relative; padding: .9rem 1rem .9rem 2.4rem; background: var(--cream); border: 1px solid var(--line); border-radius: 12px; font-size: .95rem; color: var(--ink-2); }
.audience li::before { content: "→"; position: absolute; left: 1rem; top: .9rem; color: var(--red-tinta); font-weight: 700; }
@media (max-width: 620px){ .audience { grid-template-columns: 1fr; } }

/* Prosa (texto largo: guías, blog, legal) */
.prose { max-width: 760px; }
.prose.center { margin-inline: auto; }
.prose > * + * { margin-top: 1.05rem; }
.prose h2 { margin-top: 2.4rem; }
.prose h3 { margin-top: 1.8rem; font-size: 1.22rem; }
.prose ul { display: grid; gap: .55rem; padding-left: 0; }
.prose ul li { position: relative; padding-left: 1.4rem; color: var(--ink-2); }
.prose ul li::before { content: ""; position: absolute; left: 2px; top: .62em; width: 7px; height: 7px; border-radius: 50%; background: var(--red); }
.prose strong { color: var(--ink); }

/* Formularios */
.form { display: grid; gap: 1rem; }
.form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
/* Una columna de la rejilla no se encoge por debajo de lo que mide su contenido, y un
 * desplegable mide lo que su opción más larga («General de Ley Personas Morales»): los
 * campos se salían del recuadro. Con min-width:0 la columna manda y el campo se ajusta. */
.form .row > * { min-width: 0; }
.form .row input, .form .row select, .form .row textarea { max-width: 100%; }
/* QUE `hidden` GANE SIEMPRE.
 *
 * El navegador trae `[hidden] { display: none }`, pero cualquier regla propia que ponga
 * un `display` le gana por especificidad: `.field { display: flex }` hacia que un campo
 * marcado como oculto se siguiera viendo. Pasa en silencio -no hay error, sencillamente
 * el elemento esta ahi- y ya habia tres parches sueltos por el archivo para tres casos
 * concretos, que es la señal de que faltaba la regla general.
 *
 * Con esto, `el.hidden = true` esconde de verdad, sea cual sea la clase del elemento.
 */
[hidden] { display: none !important; }

.field { display: flex; flex-direction: column; gap: .35rem; }
.field label { font-size: .85rem; font-weight: 600; color: var(--ink-2); }
.field .req { color: var(--red-tinta); }
.field input, .field select, .field textarea { font: inherit; font-size: .97rem; padding: .8rem .9rem; border: 1px solid var(--line-2); border-radius: 10px; background: var(--surface); color: var(--ink); transition: border-color .15s, box-shadow .15s; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--red); box-shadow: 0 0 0 3px var(--red-tint); }
.field textarea { min-height: 130px; resize: vertical; }
.form__note { font-size: .84rem; color: var(--muted); }
@media (max-width: 640px){ .form .row { grid-template-columns: 1fr; } }

/* Embed (Cal.com / mapa) placeholder */
.embed-ph { border: 2px dashed var(--line-2); border-radius: var(--r); background: var(--cream); padding: clamp(2rem,5vw,3.5rem); text-align: center; color: var(--muted); }
.embed-ph svg { color: var(--red-tinta); margin-bottom: .8rem; }

/* Blog */
.post-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 1.5rem; margin-top: 2.5rem; }
@media (max-width: 860px){ .post-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px){ .post-grid { grid-template-columns: 1fr; } }
.post-card { display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; transition: transform .2s, box-shadow .2s; }
.post-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.post-card__body { padding: 1.5rem; display: flex; flex-direction: column; flex: 1; }
.post-card .tagline { font-size: .76rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--red-tinta); }
.post-card h3 { margin-top: .5rem; font-size: 1.18rem; }
.post-card p { margin-top: .5rem; font-size: .94rem; color: var(--muted); flex: 1; }
.post-card .link-arrow { margin-top: 1rem; }
.post-hero__meta { display: flex; gap: 1rem; align-items: center; font-size: .88rem; color: var(--muted); margin-top: 1rem; }

/* =========================================================================
   v4 — Maqueta de plataforma "a la medida"
   ========================================================================= */
.app-mock { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; overflow: hidden; box-shadow: var(--shadow-lg); }
.app-mock__bar { display: flex; align-items: center; gap: .45rem; padding: .7rem 1rem; border-bottom: 1px solid var(--line); background: var(--cream); }
.app-mock__bar i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-2); }
.app-mock__bar b { margin-left: .6rem; font-family: var(--font-sans); font-weight: 600; font-size: .82rem; color: var(--muted); }
.app-mock__body { display: grid; grid-template-columns: 168px 1fr; min-height: 300px; }
.app-mock__side { background: var(--ink-band); padding: 1rem .7rem; display: flex; flex-direction: column; gap: .25rem; }
.app-mock__side a { color: #B9AEA2; font-size: .8rem; padding: .45rem .6rem; border-radius: 8px; display: flex; gap: .55rem; align-items: center; }
.app-mock__side a svg { width: 15px; height: 15px; flex: none; }
.app-mock__side a.on { background: rgba(255,255,255,.09); color: #fff; }
.app-mock__main { padding: 1.1rem; }
.app-mock__tiles { display: grid; grid-template-columns: repeat(3,1fr); gap: .7rem; }
.app-mock__tile { background: var(--cream); border-radius: 10px; padding: .75rem .8rem; }
.app-mock__tile span { font-size: .64rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; font-weight: 600; }
.app-mock__tile b { display: block; font-family: var(--font-display); font-size: 1.3rem; margin-top: .15rem; color: var(--ink); }
.app-mock__tile.up b { color: #1f9d61; }
.app-mock__chart { margin-top: .8rem; height: 120px; border: 1px solid var(--line); border-radius: 10px; display: flex; align-items: flex-end; gap: 5px; padding: 9px; background: var(--bg); }
.app-mock__chart i { flex: 1; background: linear-gradient(var(--red), var(--red-600)); border-radius: 4px 4px 0 0; opacity: .9; }
@media (max-width: 560px){
  .app-mock__body { grid-template-columns: 1fr; }
  .app-mock__side { flex-direction: row; overflow-x: auto; }
  .app-mock__tiles { grid-template-columns: 1fr 1fr; }
}

/* Comparación a la medida vs enlatado */
.vs { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; margin-top: 2.5rem; }
.vs__col { border-radius: var(--r); padding: 1.7rem; border: 1px solid var(--line); }
.vs__col--bad { background: var(--cream); }
.vs__col--good { background: var(--red-tint); border-color: rgba(var(--red-rgb),.25); }
.vs__col h3 { font-size: 1.15rem; margin-bottom: 1rem; }
.vs__col ul { display: grid; gap: .6rem; }
.vs__col li { position: relative; padding-left: 1.7rem; font-size: .95rem; color: var(--ink-2); }
.vs__col--bad li::before { content: "✕"; position: absolute; left: 0; color: var(--muted-2); font-weight: 700; }
.vs__col--good li::before { content: "✓"; position: absolute; left: 0; color: var(--red-tinta); font-weight: 800; }
@media (max-width: 640px){ .vs { grid-template-columns: 1fr; } }

/* =========================================================================
   v5 — Tienda ContaDigital + carrito + cotizador
   ========================================================================= */
.plan { display: flex; flex-direction: column; }
.plan.is-featured { border-color: var(--red); box-shadow: 0 14px 40px rgba(var(--red-rgb),.14); position: relative; }
.plan__flag { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); background: var(--red); color: #fff; font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: .3rem .8rem; border-radius: 999px; }
.plan__name { font-family: var(--font-sans); font-weight: 700; font-size: 1.15rem; }
.plan__price { display: flex; align-items: baseline; gap: .3rem; margin: .8rem 0 .2rem; }
.plan__price b { font-family: var(--font-display); font-weight: 600; font-size: 2.4rem; color: var(--ink); line-height: 1; }
.plan__price span { color: var(--muted); font-size: .9rem; }
.plan__desc { color: var(--muted); font-size: .93rem; margin-bottom: 1rem; }
.plan .check-list { margin-top: 0; flex: 1; }
.plan .btn { margin-top: 1.4rem; }
/* Cantidad / paquete en la tienda: va encima del botón y le quita su margen. */
.plan { min-width: 0; }
.plan__qty { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem; margin-top: 1.2rem; font-size: .9rem; font-weight: 600; }
.plan__qty select { flex: 1 1 12rem; }
.plan__qty input, .plan__qty select { min-width: 0; max-width: 100%; padding: .45rem .6rem; border: 1px solid var(--line, #ddd); border-radius: 8px; font: inherit; font-weight: 400; }
.plan__qty input { width: 6rem; }
.plan__qty + .btn { margin-top: .7rem; }

/* Carrito flotante */
.cart-fab { position: fixed; right: 20px; bottom: 20px; z-index: 70; width: 58px; height: 58px; border-radius: 50%; background: var(--red); color: #fff; border: none; box-shadow: 0 10px 26px rgba(var(--red-rgb),.4); display: grid; place-items: center; }
.cart-fab svg { width: 24px; height: 24px; }
.cart-fab__count { position: absolute; top: -4px; right: -4px; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 999px; background: var(--ink); color: #fff; font-size: .74rem; font-weight: 700; display: grid; place-items: center; border: 2px solid #fff; }
.cart-fab[hidden] { display: none; }

.cart-drawer { position: fixed; inset: 0 0 0 auto; width: min(420px, 92vw); background: var(--surface); z-index: 90; box-shadow: -20px 0 60px rgba(27,23,20,.2); transform: translateX(100%); transition: transform .3s cubic-bezier(.2,.8,.2,1); display: flex; flex-direction: column; }
.cart-drawer.open { transform: none; }
.cart-backdrop { position: fixed; inset: 0; background: rgba(27,23,20,.4); z-index: 89; opacity: 0; visibility: hidden; transition: opacity .3s; }
.cart-backdrop.open { opacity: 1; visibility: visible; }
.cart-drawer__head { display: flex; align-items: center; justify-content: space-between; padding: 1.2rem 1.4rem; border-bottom: 1px solid var(--line); }
.cart-drawer__head h3 { font-size: 1.2rem; }
.cart-close { background: none; border: none; font-size: 1.5rem; color: var(--muted); line-height: 1; }
.cart-items { flex: 1; overflow-y: auto; padding: 1rem 1.4rem; }
.cart-item { display: flex; gap: .8rem; align-items: flex-start; padding: .9rem 0; border-bottom: 1px solid var(--cream-2); }
.cart-item__info { flex: 1; }
.cart-item__info b { font-size: .95rem; font-weight: 600; }
.cart-item__info span { display: block; color: var(--muted); font-size: .85rem; }
.cart-item__rm { background: none; border: none; color: var(--muted-2); font-size: .8rem; text-decoration: underline; }
.cart-item__price { font-weight: 700; white-space: nowrap; }
.cart-empty { color: var(--muted); text-align: center; padding: 2rem 0; }
.cart-drawer__foot { padding: 1.2rem 1.4rem; border-top: 1px solid var(--line); }
.cart-total { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 1rem; }
.cart-total b { font-family: var(--font-display); font-size: 1.5rem; }
.cart-note { font-size: .8rem; color: var(--muted); margin-top: .8rem; text-align: center; }
.cart-cuenta { display: block; font-size: .85rem; margin-bottom: .7rem; }
.cart-cuenta small { color: var(--muted); }
.cart-cuenta input { display: block; width: 100%; margin-top: .3rem; padding: .5rem .6rem; border: 1px solid var(--line, #ddd); border-radius: 8px; font: inherit; }

/* =========================================================================
   v6 — Agenda propia (booking) + Panel de administración
   ========================================================================= */
.slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(86px, 1fr)); gap: .55rem; margin-top: .5rem; }
.slot { padding: .6rem .4rem; border: 1px solid var(--line-2); border-radius: 10px; background: var(--realce); font-weight: 600; font-size: .92rem; text-align: center; color: var(--ink-2); transition: .15s; }
.slot:hover { border-color: var(--red); color: var(--red-tinta); }
.slot.sel { background: var(--red); color: #fff; border-color: var(--red); }
.slot[disabled] { opacity: .35; cursor: not-allowed; }
.booking-ok { background: var(--red-tint); border: 1px solid rgba(var(--red-rgb),.25); border-radius: var(--r); padding: 1.6rem; }
.booking-ok h3 { color: var(--red-tinta); }
.gcal-link { margin-top: 1rem; }

/* Panel admin */
.admin-shell { min-height: 100vh; background: var(--cream); }
/* ===================== El encabezado del panel =====================
 *
 * Tenía siete controles y CADA UNO llevaba su estilo escrito a mano en el HTML,
 * con `rgba(255,255,255,.12)` repetido seis veces. Por eso se veía como un
 * montón de pastillas de sitios distintos y no como una barra: nadie los había
 * diseñado juntos, se habían ido añadiendo.
 *
 * Ahora hay UNA familia —`.top-ctl`— y las variantes son de forma, no de color:
 * cuadrada para un icono, alargada para el buscador, con flecha para un
 * desplegable. Cambiar el aspecto de la barra es cambiar tres líneas, y ninguno
 * se queda atrás porque ninguno tiene estilo propio.
 *
 * Y va de lado a lado. Estaba dentro de `.container`, que la centraba con un
 * hueco enorme a cada lado en un monitor ancho mientras las pestañas de debajo
 * sí llegaban al borde: dos barras pegadas, alineadas de forma distinta. Eso es
 * lo que hacía que se viera descuadrada aunque cada pieza estuviera bien.
 */
.admin-top { background: var(--ink-band); color: #fff; padding: .55rem 0; position: sticky; top: 0; z-index: 60;
  border-bottom: 1px solid rgba(255,255,255,.08); }
.admin-top .container { max-width: none; width: 100%; padding-inline: clamp(.6rem, 2vw, 1.2rem); gap: .8rem; }

/* El control de la barra. Todos miden lo mismo de alto: una fila de botones que
 * no se alinean es lo primero que se ve y lo último que se sabe explicar. */
.top-ctl { display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  height: 32px; padding: 0 .7rem; border-radius: 9px; flex: none; white-space: nowrap;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.13);
  color: #fff; font: inherit; font-size: .82rem; font-weight: 500; cursor: pointer;
  transition: background .15s ease, border-color .15s ease; }
.top-ctl:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.24); }
/* Sin esto, `hidden` deja de esconder.
 *
 * El navegador esconde un elemento con `hidden` mediante `display:none`, y basta
 * con que una clase diga `display:inline-flex` para ganarle: no falla, no avisa,
 * simplemente el atributo deja de servir. Aquí salió a la vista porque el
 * selector de cuentas —vacío, de la plataforma— aparecía en el panel de un
 * cliente como un control con una flecha y nada dentro. Lo mismo le pasaba al
 * botón de apps y al de ayuda, que se ven antes de que la sesión decida si esta
 * cuenta puede verlos. */
.top-ctl[hidden], .menumodo[hidden] { display: none !important; }
.top-ctl:focus-visible { outline: 2px solid rgba(255,255,255,.6); outline-offset: 2px; }
.top-ctl svg { width: 15px; height: 15px; flex: none; }
.top-ctl--ico { width: 32px; padding: 0; }
.top-ctl--cuad { width: 34px; height: 34px; padding: 0; border-radius: 10px; }
/* El buscador es el único que pesa más, porque es el único que se usa a diario
 * sin saber de antemano qué se busca. Lo demás son destinos concretos. */
.top-buscar { min-width: 148px; justify-content: flex-start; padding-left: .75rem; }
.top-buscar kbd { margin-left: auto; background: rgba(255,255,255,.13); border: 1px solid rgba(255,255,255,.16);
  border-radius: 5px; color: rgba(255,255,255,.75); font-size: .66rem; padding: .08rem .32rem; font-family: inherit; }
/* Los desplegables nativos en una barra oscura son la pieza que más canta: cada
 * navegador los pinta a su manera y ninguno los pinta oscuros. Se les quita la
 * apariencia y se les dibuja la flecha, para que sean un control más de la fila. */
.top-sel { appearance: none; -webkit-appearance: none; max-width: 168px; padding-right: 1.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .5rem center; background-size: 11px;
  text-overflow: ellipsis; }
.top-sel option { background: var(--ink-band); color: #fff; }
/* «Cerrar sesión» se tiene que ver. Estaba casi transparente para no competir, y quien
 * lo buscaba no lo encontraba: salir de una cuenta en una computadora compartida no
 * es algo que deba costar buscarlo. Lleva borde y su icono, siempre en la esquina. */
.top-salir { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.32); color: #fff; font-weight: 600; }
.top-salir:hover { background: #fff; border-color: #fff; color: var(--ink-band, #1f2328); }
@media (max-width: 700px) { .top-salir span { display: none; } .top-salir { width: 32px; padding: 0; } }

/* La marca. Si la cuenta subió su logotipo, va sobre una tarjeta blanca con aire.
 *
 * No es un adorno: casi todos los logotipos que suben son PNG con fondo blanco o
 * con tinta oscura. Pegados sobre la barra, el primero se ve como un recorte
 * blanco y el segundo directamente no se ve. Con la tarjeta, los dos se ven
 * bien y —lo que importa— se ven a propósito. */
.brand__chip { display: inline-flex; align-items: center; background: #fff; border-radius: 8px;
  padding: 4px 8px; flex: none; }
.brand__chip img { height: 22px; width: auto; display: block; }
/* El separador y el nombre del módulo: lo que dice DÓNDE estás. */
.top-sep { flex: none; width: 1px; height: 20px; background: rgba(255,255,255,.16); }
.top-modulo { color: #fff; font-weight: 600; font-size: .9rem; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
/* La insignia de modo. Antes era amarillo puro y se llevaba la mirada de toda la
 * barra; es una advertencia útil, no la protagonista. */
.top-modo { flex: none; font-size: .655rem; font-weight: 700; letter-spacing: .07em;
  border-radius: 6px; padding: .2rem .45rem; white-space: nowrap; text-transform: uppercase; }
/* EL PLAN DE LA CUENTA (2026-10-01): el negocio y su plan, y si está en prueba, cuántos
 * días le quedan. Es un botón —lleva a Mi plan—, pero no compite con los de la derecha:
 * texto claro sobre la barra, el plan en negritas, el aviso en ámbar. */
.top-plan { display: inline-flex; align-items: center; gap: .45rem; min-width: 0; height: 28px;
  padding: 0 .6rem; border-radius: 8px; border: 1px solid rgba(255,255,255,.16);
  background: rgba(255,255,255,.06); color: rgba(255,255,255,.82); font: inherit; font-size: .76rem;
  white-space: nowrap; cursor: pointer; transition: background .15s ease, border-color .15s ease; }
.top-plan[hidden] { display: none !important; }
.top-plan:hover { background: rgba(255,255,255,.13); border-color: rgba(255,255,255,.28); }
.top-plan:focus-visible { outline: 2px solid rgba(255,255,255,.6); outline-offset: 2px; }
.top-plan__neg { overflow: hidden; text-overflow: ellipsis; max-width: 16ch; }
.top-plan__neg::after { content: "·"; margin-left: .45rem; opacity: .55; }
.top-plan__plan { font-weight: 700; color: #fff; flex: none; }
.top-plan__est { color: rgba(255,255,255,.75); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.top-plan__est--aviso { color: #F5C518; font-weight: 600; }
.top-plan { flex: 0 1 auto; overflow: hidden; }   /* su ancho mínimo (el nombre del plan) lo pone admin.js */
.top-plan__plan { flex-shrink: 0; }
/* Si falta espacio (el selector de empresa de un despacho, una pantalla mediana), la
 * etiqueta del plan desplaza a «MI NEGOCIO», que sólo dice que la cuenta es tuya.
 * «OPERANDO CLIENTE» no se quita nunca: avisa que lo que toques no es tuyo. */
@media (max-width: 1400px) {
  .admin-top div:has(> #planChip:not([hidden])) > #modoBadge:not([data-modo="cliente"]) { display: none; }
}
.top-plan--plataforma { background: rgba(245,197,24,.18); border-color: rgba(245,197,24,.35); }
.top-plan--plataforma .top-plan__plan { color: #F5C518; text-transform: uppercase; letter-spacing: .07em; font-size: .68rem; }
@media (max-width: 1180px) { .top-plan__neg { display: none; } }/* En un teléfono la etiqueta del plan ocupa el lugar de la insignia «MI NEGOCIO»: las dos
 * no caben junto a los botones, y la que dice qué contrataste es la que lleva a algún lado. */
@media (max-width: 620px) {
  .top-plan__est { display: none; }
  .top-plan { max-width: 40vw; overflow: hidden; }
}

@media (max-width: 700px) {
  .top-buscar { min-width: 0; }
  .top-buscar kbd, .top-buscar span { display: none; }
  .top-buscar { width: 32px; padding: 0; }
}

/* ===== Command Center (dashboard glassmorphism) ===== */
.omni {
  --omni-soft: 0 8px 32px rgba(0,0,0,.07);
  --omni-hover: 0 12px 44px rgba(0,0,0,.12);
  background-image:
    radial-gradient(at 0% 0%, hsla(353,60%,45%,.07) 0, transparent 50%),
    radial-gradient(at 90% 5%, hsla(225,39%,40%,.06) 0, transparent 50%),
    radial-gradient(at 50% 100%, hsla(339,49%,45%,.05) 0, transparent 55%);
  margin: -1rem; padding: 1.4rem; border-radius: 24px;
}
.omni-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.2rem; }
.omni-eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--ink-2); font-weight: 700; }
.omni-title { font-family: var(--font-sans); font-size: 1.5rem; font-weight: 700; letter-spacing: -.5px; margin-top: .2rem; }
.omni-card {
  background: rgba(255,255,255,.66); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(255,255,255,.55); border-radius: 20px; box-shadow: var(--omni-soft);
  padding: 1.4rem 1.5rem; transition: transform .25s, box-shadow .25s;
}
:root[data-theme="dark"] .omni-card { background: rgba(40,38,40,.6); border-color: rgba(255,255,255,.08); }
/* Cuatro columnas fijas recibían CINCO tarjetas en dos pantallas —Sistema maestro y el
 * Consolidado— y la quinta se quedaba sola en un segundo renglón con tres huecos al lado.
 *
 * `auto-fit` en vez de un número fijo: se acomodan las que haya. Con cinco da dos
 * renglones parejos en vez de 4+1. `minmax` con `1fr` mantiene el mínimo sin desbordar
 * cuando son muchas. */
.omni-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: 1.1rem; margin-bottom: 1.1rem; }
.omni-kpis .omni-card:hover { transform: translateY(-3px); box-shadow: var(--omni-hover); }
.omni-lbl { font-size: 12px; color: var(--ink-2); font-weight: 600; text-transform: uppercase; letter-spacing: .5px; }
.omni-val { font-size: 2rem; font-weight: 700; margin: .5rem 0 .5rem; letter-spacing: -1px; }
.omni-pill { display: inline-block; padding: 3px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; background: rgba(0,0,0,.04); color: var(--ink-2); }
.omni-alert { border: 1px solid rgba(193,39,45,.3); }
.omni-grid2 { display: grid; grid-template-columns: 2fr 1fr; gap: 1.1rem; margin-bottom: 1.1rem; }
.omni-chart { display: flex; flex-direction: column; min-height: 320px; }
.omni-section { font-size: .93rem; font-weight: 700; margin-bottom: 1rem; display: flex; align-items: center; gap: .5rem; }
.omni-legend { display: flex; gap: 1.2rem; font-size: 12px; color: var(--ink-2); margin-top: .6rem; }
.omni-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: middle; }
.omni-dot { width: 9px; height: 9px; background: var(--red); border-radius: 50%; display: inline-block; }
.omni-feed-list { display: flex; flex-direction: column; gap: 1rem; max-height: 300px; overflow-y: auto; }
.omni-feed-item { display: flex; gap: .8rem; align-items: flex-start; }
.omni-feed-ico { width: 34px; height: 34px; border-radius: 11px; background: var(--tarjeta); box-shadow: 0 2px 8px rgba(0,0,0,.06); display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-weight: 700; font-size: .82rem; }
.omni-feed-item h4 { font-size: .84rem; font-weight: 700; margin-bottom: 2px; }
.omni-feed-item p { font-size: .78rem; color: var(--ink-2); }
.omni-feed-item .t { font-size: 11px; color: var(--ink-2); margin-top: 3px; font-weight: 600; }
@media (max-width: 900px) { .omni-kpis { grid-template-columns: repeat(2,1fr); } .omni-grid2 { grid-template-columns: 1fr; } }

/* Lanzador de aplicaciones (estilo Odoo) */
#appLauncher { position: fixed; inset: 0; z-index: 40; background: var(--cream, #f6f4f2); overflow-y: auto; }
.launcher-inner { max-width: 1000px; margin: 0 auto; padding: 6rem 1.4rem 3rem; }
.app-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1.4rem; }
.app-card { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 18px; padding: 1.7rem 1rem; text-align: center; cursor: pointer; transition: transform .18s, box-shadow .18s, border-color .18s; }
.app-card:hover { transform: translateY(-3px); box-shadow: 0 12px 32px rgba(0,0,0,.09); border-color: var(--red); }
.app-ico { width: 54px; height: 54px; border-radius: 15px; margin: 0 auto .8rem; display: flex; align-items: center; justify-content: center; color: #fff; }
.app-ico svg { width: 25px; height: 25px; }
.app-card b { font-size: .95rem; font-weight: 600; }
/* Constructor de páginas por bloques */
.pg-block { border: 1px solid var(--line); border-radius: 14px; padding: 1rem 1.2rem; margin-bottom: .9rem; background: var(--surface); }
.pg-block-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .8rem; }
.pg-drag { cursor: grab; color: var(--ink-2); font-size: 18px; line-height: 1; user-select: none; padding: 0 .2rem; }
.pg-drag:active { cursor: grabbing; }
.pg-block.pg-dragging { opacity: .5; }
.pg-block.drop-before { box-shadow: 0 -3px 0 0 var(--red); }
.pg-block.drop-after { box-shadow: 0 3px 0 0 var(--red); }
.pg-mini { width: 30px; height: 30px; border: 1px solid var(--line); background: var(--tarjeta); border-radius: 8px; cursor: pointer; font-size: .88rem; }
.pg-mini:hover { border-color: var(--red); color: var(--red-tinta); }
.pg-img { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.pg-img-prev { width: 110px; height: 66px; border-radius: 10px; border: 1px dashed var(--line); background: var(--tarjeta) center/cover no-repeat; flex: 0 0 auto; }

/* Cargadores de imagen del diseñador de sitio */
.imgup { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.imgup-prev { width: 92px; height: 62px; border-radius: 10px; border: 1px dashed var(--line); background: var(--surface) center/cover no-repeat; flex: 0 0 auto; }
.imgup-btn { cursor: pointer; }
/* El logotipo de una empresa (ficha de Empresas › Apariencia y moneda): la vista previa
 * sobre blanco —casi todos los logotipos son tinta oscura o fondo blanco y en el tema
 * oscuro no se verían—, y «Subir logotipo» / «Cambiar» / «Quitar» al lado. */
.logo-up { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.logo-up__prev { width: 150px; height: 64px; border-radius: 10px; border: 1px dashed var(--line); flex: 0 0 auto;
  background: var(--surface) center/contain no-repeat; display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: .76rem; }
.logo-up__prev.con { background-color: #fff; border-style: solid; background-origin: content-box; padding: 6px 10px; }
.logo-up__prev.con span { display: none; }
.logo-up__acc { display: flex; gap: .5rem; flex-wrap: wrap; }
.logo-up__btn { cursor: pointer; }
.logo-up__msg { flex-basis: 100%; margin: 0; }
.galeria-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: .7rem; }
.galeria-item { position: relative; aspect-ratio: 4/3; border-radius: 10px; overflow: hidden; border: 1px solid var(--line); }
.galeria-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.galeria-item button { position: absolute; top: 4px; right: 4px; width: 24px; height: 24px; border: 0; border-radius: 50%; background: rgba(0,0,0,.6); color: #fff; cursor: pointer; font-size: .88rem; line-height: 1; }

.social-fields { display: grid; gap: .6rem; }
.social-row { display: flex; align-items: center; gap: .7rem; }
.social-row input { flex: 1; }
.social-ico { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; }
.social-ico svg { width: 19px; height: 19px; }
.admin-top .container { display: flex; align-items: center; justify-content: space-between; }
.admin-top .brand__pi { font-size: 1.5rem; }
.admin-top b { font-family: var(--font-sans); font-weight: 600; }
.admin-login { max-width: 380px; margin: 8vh auto; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 2rem; box-shadow: var(--shadow); }
.admin-tabs { display: flex; gap: .5rem; margin: 1.6rem 0; }
.admin-tab { padding: .6rem 1.1rem; border-radius: 999px; border: 1px solid var(--line-2); background: var(--surface); font-weight: 600; font-size: .92rem; color: var(--ink-2); }
.admin-tab.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.admin-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 1.5rem; align-items: start; }
@media (max-width: 900px){ .admin-grid { grid-template-columns: 1fr; } }
/* Lista tipo tabla: un solo panel con filas divididas */
/* La tarjeta la da el CONTENEDOR (.admin-list), no la fila. Pero JS mete filas en varios
   contenedores que son <div> pelones, y ahí las mismas listas salían desnudas sobre el
   fondo, sin borde ni tarjeta, con el separador flotando en el aire. El :has() acierta con
   los que de verdad acaban teniendo filas —sea cual sea— en vez de con la lista que yo
   pueda adivinar leyendo el JS. */
.admin-list, div:has(> .admin-row) { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; box-shadow: 0 1px 2px rgba(0,0,0,.03); }
.admin-list > .form__note, div:has(> .admin-row) > .form__note { padding: 1.1rem 1.2rem; margin: 0; }
.admin-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; background: none; border: none; border-bottom: 1px solid var(--line); border-radius: 0; padding: .8rem 1.15rem; transition: background .12s; }
.admin-row:last-child { border-bottom: none; }
.admin-row:hover { background: var(--realce); }
.admin-row b { font-weight: 600; font-size: .93rem; }
.admin-row span { color: var(--muted); font-size: .82rem; margin-top: .1rem; }
.admin-del { background: none; border: none; color: var(--red-tinta); font-size: .84rem; font-weight: 600; cursor: pointer; padding: .2rem .4rem; border-radius: 6px; }
.admin-del:hover { background: rgba(193,39,45,.08); }
/* ===================== Las que se escribían y no existían =====================
 *
 * Veintiuna clases estaban puestas en elementos de verdad y no tenían una sola
 * regla ni se buscaban desde el JS: no rompían nada, sólo se veían peor de lo
 * que estaban escritas. Las encontró `verificar-estilos`, que es lo que impide
 * que vuelva a pasar sin que nadie se entere.
 *
 * Todas se resuelven con el vocabulario que ya había —`.btn`, `.badge-soft`,
 * `.tabla-wrap`, `.tb-sub`— en lugar de inventar uno nuevo al lado. Una clase
 * huérfana se arregla poniéndola en la familia que le tocaba, no dándole un
 * aspecto propio.
 */

/* El botón con énfasis. `.btn` ya es rojo relleno, así que esto NO cambia cómo
 * se ven hoy los 27 que lo llevan: lo que hace es que sigan siendo el principal
 * el día que `.btn` se vuelva el neutro. Estaba escrito en «Guardar», «Guardar
 * sitio» y «Activar publicidad»; que la clase más importante del panel no
 * existiera es exactamente el fallo que se buscaba. */
.btn--primary { background: var(--red); color: #fff; border-color: transparent; }
.btn--primary:hover { background: var(--red-600); }
/* Más pequeño que `--sm`: para los botones que van DENTRO de una fila de tabla,
 * donde uno normal parte el renglón. */
.btn--mini { padding: .2rem .5rem; font-size: .74rem; border-radius: 7px; }

/* El aviso de un formulario: lo que sale al guardar. El color lo pone el JS
 * según haya ido bien o mal —verde o rojo—, así que aquí sólo va la forma. Sin
 * esto eran diecinueve líneas de texto suelto, del tamaño del cuerpo y pegadas
 * al botón. */
.form__msg { display: block; margin-top: .7rem; font-size: .87rem; font-weight: 500; line-height: 1.4; }

/* La casilla con su texto, alineados. Sin esto la casilla se iba arriba y el
 * texto quedaba a media altura, que es el defecto que delata un formulario
 * hecho a trozos. */
.chk { display: inline-flex; align-items: center; gap: .45rem; font-size: .88rem; cursor: pointer; }
.chk input { margin: 0; flex: none; }

/* La etiqueta de estado en línea. Es `.badge-soft` con color: se separan porque
 * `.badge-soft` es neutra y ésta dice si algo salió bien. */
.pill { display: inline-block; border-radius: 999px; padding: .12rem .6rem; font-size: .74rem;
  font-weight: 600; background: var(--cream-2); color: var(--muted); }
.pill--ok { background: var(--ok-fondo, rgba(31,122,77,.12)); color: var(--ok-tinta); }
/* Las otras cuatro. `.pill` ya existía con una sola variante -la verde-, asi que un
   estado que no fuera «bien» salia en gris: «cancelada» y «calculada» se veian igual.
   Los colores salen de los mismos tokens que los avisos, que es lo que hace que una
   pastilla verde signifique lo mismo en toda la plataforma. */
.pill--aviso  { background: var(--aviso-fondo); color: var(--aviso-tinta); }
.pill--info   { background: var(--info-fondo); color: var(--info-tinta); }
.pill--mal    { background: var(--mal-fondo); color: var(--mal-tinta); }
.pill--neutro { background: var(--neutro-fondo); color: var(--neutro-tinta); }

/* La línea de debajo de un indicador. Es lo mismo que `.tb-sub` y por eso se
 * escribe una vez y se le da el otro nombre: dos reglas iguales con dos nombres
 * se separan en cuanto alguien toque una. */
.kpi__sub, .tb-sub { color: var(--muted); font-size: .8rem; }

/* Una tabla pequeña dentro de una tarjeta —los datos de un registro DNS, el
 * desglose de un cálculo—. No es la tabla grande con su marco: es una lista de
 * dos columnas que resulta que se lee mejor alineada. */
.tb { width: 100%; border-collapse: collapse; font-size: .86rem; }
.tb td { padding: .3rem .5rem .3rem 0; vertical-align: top; }
.tb tr + tr td { border-top: 1px solid var(--line); }
.tb code { font-size: .82rem; }
/* La tabla del pivote va dentro de `.tabla-wrap`, que ya pone el marco; aquí
 * sólo hace falta que las celdas respiren igual que en las demás. */
.tabla { width: 100%; border-collapse: collapse; }

/* Dos columnas que se apilan solas. Estaba escrito a mano en el HTML con su
 * `grid-template-columns` de sesenta caracteres; aquí se dice una vez. */
.tb-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; }

/* «Avísame cuando esté»: es el botón de un módulo que todavía no se vende, y
 * tiene que verse como una espera y no como una compra. */
.mod-app__pedir { font-style: normal; opacity: .9; }

/* El cuerpo de Ajustes, al lado de su índice. `.aj-nav` sí tenía regla y esto
 * no: el índice quedaba pegado al contenido. */
.aj-cuerpo { min-width: 0; }

/* El campo de «con cuánto paga» del punto de venta. Es el que más se teclea de
 * toda la pantalla y era el único sin formato. */
.cart-field { font: inherit; font-size: 1rem; padding: .6rem .7rem; border: 1px solid var(--line-2);
  border-radius: 10px; background: var(--surface); color: var(--ink); }
.cart-field:focus { outline: none; border-color: var(--red); box-shadow: 0 0 0 3px var(--red-tint); }

/* La columna del catálogo en el punto de venta: la que se desplaza mientras el
 * ticket de al lado se queda quieto. */
.pos-catalogo { min-width: 0; }

/* La tarjeta de actividad reciente del tablero. */
.omni-feed { display: flex; flex-direction: column; }

/* El constructor de páginas: el desplegable de estilo de un bloque y la rejilla
 * de sus campos. */
.pg-estilo { border-top: 1px solid var(--line); padding-top: .5rem; }
.pg-estilo > summary { color: var(--muted); }
.pg-fields { display: grid; gap: .6rem; }

/* El nombre del bloque en la lista del lienzo, que se corta en vez de empujar
 * al tirador de arrastre fuera de la columna. */
.ed-item__nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Latido: se le pone a un elemento para que se note que acaba de cambiar. El JS
 * lo ponía y no pasaba nada, que es la peor versión de un aviso. */
@keyframes pi-pulse { 0% { box-shadow: 0 0 0 0 var(--red-tint); } 70% { box-shadow: 0 0 0 10px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
.pulse { animation: pi-pulse 1.2s ease-out 2; }
@media (prefers-reduced-motion: reduce) { .pulse { animation: none; } }

/* ===================== Las filas =====================
 *
 * Cuatro maneras de poner cosas en fila estaban escritas a mano 116 veces en el
 * HTML del panel. No eran cuatro decisiones: eran ciento dieciséis copias de
 * cuatro decisiones, y cambiar la separación de las filas significaba buscar y
 * reemplazar en un archivo de cinco mil líneas sin saber si se dejaba alguna.
 *
 * Los valores son EXACTAMENTE los que había: esto no cambia cómo se ve nada, y
 * se comprobó midiendo la posición de los 6.148 elementos del panel antes y
 * después. Lo que cambia es que ahora hay un sitio donde tocarlas.
 *
 * No se convirtieron los márgenes ni los anchos sueltos —`margin-top:.8rem`,
 * `max-width:640px`— aunque también se repiten. Ésos son decisiones de una
 * pantalla concreta, y darles un nombre como `.mt-08` sería cambiar un número
 * por un alias del mismo número: la misma información, un salto más para
 * leerla. */
.fila { display: flex; align-items: center; gap: 1rem; }
/* Una fila de controles pequeños: filtros, selectores de periodo. */
.fila-chica { display: flex; align-items: center; gap: .5rem; font-size: .9rem; }
/* Una fila de botones. Sin `align-items` a propósito: se estiran a la misma
 * altura, que es lo que se quiere cuando uno tiene dos renglones de texto. */
.fila-acc { display: flex; gap: .6rem; }
.fila-acc--wrap { flex-wrap: wrap; }

.badge-soft { display: inline-block; background: var(--cream-2); border-radius: 999px; padding: .1rem .55rem; font-size: .74rem; color: var(--muted); }

/* =========================================================================
   Tabla estilo Odoo — vista de datos con columnas (firma Pi Management)
   ========================================================================= */
/* ---------- Una sola forma de empezar una pantalla ----------
 *
 * Había cuatro: .tbl-toolbar con un <h3> (la mayoría), <h2 class="panel-title"> (19),
 * .omni-head (el tablero) y una sección que arrancaba directamente en un .panel. Y el
 * mismo título en tres tamaños, porque el h3 del toolbar era fluido —clamp(1.2rem,
 * 2.2vw, 1.5rem)— mientras panel-title y omni-title eran fijos en 1.5rem: coincidían en
 * escritorio y se separaban al estrechar, que es justo donde peor se nota.
 *
 * No se tocan las 94 secciones a mano. Se hace que las cuatro variantes rindan igual. */
.tbl-toolbar h3, .panel-title, .omni-title { font-size: 1.5rem; line-height: 1.2; letter-spacing: -.01em; }
@media (max-width: 620px){ .tbl-toolbar h3, .panel-title, .omni-title { font-size: 1.25rem; } }

.tbl-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.2rem; }
/* Sin flex-wrap, tres botones de acción empujaban el título fuera de la pantalla. Las
   variantes escritas en línea sí lo llevaban; la clase, que es la que se usa en 20 de los
   toolbars, no. */
.tbl-toolbar__actions { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.tbl-count { color: var(--muted); font-size: .82rem; margin-left: .6rem; }

/* La rejilla de aplicaciones del panel de Módulos. Es la misma que ve el cliente al crear
   su empresa, a propósito: administrar lo que contrataste y contratarlo no deberían
   parecer dos sistemas distintos. */
/* El cajón de ayuda lleva display:flex en su atributo style, y eso le gana al atributo
   hidden: se quedaba abierto y vacío al cargar el panel. Con !important porque lo que
   hay que vencer es un estilo en línea. */
#ayudaCajon[hidden] { display: none !important; }

/* La marca de «hecho» de los primeros pasos. Vacía cuando falta: un círculo abierto se
   lee como una casilla por marcar sin tener que decirlo. */
.arr-mark { flex: none; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line-2);
            display: grid; place-items: center; font-size: .7rem; font-weight: 700; margin-top: .15rem; }
/* Doble clase: `.admin-row span` pintaba la palomita en gris sobre verde (1.2:1).
   --bg da blanco sobre verde oscuro y casi negro sobre el verde claro del tema oscuro. */
.arr-mark.arr-mark--ok { background: var(--ok-tinta); border-color: var(--ok-tinta); color: var(--bg); }

/* La ayuda dibujada: qué pulsar, en qué orden y dónde está. El botón se pinta con su
   texto exacto, así que quien lee compara con lo que tiene delante en vez de traducir. */
.ay-pasos { display: flex; flex-direction: column; gap: .1rem; margin-bottom: 1.2rem; }
.ay-paso { display: grid; grid-template-columns: 1.5rem 1fr; gap: .65rem; align-items: start;
           padding: .5rem 0; position: relative; }
/* El hilo que une un paso con el siguiente: es una secuencia, no una lista suelta. */
.ay-paso:not(:last-child)::after { content: ''; position: absolute; left: .72rem; top: 1.9rem;
                                   bottom: -.1rem; width: 1px; background: var(--line); }
.ay-n { width: 1.5rem; height: 1.5rem; border-radius: 50%; background: var(--realce);
        color: var(--ink-2); display: grid; place-items: center; font-size: .72rem;
        font-weight: 700; flex: none; position: relative; z-index: 1;
        font-size: .95rem; line-height: 1; }
.ay-boton { display: inline-block; border: 1px solid var(--line-2); border-radius: 999px;
            padding: .18rem .6rem; font-size: .82rem; font-weight: 600; background: var(--tarjeta); }
.ay-boton--pri { background: var(--red); color: #fff; border-color: var(--red); }
.ay-paso small { display: block; color: var(--muted); font-size: .78rem; margin-top: .25rem; line-height: 1.4; }

.ay-campos { margin-bottom: 1.2rem; }
.ay-campos b { display: block; font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
               color: var(--muted); margin-bottom: .4rem; }
.ay-campos > div { display: flex; flex-wrap: wrap; gap: .3rem; }
.ay-campo { border: 1px dashed var(--line-2); border-radius: 6px; padding: .12rem .45rem; font-size: .78rem; color: var(--ink-2); }

.ay-ojo { border-left: 3px solid var(--aviso-tinta); background: var(--aviso-fondo);
          border-radius: 0 8px 8px 0; padding: .7rem .9rem; }
.ay-ojo b { display: block; font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
            color: var(--aviso-tinta); margin-bottom: .25rem; }
.ay-ojo p { font-size: .86rem; line-height: 1.5; }

.mod-apps { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(min(250px,100%), 1fr)); }
.mod-fam h5 { font-size: .7rem; text-transform: uppercase; letter-spacing: .1em; font-weight: 700;
              padding-bottom: .35rem; margin-bottom: .5rem; border-bottom: 2px solid currentColor; }
.mod-app { padding: .3rem 0; }
.mod-app label { display: flex; gap: .55rem; align-items: flex-start; cursor: pointer; }
.mod-app input { margin-top: .3rem; flex: none; }
.mod-app b { font-weight: 600; font-size: .88rem; }
.mod-app small { display: block; color: var(--ink-2); font-size: .78rem; line-height: 1.35; }
.mod-app em { display: block; font-style: normal; font-size: .74rem; color: var(--muted); margin-top: .1rem; }
/* Lo que no existe todavía y lo que existe pero no cabe en el plan se ven distinto: uno
   no se puede comprar de ninguna manera, el otro se compra subiendo de paquete. */
.mod-app--pronto { opacity: .45; }
.mod-app--pronto label { cursor: default; }
.mod-app--fuera { opacity: .8; }
.mod-app--fuera label { cursor: default; }
.mod-app--fuera em { color: var(--red-tinta); }

/* La descripción de la pantalla llevaba 29 ritmos verticales distintos, todos escritos en
   el atributo style. Lleva !important porque eso es lo único que le gana a una declaración
   en línea, y el alcance es estrecho a propósito: sólo la nota que cuelga directamente de
   la sección o de su vista, es decir la que describe la pantalla. Las notas de dentro de
   un formulario o un panel se quedan como están. */
section[data-panel] > .form__note,
section[data-panel] > [data-vista] > .form__note { margin: -.4rem 0 1.2rem !important; }
.tbl-search { border: 1px solid var(--line); border-radius: 999px; padding: .5rem .95rem; font-size: .86rem; min-width: 220px; background: var(--tarjeta); color: var(--ink); }
.tbl-search:focus { outline: none; border-color: var(--red); }
.btn--sm { padding: .4rem .85rem; font-size: .82rem; }

/* El marco de una tabla DESPLAZA, no recorta.
 *
 * Tenía `overflow: hidden`, que con una tabla más ancha que la pantalla se come
 * las últimas columnas: no aparece barra, no hay manera de llegar a ellas, y
 * desde fuera parece que la tabla no tiene esos datos. En «Qué tiene cada
 * cliente» se comía el botón de «Entrar como dueño».
 *
 * Existía `.tabla-scroll` para esto y NADIE la usaba: once tablas metidas
 * directamente en el marco, cero con la clase. Una clase que hay que acordarse
 * de poner en cada tabla se olvida; el marco desplaza siempre y no hay nada que
 * recordar.
 *
 * `.piv-wrap` pone su propio `overflow: auto` para que su cabecera pegajosa
 * funcione, y como va después, gana. */
.tabla-wrap { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 14px; overflow-x: auto; box-shadow: 0 1px 2px rgba(0,0,0,.03); }
.tabla-scroll { overflow-x: auto; }
/* El ancho minimo va SOLO en las tablas que tienen quien las desplace.
 *
 * Sin el, en un telefono la tabla se encoge hasta que las columnas se aplastan y el
 * texto se parte letra por letra: se ve todo y no se lee nada. Con el, la tabla
 * conserva su ancho y el contenedor la desplaza de lado.
 *
 * Va acotado a `.tabla-scroll >` a proposito. Si se lo pusiera a toda `.tabla-odoo`,
 * las tablas que no van dentro de un contenedor -las anidadas en el detalle de una
 * fila- desbordarian la pagina entera de lado, que es justo el defecto que esto
 * viene a arreglar. */
.tabla-scroll > .tabla-odoo { min-width: 44rem; }
.tabla-odoo { width: 100%; border-collapse: collapse; font-size: .88rem; }
.tabla-odoo thead th { text-align: left; font-weight: 600; font-size: .74rem; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); background: var(--realce); padding: .7rem 1rem; border-bottom: 1px solid var(--line); white-space: nowrap; cursor: default; }
.tabla-odoo thead th.sortable { cursor: pointer; }
.tabla-odoo thead th.sortable:hover { color: var(--ink); }
.tabla-odoo thead th.r, .tabla-odoo td.r { text-align: right; }
.tabla-odoo th.col-check, .tabla-odoo td.col-check { width: 38px; padding-right: 0; text-align: center; }
.tabla-odoo tbody td { padding: .7rem 1rem; border-bottom: 1px solid var(--line); color: var(--ink); vertical-align: middle; }
.tabla-odoo tbody tr:last-child td { border-bottom: none; }
.tabla-odoo tbody tr { transition: background .12s; }
.tabla-odoo tbody tr:hover { background: var(--realce); }
.tabla-odoo tbody tr.sel { background: rgba(var(--red-rgb),.05); }
.tb-avatar { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; color: #fff; font-weight: 600; font-size: .8rem; flex: none; }
.tb-cell-avatar { display: flex; align-items: center; gap: .65rem; }
.tb-cell-avatar b { font-weight: 600; }
.tb-pill { display: inline-block; border-radius: 999px; padding: .15rem .6rem; font-size: .74rem; font-weight: 600; border: 1px solid transparent; }
.tb-pill--borrador { background: var(--neutro-fondo); color: var(--neutro-tinta); }
.tb-pill--enviada, .tb-pill--pendiente { background: var(--aviso-fondo); color: var(--aviso-tinta); }
.tb-pill--aceptada, .tb-pill--pagada, .tb-pill--activa { background: var(--ok-fondo); color: var(--ok-tinta); }
.tb-pill--rechazada, .tb-pill--cancelada, .tb-pill--vencida { background: var(--mal-fondo); color: var(--mal-tinta); }
.tb-pill--propio { background: var(--ok-fondo); color: var(--ok-tinta); }
.tb-pill--personalizado { background: var(--aviso-fondo); color: var(--aviso-tinta); }
.tb-actions { display: flex; gap: .5rem; justify-content: flex-end; white-space: nowrap; }
/* El icono de cada grupo del índice de ajustes: el mismo SVG del menú, a tamaño de
   texto. Sin medida, un SVG sin width se pinta enorme. */
.aj-ico { width: 1.05em; height: 1.05em; vertical-align: -.15em; }
.tb-link { background: none; border: none; color: var(--ink-2); font-size: .82rem; font-weight: 600; cursor: pointer; padding: .2rem .35rem; border-radius: 6px; text-decoration: none; }
.tb-link:hover { background: var(--realce); color: var(--ink); }
.tb-link--danger { color: var(--red-tinta); }
.tb-link--danger:hover { background: rgba(193,39,45,.08); }
.tb-empty { padding: 2.5rem 1.2rem; text-align: center; color: var(--muted); font-size: .88rem; }
/* Buscador de opciones (Ctrl+K) */
.cmdk-ov { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 9998; display: none; }
.cmdk-ov.on { display: block; }
.cmdk { position: fixed; z-index: 9999; top: 12vh; left: 50%; transform: translateX(-50%); width: min(620px, 94vw); background: var(--tarjeta); border: 1px solid var(--line); border-radius: 16px; box-shadow: 0 24px 60px rgba(0,0,0,.28); display: none; overflow: hidden; }
.cmdk.on { display: block; }
.cmdk-in { width: 100%; border: none; border-bottom: 1px solid var(--line); padding: 1.05rem 1.2rem; font-size: 1rem; background: transparent; color: var(--ink); outline: none; }
.cmdk-list { max-height: 52vh; overflow-y: auto; padding: .4rem; }
.cmdk-item { display: flex; align-items: center; gap: .7rem; padding: .6rem .8rem; border-radius: 10px; cursor: pointer; font-size: .92rem; color: var(--ink); }
.cmdk-item .g { margin-left: auto; font-size: .76rem; color: var(--muted); }
.cmdk-item.sel, .cmdk-item:hover { background: var(--realce); }
.cmdk-item .ic { width: 22px; text-align: center; }
.cmdk-empty { padding: 1.6rem; text-align: center; color: var(--muted); font-size: .9rem; }
.cmdk-foot { border-top: 1px solid var(--line); padding: .5rem .9rem; font-size: .76rem; color: var(--muted); display: flex; gap: 1rem; }
kbd { background: var(--realce); border: 1px solid var(--line); border-radius: 5px; padding: .05rem .35rem; font-size: .74rem; font-family: inherit; }

.pi-toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(20px); background: #1f9d61; color: #fff; padding: .7rem 1.2rem; border-radius: 999px; font-size: .88rem; font-weight: 600; box-shadow: 0 6px 20px rgba(0,0,0,.2); opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; z-index: 9999; }
.pi-toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Toggle de vistas (lista / kanban / mapa) */
/* .toggle-group/.toggle se usan en doce pantallas (10 grupos, 20 botones) y no tenían
   NINGUNA regla: se pintaban como botones crudos del navegador, gris y biselados, en medio
   de pantallas por lo demás terminadas. Se enganchan a .vista-toggle en vez de copiarle las
   reglas, para que sigan siendo un solo control y no dos que se van separando. */
/* `flex-wrap` y `white-space` no son cosmética aquí.
 *
 * Sin ellos el grupo no se parte NUNCA y el navegador, para que quepa, parte
 * las palabras: «Equipos de ventas» acababa en tres renglones de una palabra
 * cada uno dentro de una casilla de sesenta píxeles. Ahora se parte entre
 * botones, que es por donde tiene sentido partir. Con dos o tres opciones no
 * cambia nada, que es el caso de nueve de las diez pantallas que lo usan. */
.vista-toggle, .toggle-group { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--tarjeta); }
.vista-toggle button, .toggle-group button, .toggle-group .toggle { border: none; background: none; padding: .45rem .7rem; font-size: .82rem; font-weight: 600; color: var(--muted); cursor: pointer; display: flex; align-items: center; gap: .35rem; white-space: nowrap; border-right: 1px solid var(--line); }
.vista-toggle button:last-child, .toggle-group button:last-child, .toggle-group .toggle:last-child { border-right: none; }
.vista-toggle button.on, .toggle-group button.on, .toggle-group .toggle.on { background: var(--red); color: #fff; }

/* Muchas opciones: deja de ser un interruptor y pasa a ser una fila de pestañas.
 *
 * Un control segmentado dice «elige una de estas pocas», y con catorce casillas
 * encajonadas deja de decir eso: parece una rejilla de botones y hay que leerla
 * entera para encontrar la que se busca. Con el mismo aspecto que la segunda
 * fila del menú, el ojo ya sabe qué son sin pensarlo, y la que está puesta se
 * distingue por color en vez de por un bloque rojo que pesa más que el título. */
.toggle-group--tabs { border: none; border-radius: 0; background: none; gap: .2rem; }
.toggle-group--tabs button, .toggle-group--tabs .toggle { border-right: none; border-radius: 7px; padding: .34rem .62rem; font-size: .855rem; font-weight: 500; color: var(--ink-2); }
.toggle-group--tabs button:hover, .toggle-group--tabs .toggle:hover { background: rgba(0,0,0,.05); color: var(--ink); }
.toggle-group--tabs button.on, .toggle-group--tabs .toggle.on { background: var(--red-tint); color: var(--red-tinta); font-weight: 600; }
.toggle-group--tabs .n { background: var(--line-2); color: var(--ink); border-radius: 99px; padding: 0 .42rem; font-size: .7rem; font-weight: 600; }
.vista-toggle button:not(.on):hover, .toggle-group button:not(.on):hover, .toggle-group .toggle:not(.on):hover { background: var(--realce); color: var(--ink); }

/* Kanban */
.kb-board { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: .6rem; align-items: flex-start; }
.kb-col { flex: 0 0 260px; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; display: flex; flex-direction: column; max-height: 72vh; }
.kb-col.kb-over { border-color: var(--red); box-shadow: 0 0 0 2px rgba(var(--red-rgb),.15); }
.kb-col-h { display: flex; align-items: center; justify-content: space-between; padding: .7rem .9rem; font-weight: 600; font-size: .8rem; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-2); border-bottom: 1px solid var(--line); position: sticky; top: 0; }
.kb-n { background: var(--cream-2); color: var(--muted); border-radius: 999px; padding: .05rem .5rem; font-size: .74rem; }
.kb-col-body { padding: .7rem; display: flex; flex-direction: column; gap: .6rem; overflow-y: auto; min-height: 60px; }
.kb-card { background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: .7rem .8rem; cursor: grab; box-shadow: 0 1px 2px rgba(0,0,0,.04); transition: box-shadow .12s, transform .05s; }
:root[data-theme="dark"] .kb-card { background: var(--cream); }
.kb-card:hover { box-shadow: 0 3px 10px rgba(0,0,0,.08); }
.kb-card:active { cursor: grabbing; }
.kb-card.kb-drag { opacity: .5; }
.kb-card b { font-size: .9rem; display: block; }
.kb-card .kb-sub { color: var(--muted); font-size: .8rem; margin-top: .2rem; display: block; }
.kb-card .kb-total { font-weight: 700; color: var(--ink); margin-top: .35rem; display: block; }
.kb-empty { color: var(--muted); font-size: .8rem; text-align: center; padding: 1rem 0; }

/* Mapa */
.mapa-wrap { display: grid; grid-template-columns: 300px 1fr; gap: 1rem; align-items: stretch; }
@media (max-width: 780px){ .mapa-wrap { grid-template-columns: 1fr; } }
.mapa-lista { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 14px; max-height: 70vh; overflow-y: auto; }
.mapa-item { padding: .7rem .9rem; border-bottom: 1px solid var(--line); cursor: pointer; font-size: .86rem; }
.mapa-item:hover, .mapa-item.on { background: var(--realce); }
.mapa-item b { display: block; }
.mapa-item .m-dir { color: var(--muted); font-size: .8rem; }
.mapa-item .m-sin { color: var(--red-tinta); font-size: .76rem; }
#mapaLienzo, .mapa-canvas { height: 70vh; min-height: 420px; border-radius: 14px; border: 1px solid var(--line); overflow: hidden; z-index: 0; }

/* Punto de Venta */
.pos-layout { display: grid; grid-template-columns: 1fr 360px; gap: 1.2rem; align-items: start; }
@media (max-width: 900px){ .pos-layout { grid-template-columns: 1fr; } }
.pos-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: .7rem; }
.pos-prod { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 12px; padding: .8rem .7rem; text-align: left; cursor: pointer; display: flex; flex-direction: column; gap: .3rem; transition: box-shadow .12s, transform .04s; min-height: 84px; }
.pos-prod:hover { box-shadow: 0 4px 12px rgba(0,0,0,.08); }
.pos-prod:active { transform: scale(.98); }
.pos-prod .pn { font-weight: 600; font-size: .86rem; color: var(--ink); line-height: 1.2; }
.pos-prod .pp { font-weight: 800; color: var(--red-tinta); }
.pos-prod .ps { font-size: .72rem; color: var(--muted); }
.pos-prod.agotado { opacity: .5; }
.pos-ticket { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 16px; position: sticky; top: 58px; display: flex; flex-direction: column; max-height: calc(100vh - 74px); }
.pos-ticket-h { display: flex; justify-content: space-between; align-items: center; padding: .9rem 1.1rem; border-bottom: 1px solid var(--line); font-size: 1.05rem; }
.pos-lineas { flex: 1; overflow-y: auto; padding: .3rem 1.1rem; min-height: 80px; }
.pos-linea { display: flex; align-items: center; gap: .6rem; padding: .55rem 0; border-bottom: 1px solid var(--line); }
.pos-linea .l-n { flex: 1; font-size: .86rem; color: var(--ink); }
.pos-linea .l-n small { display: block; color: var(--muted); }
.pos-linea .l-imp { font-weight: 700; min-width: 62px; text-align: right; }
.pos-qty { display: flex; align-items: center; gap: .35rem; }
.pos-qty button { width: 24px; height: 24px; border: 1px solid var(--line); background: var(--realce); border-radius: 6px; cursor: pointer; font-weight: 700; color: var(--ink); }
.pos-foot { padding: .9rem 1.1rem 1.1rem; border-top: 1px solid var(--line); }
.pos-tot { display: flex; justify-content: space-between; font-size: .9rem; margin: .2rem 0; color: var(--ink-2); }
.pos-grand { font-size: 1.35rem; font-weight: 800; color: var(--ink); margin: .4rem 0 .7rem; }
.pos-metodos { display: flex; gap: .5rem; margin-bottom: .6rem; }
.pos-metodo { flex: 1; padding: .55rem; border: 1px solid var(--line); background: #fff; border-radius: 10px; font-weight: 600; cursor: pointer; color: var(--ink-2); }
:root[data-theme="dark"] .pos-metodo { background: var(--cream); }
.pos-metodo.on { background: var(--red); color: #fff; border-color: var(--red); }
/* La caja del turno: arriba del catálogo, siempre a la vista. */
.pos-caja { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .8rem 1.2rem; background: var(--tarjeta); border: 1px solid var(--line); border-radius: 14px; padding: .75rem 1rem; margin-bottom: 1rem; }
.pos-caja__estado { display: flex; align-items: center; gap: .7rem; font-size: .92rem; color: var(--ink); }
.pos-caja__punto { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--ok-tinta); box-shadow: 0 0 0 4px var(--ok-fondo); }
.pos-caja__punto.cerrada { background: var(--mal-tinta); box-shadow: 0 0 0 4px var(--mal-fondo); }
.pos-caja__acc { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; }
.pos-abrir { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem; }
.pos-abrir .field { margin: 0; min-width: 140px; }
.pos-corte { margin-bottom: 1rem; }
.pos-corte .kpi-grid { margin-top: .6rem; }
/* Sin caja abierta el catálogo se ve, pero no se toca. */
/* Libro diario: la cabecera de cada póliza y sus sumas, distinguibles de los renglones. */
.tbl.dia .dia-pol td { background: var(--surface); border-top: 1px solid var(--line); padding-top: .55rem; }
.tbl.dia .dia-sum td { color: var(--muted); font-style: italic; }
.tbl.dia tfoot .dia-sum td { color: var(--ink); font-style: normal; border-top: 2px solid var(--line); }
.tbl.dia .dia-cta { white-space: nowrap; font-variant-numeric: tabular-nums; }
.pos-bloqueado { opacity: .45; pointer-events: none; filter: grayscale(.25); }

/* =========================================================================
   v7 — FAQ + testimonios + valores
   ========================================================================= */
.faq { max-width: 780px; margin-inline: auto; display: grid; gap: .8rem; }
.faq details { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.faq summary { list-style: none; cursor: pointer; padding: 1.05rem 1.3rem; font-weight: 600; color: var(--ink); display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--red-tinta); font-size: 1.5rem; font-weight: 400; line-height: 1; transition: transform .2s; }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details > div { padding: 0 1.3rem 1.2rem; color: var(--ink-2); }

.testis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; margin-top: 2.5rem; }
.testi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 1.7rem; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; }
.testi__stars { color: var(--red-tinta); letter-spacing: 2px; margin-bottom: .7rem; }
.testi p { font-style: italic; color: var(--ink-2); flex: 1; }
.testi .who { margin-top: 1.1rem; font-weight: 700; font-size: .92rem; color: var(--ink); }
.testi .who span { display: block; color: var(--muted); font-weight: 500; font-size: .82rem; }
@media (max-width: 820px){ .testis { grid-template-columns: 1fr; } }

.values { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.3rem; margin-top: 2.5rem; }
.value { padding: 1.6rem; border-radius: var(--r); background: var(--cream); border: 1px solid var(--line); }
.value .card__icon { margin-bottom: .9rem; }
.value h3 { font-size: 1.12rem; }
.value p { margin-top: .4rem; color: var(--muted); font-size: .95rem; }
@media (max-width: 760px){ .values { grid-template-columns: 1fr; } }

/* Página de error / gracias */
.state-hero { text-align: center; max-width: 620px; margin-inline: auto; }
.state-hero .big { font-family: var(--font-display); font-weight: 600; font-size: clamp(4rem, 14vw, 8rem); color: var(--red-tinta); line-height: 1; }

/* =========================================================================
   v8 — Accesibilidad + botones flotantes + cookies + sectores
   ========================================================================= */
.skip-link { position: absolute; left: -999px; top: 0; z-index: 200; background: var(--red); color: #fff; padding: .7rem 1.2rem; border-radius: 0 0 10px 0; font-weight: 600; }
.skip-link:focus { left: 0; }
:focus-visible { outline: 3px solid rgba(var(--red-rgb),.55); outline-offset: 2px; border-radius: 5px; }

/* Botones flotantes (WhatsApp + subir) */
.fabs { position: fixed; left: 18px; bottom: 18px; z-index: 70; display: flex; flex-direction: column-reverse; gap: .6rem; }
body.cookie-open .fabs { display: none; }
.fab-btn { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; box-shadow: var(--shadow); border: none; cursor: pointer; transition: transform .18s ease; }
.fab-btn:hover { transform: translateY(-3px); }
.fab-wa { background: #25D366; color: #fff; }
.fab-wa svg { width: 28px; height: 28px; }
.fab-top { background: var(--surface); color: var(--ink); border: 1px solid var(--line); opacity: 0; visibility: hidden; transform: translateY(10px); }
.fab-top.show { opacity: 1; visibility: visible; transform: none; }
.fab-top:hover { background: var(--ink); color: #fff; }

/* Banner de cookies */
.cookie { position: fixed; left: 50%; transform: translateX(-50%); bottom: 18px; z-index: 85; width: min(560px, calc(100vw - 36px)); background: var(--surface); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow-lg); padding: 1.1rem 1.3rem; display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; }
.cookie[hidden] { display: none; }
.cookie p { font-size: .86rem; color: var(--ink-2); flex: 1 1 220px; margin: 0; }
.cookie a { color: var(--red-tinta); text-decoration: underline; }
.cookie__btns { display: flex; gap: .5rem; }
.cookie .btn { padding: .55rem 1rem; font-size: .86rem; box-shadow: none; }

/* Sectores que atendemos */
.sectors { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; margin-top: 2.6rem; }
.sector { display: flex; gap: .9rem; align-items: center; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 1.1rem 1.3rem; transition: border-color .2s, transform .2s; }
.sector:hover { border-color: var(--line-2); transform: translateY(-3px); }
.sector .ic { width: 46px; height: 46px; border-radius: 12px; background: var(--red-tint); color: var(--red-tinta); display: grid; place-items: center; flex: none; }
.sector .ic svg { width: 24px; height: 24px; }
.sector b { font-weight: 600; font-size: 1rem; }
.sector span { display: block; color: var(--muted); font-size: .85rem; margin-top: 1px; }
@media (max-width: 760px){ .sectors { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px){ .sectors { grid-template-columns: 1fr; } }

/* Interruptor de tema */
.theme-toggle { width: 42px; height: 42px; border-radius: 10px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); display: grid; place-items: center; cursor: pointer; transition: color .18s, border-color .18s; flex: none; }
.theme-toggle:hover { color: var(--red-tinta); border-color: var(--line-2); }
.theme-toggle svg { width: 20px; height: 20px; }
.theme-toggle .i-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .i-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .i-sun { display: block; }

/* =========================================================================
   v9 — Newsletter + filtro de blog + mapa
   ========================================================================= */
.newsletter { background: var(--ink-band); color: #F3ECE3; }
.newsletter .container { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; padding-block: clamp(2rem, 4vw, 2.8rem); }
.newsletter h3 { color: #fff; font-size: clamp(1.3rem, 2.5vw, 1.7rem); }
.newsletter p { color: #C9BEB2; margin-top: .3rem; font-size: .95rem; }
.newsletter form { display: flex; gap: .6rem; flex: 1 1 340px; max-width: 470px; }
.newsletter input { flex: 1; padding: .8rem 1rem; border-radius: 10px; border: 1px solid rgba(255,255,255,.2); background: rgba(255,255,255,.08); color: #fff; font: inherit; }
.newsletter input::placeholder { color: #B6ABA0; }
.newsletter input:focus { outline: none; border-color: #E8A0A3; }
.newsletter .btn { white-space: nowrap; }
.newsletter__ok { color: #7bdcab; font-weight: 600; font-size: .92rem; }
@media (max-width: 560px){ .newsletter form { flex-direction: column; } }

.filters { display: flex; gap: .5rem; flex-wrap: wrap; justify-content: center; margin-top: 2rem; }
.filter-chip { padding: .5rem 1.1rem; border-radius: 999px; border: 1px solid var(--line-2); background: var(--surface); font-weight: 600; font-size: .9rem; color: var(--ink-2); cursor: pointer; transition: .15s; }
.filter-chip:hover { border-color: var(--red); color: var(--red-tinta); }
.filter-chip.on { background: var(--red); color: #fff; border-color: var(--red); }
.post-card.hide { display: none; }

.map-embed { display: block; width: 100%; height: 300px; border: 1px solid var(--line); border-radius: var(--r); margin-top: 1.2rem; filter: saturate(.9); }
:root[data-theme="dark"] .map-embed { filter: invert(.92) hue-rotate(180deg) saturate(.8); }

/* =========================================================================
   v10 — ERP: Cotizaciones (editor en panel + documento del cliente)
   ========================================================================= */
/* Editor de conceptos en /admin */
.qitems { width: 100%; border-collapse: collapse; margin-top: .5rem; }
.qitems th { text-align: left; font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: .3rem .35rem; }
.qitems th.num, .qitems td.num { text-align: right; }
.qitems td { padding: .2rem .25rem; vertical-align: middle; }
.qitems input { width: 100%; padding: .5rem; border: 1px solid var(--line-2); border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit; font-size: .9rem; }
/* Colegiatura (IEDU) plegada bajo la descripción del concepto. */
.pi-iedu { margin-top: .25rem; }
.pi-iedu[open] { display: grid; gap: .3rem; }
.pi-iedu .ie-alumno, .pi-iedu .ie-curp, .pi-iedu .ie-rvoe, .pi-iedu .ie-rfc { font-size: .85rem; padding: .35rem .5rem; }
.pi-iedu .ie-curp, .pi-iedu .ie-rfc { text-transform: uppercase; }
.pi-iedu .ie-nivel { width: 100%; padding: .35rem .5rem; border: 1px solid var(--line-2); border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit; font-size: .85rem; }
.qitems input.num { text-align: right; }
/* Casillas dentro de una tabla del panel (precios del SaaS): mismo aspecto que un campo,
 * en claro y en oscuro, y a la derecha como la cifra que son. */
.tabla-odoo td input[type="number"] { width: 100%; min-width: 4.5rem; padding: .4rem .5rem; border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); color: var(--ink); font: inherit; font-size: .9rem; text-align: right; font-variant-numeric: tabular-nums; }
.tabla-odoo td input[type="number"]:focus { outline: none; border-color: var(--red); box-shadow: 0 0 0 3px var(--red-tint); }
.qitems .imp { font-weight: 600; white-space: nowrap; padding: .5rem .35rem; text-align: right; }
.qitems .rm { background: none; border: none; color: var(--red-tinta); cursor: pointer; font-size: 1.1rem; line-height: 1; }
/* Conceptos de la cotización con su columna de descuento (287): en el teléfono, cada concepto
 * es una tarjeta: la descripción arriba y cantidad, precio, descuento e importe debajo. */
@media (max-width: 640px) {
  .qitems--cot thead { display: none; }
  .qitems--cot tr { display: grid; grid-template-columns: 3.6rem 1fr 1.5fr 2rem; gap: .35rem; padding: .5rem 0; border-bottom: 1px solid var(--line); }
  .qitems--cot td { padding: 0; }
  .qitems--cot td:nth-child(1) { grid-column: 1 / -1; }
  .qitems--cot td:nth-child(5) { grid-column: 1 / 4; grid-row: 3; text-align: right; padding: .2rem 0; }
  .qitems--cot td:nth-child(6) { grid-column: 4; grid-row: 2; align-self: end; }
  .qitems--cot td[data-l]::before { content: attr(data-l); display: block; font-size: .68rem; color: var(--muted); margin-bottom: .1rem; text-align: left; }
}
.qtotals { margin: 1rem 0 0 auto; max-width: 260px; }
.qtotals div { display: flex; justify-content: space-between; padding: .25rem 0; color: var(--ink-2); }
.qtotals .grand { border-top: 1px solid var(--line); margin-top: .3rem; padding-top: .5rem; font-family: var(--font-display); font-size: 1.3rem; color: var(--ink); }
.copy-link { display: flex; gap: .5rem; margin-top: .8rem; }
.copy-link input { flex: 1; padding: .5rem .7rem; border: 1px solid var(--line-2); border-radius: 8px; background: var(--cream); color: var(--ink-2); font-size: .82rem; }

/* Documento de cotización (vista del cliente) */
.quote-doc { max-width: 820px; margin: 0 auto; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); overflow: hidden; }
.quote-doc__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; padding: clamp(1.5rem,4vw,2.2rem); border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.quote-doc__brand { display: flex; align-items: center; gap: .6rem; }
.quote-doc__brand .brand__pi { font-size: 2rem; }
.quote-doc__meta { text-align: right; }
.quote-doc__meta .folio { font-family: var(--font-display); font-weight: 600; font-size: 1.5rem; color: var(--red-tinta); }
.quote-doc__meta small { color: var(--muted); font-size: .85rem; display: block; }
.quote-doc__body { padding: clamp(1.5rem,4vw,2.2rem); }
.quote-doc__to { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.quote-doc__to h4 { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: .3rem; }
.quote-table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; }
.quote-table th { text-align: left; font-size: .74rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); border-bottom: 2px solid var(--line); padding: .6rem .4rem; }
.quote-table td { padding: .7rem .4rem; border-bottom: 1px solid var(--line); color: var(--ink-2); }
.quote-table .num { text-align: right; white-space: nowrap; }
.quote-doc__totals { margin-left: auto; max-width: 300px; }
.quote-doc__totals div { display: flex; justify-content: space-between; padding: .3rem 0; color: var(--ink-2); }
.quote-doc__totals .grand { border-top: 2px solid var(--line); margin-top: .4rem; padding-top: .6rem; font-family: var(--font-display); font-size: 1.5rem; color: var(--ink); }
.quote-actions { display: flex; gap: .6rem; padding: 1.4rem clamp(1.5rem,4vw,2.2rem); background: var(--cream); flex-wrap: wrap; align-items: center; }
/* Carta de aceptación y constancia (vista del cliente, ver cotizacion-view.js) */
.carta-acept { padding: clamp(1.5rem,4vw,2.2rem); border-top: 1px solid var(--line); min-width: 0; }
.carta-acept h2 { font-family: var(--font-display); font-size: 1.4rem; margin-bottom: .4rem; }
.carta-acept h2:focus { outline: none; }
.carta-acept h2:focus-visible { outline: 2px solid var(--red); outline-offset: 4px; }
.carta-acept__ayuda { color: var(--muted); font-size: .92rem; margin-bottom: 1rem; }
.carta-acept__texto { max-height: 26rem; overflow-y: auto; padding: 1.1rem 1.2rem; border: 1px solid var(--line-2); border-radius: var(--r-sm); background: var(--cream); color: var(--ink-2); font-size: .92rem; line-height: 1.6; overflow-wrap: anywhere; }
.carta-acept__texto:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.carta-acept__texto--todo { max-height: none; overflow: visible; }
.carta-acept__texto p { margin: 0 0 .75rem; }
.carta-acept__titulo { font-family: var(--font-display); font-size: 1.1rem; color: var(--ink); margin-bottom: .8rem; }
.carta-acept__form { margin-top: 1.1rem; }
.carta-acept__check { display: flex; gap: .55rem; align-items: flex-start; font-weight: 600; color: var(--ink); margin-bottom: .8rem; cursor: pointer; }
.carta-acept__check input { width: 1.15rem; height: 1.15rem; margin-top: .15rem; flex: none; accent-color: var(--red); }
.carta-acept__botones { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: .8rem; }
.carta-acept__firma { display: grid; grid-template-columns: minmax(0,10rem) minmax(0,1fr); gap: .35rem 1rem; margin-top: 1.1rem; font-size: .92rem; }
.carta-acept__firma dt { color: var(--muted); }
.carta-acept__firma dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
.carta-acept__firma code { font-size: .82rem; word-break: break-all; }
.carta-acept--comentar { background: var(--cream); }
.carta-acept--constancia { background: var(--surface); }
@media (max-width: 560px) { .carta-acept__firma { grid-template-columns: 1fr; } .carta-acept__firma dd { margin-bottom: .4rem; } .carta-acept__botones .btn { flex: 1 1 100%; justify-content: center; } }
@media print { .carta-acept--comentar, .carta-acept__botones, #cartaBox { display: none !important; } .carta-acept__texto { max-height: none; overflow: visible; border: 0; background: none; } body.imprime-constancia .quote-doc > :not(#constancia) { display: none !important; } }
.status-badge { display: inline-block; padding: .3rem .8rem; border-radius: 999px; font-size: .78rem; font-weight: 700; }
.status-borrador { background: var(--neutro-fondo); color: var(--neutro-tinta); }
.status-enviada { background: var(--info-fondo); color: var(--info-tinta); }
.status-aceptada { background: var(--ok-fondo); color: var(--ok-tinta); }
.status-rechazada { background: var(--mal-fondo); color: var(--mal-tinta); }
.status-nuevo { background: var(--info-fondo); color: var(--info-tinta); }
.status-pagado, .status-entregado { background: var(--ok-fondo); color: var(--ok-tinta); }
.status-en_proceso { background: var(--aviso-fondo); color: var(--aviso-tinta); }
.status-cancelado { background: var(--mal-fondo); color: var(--mal-tinta); }
.status-convertida { background: var(--neutro-fondo); color: var(--neutro-tinta); }
.status-pendiente { background: var(--aviso-fondo); color: var(--aviso-tinta); }
.status-pagada { background: var(--ok-fondo); color: var(--ok-tinta); }
.status-cancelada { background: var(--mal-fondo); color: var(--mal-tinta); }
/* Auditoría fiscal: el semáforo por obligación (Impuestos → Auditoría). */
.aud-semaforo { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: .6rem; padding: .6rem 1.15rem 1rem; }
.aud-luz { display: flex; gap: .6rem; align-items: center; padding: .6rem .75rem; border: 1px solid var(--line); border-radius: 10px; }
.aud-punto { width: .9rem; height: .9rem; border-radius: 50%; flex: none; background: var(--line); }
.aud-luz--verde .aud-punto { background: var(--ok-tinta); }
.aud-luz--amarillo .aud-punto { background: var(--aviso-tinta); }
.aud-luz--rojo .aud-punto { background: var(--mal-tinta); }
.aud-luz--rojo { background: var(--mal-fondo); }
.aud-luz--por_venir { opacity: .55; }
.aud-luz--no_aplica { opacity: .6; }
.aud-luz--no_aplica .aud-punto { background: var(--muted); }
.pedido-estado { padding: .35rem .6rem; border: 1px solid var(--line-2); border-radius: 8px; background: var(--surface); color: var(--ink); font: inherit; font-size: .85rem; }

/* Portal de clientes */
.portal-login { max-width: 410px; margin: 2vh auto; }
.portal-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.8rem; }
.portal-head h1 { font-size: clamp(1.6rem, 3vw, 2.2rem); }
.portal-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; }
@media (max-width: 760px){ .portal-cards { grid-template-columns: 1fr; } }
.mini-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: .75rem 0; border-bottom: 1px solid var(--line); font-size: .92rem; }
.mini-row:last-child { border-bottom: none; }
.mini-row a { color: var(--red-tinta); font-weight: 600; }

/* =========================================================================
   v12 — Panel con barra lateral (ERP interno) + dashboard
   ========================================================================= */
.topbar__portal { font-weight: 600; }

/* ===================== El menú: dos filas de pestañas =====================
 *
 * Era una barra lateral con acordeón: los trece módulos apilados, y el abierto
 * desplegando sus pantallas debajo. Funcionaba, pero para ver en qué módulo
 * estabas había que mirar cuál estaba desplegado, y para cambiar de módulo
 * había que buscarlo en una columna de trece encabezados que a media pantalla
 * ya no cabía entera.
 *
 * Ahora son dos renglones fijos arriba: MÓDULOS y, debajo, las PANTALLAS del
 * módulo en el que estás. Es la forma en que están hechos los programas con los
 * que ya trabaja quien va a usar esto, y tiene una ventaja que la columna no
 * podía dar: los trece módulos se ven de un vistazo, sin desplegar nada.
 *
 * Los dos renglones van dentro de UN contenedor fijo. Fijándolos por separado
 * habría que decirle al segundo a qué altura empieza, y ese número se rompe el
 * día que una etiqueta ocupe dos renglones o que el primero se parta en dos.
 */
.admin-body { display: block; min-height: calc(100vh - 58px); }
.admin-nav { position: sticky; top: 58px; z-index: 31; background: var(--surface); box-shadow: 0 1px 0 var(--line); }

/* ===================== El menú en COLUMNA =====================
 *
 * Es el MISMO DOM que el de arriba: las mismas pestañas de módulo y los mismos
 * botones de pantalla, colocados de otra manera. Dos maquetados del mismo HTML
 * y no dos menús: un segundo menú se queda atrás en cuanto alguien añada una
 * pantalla y la ponga en uno solo.
 *
 * Doce pestañas de módulo una debajo de otra no caben, así que en columna el
 * módulo se cambia con un botón que abre el lanzador —el que ya existía— y
 * debajo van sólo las pantallas del módulo abierto. Es lo que gana el aire:
 * arriba no queda nada, y el contenido empieza en la primera línea.
 */
/* El botón que cambia la forma del menú.
 *
 * Vive en la barra oscura de arriba, que es la más disputada del panel: nombre de
 * la cuenta, empresa, buscador, ayuda y salir. Añadirle ciento once píxeles la
 * desbordó y la insignia de la empresa se montó sobre el buscador.
 *
 * Debajo de 900px se esconde, y no por sitio: es que ahí NO HACE NADA. La columna
 * vuelve a pestañas por debajo de ese ancho (ver el media query de más abajo), así
 * que el botón ofrecería un cambio que no se ve. Un control que no cambia nada es
 * peor que ninguno. */
.menumodo { display: inline-flex; align-items: center; gap: .38rem; flex: none;
  height: 32px; padding: 0 .72rem; border-radius: 999px; white-space: nowrap;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.2);
  color: #fff; font: inherit; font-size: .78rem; font-weight: 600; cursor: pointer; }
.menumodo:hover { background: rgba(255,255,255,.2); }
.menumodo svg { width: 14px; height: 14px; flex: none; }
@media (max-width: 900px) { .menumodo { display: none; } }


.selmod { display: none; width: 100%; align-items: center; gap: .55rem; text-align: left;
  background: var(--tarjeta); border: 1px solid var(--line); border-radius: 11px;
  padding: .5rem .6rem; margin-bottom: .8rem; box-shadow: var(--shadow-sm);
  font: inherit; color: var(--ink); cursor: pointer; }
.selmod:hover { border-color: var(--line-2); }
.selmod__ic { width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center;
  color: #fff; background: var(--red); flex: none; }
.selmod__ic svg { width: 16px; height: 16px; }
.selmod b { font-size: .87rem; flex: 1; line-height: 1.15; font-weight: 600; }
.selmod__ch { color: var(--muted-2); font-size: .7rem; }

/* `minmax(0, 1fr)` y no `1fr`: una columna `1fr` no baja del ancho mínimo de lo que
 * lleva dentro, así que una tabla ancha estiraba la página entera a lo ancho (y
 * `scrollIntoView` la movía de lado, barra de arriba incluida). Con el mínimo en cero la
 * tabla se desplaza dentro de su propia caja, que es donde ya tiene su barra. */
[data-menu="columna"] #adminApp { display: grid; grid-template-columns: 232px minmax(0, 1fr); align-items: start; }
.admin-body { min-width: 0; }
[data-menu="columna"] .admin-nav { position: sticky; top: 58px; max-height: calc(100vh - 58px);
  overflow: auto; background: var(--cream-2); border-right: 1px solid var(--line);
  box-shadow: none; padding: .8rem .6rem; }
[data-menu="columna"] .modtabs { display: none; }
[data-menu="columna"] .selmod { display: flex; }
/* EL MENÚ SE VE SIEMPRE. NO SE OCULTA PARA NADA.
 * ===================================================================================
 *
 * Aquí hubo dos intentos de esconderlo hasta que estuviera recortado, para que no se
 * vieran un instante las 127 pantallas antes de quedarse en las de la cuenta. Los dos
 * dejaron a alguien con el panel abierto y sin una sola forma de navegar: el primero
 * porque un error en otra parte del archivo impedía llegar a la línea que lo destapaba;
 * el segundo porque la animación que iba a destaparlo no corre en un elemento que todavía
 * está oculto, así que se quedaba en el primer fotograma para siempre.
 *
 * Dos formas distintas de fallar, el mismo resultado, y ninguna de las dos la habría
 * encontrado yo: me las reportó él, las dos veces, después de quedarse tirado.
 *
 * La lección no es «prueba mejor el tercer intento». Es que la cuenta no salía desde el
 * principio: el problema que se arreglaba era feo —un parpadeo— y el que se creaba era
 * grave —un panel inservible—. Cuando el arreglo puede fallar más caro que el defecto,
 * el arreglo no es el camino.
 *
 * Si algún día molesta de verdad, se quita donde de verdad está: que el servidor mande la
 * barra ya recortada, y entonces no hay nada que esconder porque nunca se pinta de más.
 * Eso es más trabajo y no puede dejar a nadie encerrado.
 */

[data-menu="columna"] .admin-side { display: block; background: none; padding: 0; }
[data-menu="columna"] .admin-side .group { display: contents; }
/* El rótulo del grupo vuelve a verse: en columna sí cabe, y es lo que separa
 * «vender» de «cobrar» sin tener que leer los nombres. */
[data-menu="columna"] .admin-side .group.abierto h6 { display: block; font-size: .65rem;
  font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--muted-2);
  padding: .65rem .6rem .28rem; margin: 0; cursor: default; }
[data-menu="columna"] .admin-side .group.abierto h6::after { display: none; }
[data-menu="columna"] .admin-nav-item { width: 100%; padding: .44rem .6rem; border-radius: 9px;
  font-size: .855rem; white-space: normal; }
[data-menu="columna"] .admin-nav-item.on { background: var(--tarjeta); box-shadow: var(--shadow-sm); }
[data-menu="columna"] .admin-nav-item .n { margin-left: auto; }
[data-menu="columna"] .admin-side__pie { margin: .6rem 0 0; padding-top: .6rem;
  border-top: 1px solid var(--line); }
[data-menu="columna"] .admin-main { max-width: 1240px; }
/* En pantalla chica la columna estorba: se vuelve a las pestañas pase lo que
 * pase, que es justo la razón por la que las dos maquetaciones son el mismo DOM. */
@media (max-width: 900px) {
  [data-menu="columna"] #adminApp { display: block; }
  [data-menu="columna"] .admin-nav { position: sticky; top: 0; max-height: none;
    border-right: none; background: var(--surface); padding: 0; }
  [data-menu="columna"] .modtabs { display: flex; }
  [data-menu="columna"] .selmod { display: none; }
  [data-menu="columna"] .admin-side { display: flex; }
  [data-menu="columna"] .admin-side .group.abierto h6 { display: none; }
}

/* Fila 1: los módulos. */
.modtabs { display: flex; gap: .1rem; align-items: stretch; padding: 0 clamp(.5rem, 2vw, 1.2rem); overflow-x: auto; scrollbar-width: thin; border-bottom: 1px solid var(--line); }
.modtabs button { display: flex; align-items: center; gap: .45rem; flex: none; border: none; background: none; font: inherit; font-size: .855rem; font-weight: 600; color: var(--muted-2); cursor: pointer; white-space: nowrap; padding: .62rem .7rem; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.modtabs button:hover { color: var(--ink); background: rgba(0,0,0,.028); }
.modtabs button.on { color: var(--red-tinta); border-bottom-color: var(--red); }
/* El punto de color es el mismo de la tarjeta del lanzador: quien ya asoció
 * «Ventas» con el azul lo reconoce aquí sin leer. */
/* El icono de la pestaña lleva el color de su módulo mientras está en reposo —el
 * trabajo que hacía el punto— y lo suelta al activarse, para que la pestaña
 * abierta sea de un solo color: rojo el texto, rojo la línea de abajo, rojo el
 * icono. Un icono azul dentro de una pestaña roja se lee como un descuido. */
.modtabs button svg { width: 15px; height: 15px; flex: none; color: var(--mod, currentColor); opacity: .82; }
.modtabs button:hover svg { opacity: 1; }
.modtabs button.on svg { color: currentColor; opacity: 1; }

/* Fila 2: las pantallas del módulo abierto.
 *
 * `display: contents` en el grupo para que sus botones sean hijos directos de
 * la fila: si el grupo siguiera siendo una caja, cada módulo sería un bloque y
 * los botones no podrían repartirse por los renglones disponibles. Los grupos
 * que no son el activo siguen escondidos por la regla del acordeón. */
.admin-side { display: flex; flex-wrap: wrap; gap: .2rem; padding: .42rem clamp(.5rem, 2vw, 1.2rem); background: var(--cream); }
.admin-side .group { display: contents; }
.admin-side .group h6 { display: none; }
.admin-side .group.collapsed .admin-nav-item { display: none; }
/* Mientras el panel no sabe qué módulo abrir, no se enseñan los botones de
 * pantalla. Sólo ésos: la fila sigue ahí con «Ajustes», así que conserva su
 * altura y cuando aparecen los del módulo no se mueve nada de sitio. Esconder
 * la fila entera arreglaría el parpadeo cambiándolo por un salto, que es el
 * mismo defecto con otra cara. */
[data-nav="cargando"] .admin-side .group .admin-nav-item { visibility: hidden; }
[data-nav="cargando"] .modtabs button { visibility: hidden; }
.admin-side .group[hidden] { display: none !important; }
/* Ajustes no pertenece a ningún módulo: se va al extremo derecho del renglón. */
.admin-side__pie { margin-left: auto; }
.admin-nav-item { display: inline-flex; align-items: center; gap: .42rem; width: auto; text-align: left; padding: .34rem .62rem; border-radius: 7px; border: none; background: none; color: var(--ink-2); font: inherit; font-size: .855rem; font-weight: 500; cursor: pointer; white-space: nowrap; }
.admin-nav-item:hover { background: rgba(0,0,0,.05); color: var(--ink); }
.admin-nav-item.on { background: var(--red-tint); color: var(--red-tinta); font-weight: 600; }
.admin-nav-item svg { width: 15px; height: 15px; flex: none; }
.admin-nav-item .n { background: var(--line-2); color: var(--ink); border-radius: 99px; padding: 0 .42rem; font-size: .7rem; font-weight: 600; }
/* ===================== El ancho del panel =====================
 *
 * ÉSTA ES LA CAUSA DE «se ve desacomodado», y no era lo que parecía.
 *
 * `.admin-main` no tenía ancho máximo. En un monitor de 1920px la columna de contenido
 * quedaba de ~1600px, y ahí todo lo que no fuera una tabla se veía huérfano: una tarjeta
 * de 380px pegada a la izquierda con mil doscientos píxeles de vacío al lado.
 *
 * El síntoma que se reportó -la tarjeta sola de Integraciones- se culpaba al `auto-fill`
 * de su retícula. Pero `auto-fill` está puesto a propósito (ver el comentario en
 * `.integr-grid`): sirve para que una tarjeta sola conserve su ancho en vez de estirarse
 * ridículamente a todo lo largo. Cambiarlo habría cambiado un defecto por otro.
 *
 * Con un ancho máximo razonable, `auto-fill` da dos o tres columnas en vez de cinco, y
 * una tarjeta sola se ve deliberada en lugar de perdida.
 *
 * POR QUÉ 1440 Y NO LOS 1160 DEL SITIO PÚBLICO
 * El sitio público es para leer: 1160px da renglones cómodos. El panel es para trabajar,
 * y sus tablas de contabilidad tienen ocho o diez columnas. Estrangularlas a 1160 las
 * obligaría a desplazarse a lo ancho en pantallas donde había sitio de sobra.
 */
.admin-main {
  padding: clamp(1.2rem, 3vw, 2.2rem);
  max-width: 1440px;
  margin-inline: auto;
  width: 100%;
  /* `clip` y no `hidden`. Los dos recortan igual, pero `hidden` convierte al elemento en
   * contenedor de desplazamiento, y eso desactiva TODOS los `position:sticky` de dentro
   * — la paleta del constructor de páginas, el índice de Ajustes, el ticket del punto de
   * venta y la vista en vivo dejaban de seguir al desplazarse por esta línea. */
  overflow-x: clip;
}

/* El texto explicativo no puede ir a todo lo ancho.
 *
 * Hay 102 párrafos de ayuda en el panel. A 1440px son renglones de 150 caracteres, y a
 * partir de unos 75 el ojo pierde el renglón al volver a la izquierda: se relee la misma
 * línea o se salta una. Es la razón por la que los periódicos tienen columnas.
 *
 * Es un TOPE: donde el contenedor ya es angosto no hace nada. */
.admin-main > .form__note,
.admin-main > p.form__note,
section[data-panel] > .form__note,
section[data-panel] > p { max-width: 72ch; }

/* El tamaño lo pone la regla común de encabezados de pantalla (busca «Una sola forma de
   empezar una pantalla»). Aquí no se repite: estaba más abajo en el archivo y, a igual
   especificidad, ganaba la última — así que en pantalla chica este título se quedaba en
   24px mientras los del toolbar bajaban a 20. */
.panel-title { font-family: var(--font-sans); font-weight: 700; margin-bottom: 1.2rem; }

/* ===================== Gráfica del tablero =====================
 * Los colores de serie se comprobaron con el validador de paletas: en claro
 * #C1272D / #1F6FB2 y en oscuro #CE3138 / #4A8FD4 pasan las cinco comprobaciones,
 * con separación para daltonismo muy por encima del mínimo. Aun así, cada serie
 * lleva su etiqueta pegada al último punto: la identidad no depende sólo del color. */
:root { --serie-facturado: #C1272D; --serie-cobrado: #1F6FB2; }
[data-theme="dark"], .dark { --serie-facturado: #CE3138; --serie-cobrado: #4A8FD4; }

.omni-cab { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: .2rem; }
.omni-sub { color: var(--muted); font-size: .8rem; margin: .25rem 0 0; line-height: 1.4; max-width: 46ch; }

.omni-plot { position: relative; flex: 1; min-height: 220px; }
.omni-plot #omniChart { position: absolute; inset: 0; }

/* El globo de consulta: sigue al ratón sin tapar la línea que estás mirando. */
.omni-tip {
  position: absolute; top: 4px; transform: translateX(-50%); pointer-events: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: .5rem .65rem; box-shadow: 0 6px 20px rgba(0,0,0,.12);
  font-size: .8rem; display: flex; flex-direction: column; gap: .2rem; white-space: nowrap; z-index: 3;
}
.omni-tip b { color: var(--ink); }
.omni-tip span { display: flex; align-items: center; gap: .4rem; color: var(--ink-2); }
.omni-tip i { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.omni-tip .omni-tip-dif { color: var(--muted); font-size: .74rem; margin-top: .15rem; }

/* La leyenda dice también QUÉ mide cada serie: «cobrado» no significa lo mismo
 * para todo el mundo, y adivinarlo es de donde salen los malentendidos. */
.omni-legend em { color: var(--muted); font-style: normal; font-size: .74rem; }
.omni-legend span { display: inline-flex; align-items: center; gap: .35rem; }

.omni-tabla { margin-top: .9rem; overflow-x: auto; }

@media (max-width: 560px) {
  .omni-cab { flex-direction: column; }
  .omni-legend em { display: none; }
}

/* ===================== Indicadores (mosaicos con tendencia) =====================
 * Un número solo no es un indicador: es un dato suelto. Cada mosaico lleva su valor,
 * cuánto cambió contra el periodo anterior y la forma de las últimas 12 semanas.
 *
 * Los colores de estado se validaron con el comprobador de paletas: en claro
 * #147D52 / #C1272D y en oscuro #147D52 / #CE3138 pasan banda de luminosidad, croma,
 * separación para daltonismo y contraste contra su superficie. El verde y el rojo
 * NUNCA van solos: siempre con su flecha ▲▼ y el texto del periodo, porque bajo
 * deuteranopía ese par queda en el límite. */
:root { --kpi-bien: #147D52; --kpi-mal: #C1272D; --kpi-linea: #B9AEA2; }
[data-theme="dark"], .dark { --kpi-bien: #147D52; --kpi-mal: #CE3138; --kpi-linea: #6E635A; }

/* grid-auto-rows: 1fr iguala TODAS las filas, no solo las tarjetas dentro de una:
 * al envolverse a un segundo renglon, una tarjeta suelta mas alta se ve como un error. */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); grid-auto-rows: 1fr; align-items: stretch; gap: .85rem; }
.kpi-grid--dinero { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); margin-bottom: 1.4rem; }

.kpi-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: .95rem 1rem .8rem; display: flex; flex-direction: column; gap: .35rem;
  /* La cifra y su cambio arriba; la tendencia siempre pegada abajo, aunque el texto
   * de en medio sea mas corto en unas tarjetas que en otras. */
  justify-content: flex-start;
  position: relative; text-align: left; width: 100%; font: inherit; color: inherit;
  cursor: pointer; transition: border-color .15s, transform .15s, box-shadow .15s;
}
.kpi-card:hover { border-color: var(--muted); transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0,0,0,.06); }
.kpi-card:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

/* La etiqueta va ARRIBA: se lee primero qué es, después cuánto. */
.kpi-card .kpi-lbl { color: var(--muted); font-size: .78rem; letter-spacing: .02em; text-transform: uppercase; margin: 0; }
/* Cifras proporcionales: a este tamaño, tabular-nums deja los números sueltos. */
.kpi-card .kpi-num { font-family: var(--font-display); font-weight: 600; font-size: 1.85rem; color: var(--ink); line-height: 1.05; }
.kpi-grid--dinero .kpi-card .kpi-num { font-size: 2.1rem; }

.kpi-delta { display: inline-flex; align-items: center; gap: .3rem; font-size: .82rem; font-weight: 600; }
.kpi-delta--bien { color: var(--kpi-bien); }
.kpi-delta--mal  { color: var(--kpi-mal); }
.kpi-delta--plano { color: var(--muted); font-weight: 500; }
.kpi-delta .kpi-perio { color: var(--muted); font-weight: 400; }

.kpi-nota { color: var(--muted); font-size: .74rem; line-height: 1.35; }
.kpi-spark { display: block; width: 100%; height: 30px; margin-top: auto; padding-top: .35rem; overflow: visible; }

/* Los que están en cero se atenúan en vez de esconderse: siguen ahí para tocarlos,
 * pero dejan de competir por la atención con los que sí tienen movimiento. */
.kpi-card--vacio { opacity: .5; }
.kpi-card--vacio:hover { opacity: 1; }

.kpi-seccion { display: flex; align-items: baseline; gap: .6rem; margin: 0 0 .6rem; }
.kpi-seccion h4 { margin: 0; font-size: .95rem; }
.kpi-seccion span { color: var(--muted); font-size: .8rem; }

@media (max-width: 560px) {
  .kpi-grid, .kpi-grid--dinero { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .kpi-card .kpi-num, .kpi-grid--dinero .kpi-card .kpi-num { font-size: 1.6rem; }
}

@media (max-width: 820px){
  /* En un teléfono los trece módulos no caben en un renglón, y partirlos en
   * cuatro se come media pantalla antes de empezar a trabajar. Las dos filas se
   * deslizan a lo ancho: se pierde el vistazo completo, pero se gana el alto,
   * que es lo escaso ahí. */
  .admin-nav { top: 0; }
  .admin-side { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; }
  .admin-side__pie { margin-left: .4rem; }
  .admin-nav-item .n { display: none; }
  /* El pie deja de ser pie: en una tira horizontal no hay abajo. */
  .admin-side__pie { margin: 0; padding: 0 0 0 .3rem; border-top: none; border-left: 1px solid var(--line); }

  /* El botón de cobrar iba detrás de TODO el catálogo: en una columna el ticket caía al
   * final, y cobrar es justo lo que más se repite en el día. Va primero. */
  .pos-ticket { order: -1; position: static; max-height: none; }

  /* Safari en iPhone hace zoom solo al enfocar un campo de menos de 16px, y deja la página
   * descuadrada. De los 404 campos del panel, 334 estaban por debajo —la mayoría en .97rem,
   * a un pelo—. Lleva !important porque las media queries no suman especificidad: `input`
   * es 0-0-1 y cualquier clase de componente (.tbl-search, .field input…) le gana siempre.
   * Sólo un campo pasaba de 16px, y por .32px, así que no se encoge nada que se note. */
  /* 16px y NO 1rem, aunque hoy valgan lo mismo: el umbral de Safari son dieciséis
     píxeles de verdad. `1rem` sigue al tamaño base del navegador, y a quien lo tenga
     bajado le volvería el zoom. Aquí el valor absoluto es el punto, no un descuido.
     (Una consolidación de tamaños de letra lo cambió a 1rem y hubo que devolverlo.) */
  input, select, textarea { font-size: 16px !important; }
}

/* La barra de arriba no podía envolverse ni encogerse —flex-wrap:nowrap y flex:none en
 * casi todo— y desbordaba a lo ancho la página entera en un teléfono. Va con !important
 * porque los estilos de esos elementos están en el atributo style y le ganan a la hoja. */
@media (max-width: 620px){
  .admin-top .container { gap: .5rem !important; }
  /* El logo del cliente se comía 179 de 375 píxeles y empujaba al distintivo de cuenta
   * («MI NEGOCIO» / «OPERANDO CLIENTE») fuera de su caja, encima del botón de salir.
   * En un teléfono el logo es lo prescindible: saber en qué cuenta estás, no. */
  .admin-top #brandLink { display: none !important; }
  .admin-top #brandBiz + span { display: none; }       /* el separador, ya sin nada que separar */
  .admin-top .container > div:first-child { overflow: hidden; }   /* por si algo más crece */
  .admin-top .hide-sm { display: none !important; }    /* la regla vieja sólo valía dentro
                                                          de .topbar__left/.topbar__right,
                                                          así que aquí no aplicaba nunca */
  .admin-top #cmdkBtn kbd { display: none; }           /* no hay ⌘K en un teléfono */
  .admin-top #appActual { font-size: .82rem; min-width: 0; }
  .admin-top select { max-width: 110px !important; }
}

/* A media pantalla (una laptop con el panel de al lado abierto) la barra de arriba no
 * cabía: su lado derecho no se encoge y empujaba al logo debajo de los botones y la
 * página fuera de la ventana. Aquí los botones se quedan en su dibujo —el título dice
 * qué son— y el selector de empresa se acorta. */
@media (max-width: 1180px){
  .admin-top #cmdkBtn span, .admin-top #cmdkBtn kbd, .admin-top #iaBtn span,
  .admin-top .menumodo span, .admin-top #logoutBtn span { display: none; }
  .admin-top #cmdkBtn, .admin-top #iaBtn, .admin-top #logoutBtn, .admin-top .menumodo { padding-inline: .55rem; }
  .admin-top .top-sel { max-width: 140px; }
}

/* =========================================================================================
   EN EL TELÉFONO NADA SE SALE DE LA VENTANA
   =========================================================================================
   `.admin-main` recorta a lo ancho (overflow-x: clip), así que lo que no cabía no daba
   scroll: se veía cortado. Las causas eran siempre las mismas:
     - rejillas con `1fr`, que en CSS vale `minmax(auto, 1fr)` y no baja del ancho de su
       contenido (una cifra de $102,102,380 en letra grande empujaba la tarjeta de al lado);
     - rejillas con columnas escritas en el atributo style, que le ganan a la hoja;
     - la barra de arriba, que no envolvía y sacaba el botón de salir de la pantalla.
   Sólo toca el teléfono y la tableta angosta; el escritorio queda igual. */
@media screen and (max-width: 760px) {
  /* Barra de arriba: los botones bajan a un segundo renglón en vez de salirse. */
  .admin-top .container { flex-wrap: wrap !important; row-gap: .4rem !important; }
  .admin-top .container > div:last-child { flex: 1 1 auto !important; min-width: 0; flex-wrap: wrap; justify-content: flex-end; }
  /* A 16px (para que iOS no haga zoom) el texto del selector de empresa no cabía en sus
   * 32px de alto y se veía cortado por abajo. */
  body .admin-top select { padding-block: 0; line-height: 1.2; }

  .omni { margin-inline: 0; padding-inline: .6rem; }   /* el -1rem de escritorio se salía */

  /* Rejillas: cada columna puede encogerse por debajo de su contenido. */
  .admin-grid { grid-template-columns: minmax(0, 1fr) !important; }
  .omni-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  .form { grid-template-columns: minmax(0, 1fr); }
  .admin-main :is(.admin-grid, .omni-kpis, .form, .row, .omni-grid2, .rep-grid) > * { min-width: 0; }
  .admin-main .kpi b, .admin-main .omni-card :is(b, .omni-val, [id^="k"]) { overflow-wrap: anywhere; }
  .admin-main :is(input, select, textarea) { max-width: 100%; }

  /* Rejillas de captura con columnas en el atributo style: a una sola columna. */
  .admin-main .form [style*="grid-template-columns"],
  .pm-body [style*="grid-template-columns"] { grid-template-columns: minmax(0, 1fr) !important; }

  /* Barras de botones y filtros: envuelven sin salirse. */
  .tbl-toolbar__actions { min-width: 0; max-width: 100%; }
  .tbl-toolbar__actions > * { max-width: 100%; }

  /* Plan de cuentas: las acciones del renglón bajan debajo del nombre. */
  body .cta-fila { flex-wrap: wrap; }
  body .cta-cod { min-width: 0; }
  body .cta-acc { flex-wrap: wrap; margin-left: 1.7rem; }

  /* Ventanas: nunca más altas ni más anchas que la pantalla; lo demás, scroll por dentro. */
  body .pm-fondo { padding: 16px; }
  body .pm-caja, .pm-caja--ancha { width: 100% !important; max-width: 100% !important; max-height: calc(100dvh - 32px); }
  body .pm-pie { flex-wrap: wrap; }
  body .doc-overlay { padding: 16px 16px 3rem; overscroll-behavior: contain; }
  body .doc-overlay .doc-toolbar { flex-wrap: wrap; justify-content: flex-start; }
  /* La tabla de un documento (póliza, factura) se desliza dentro de la hoja; la hoja no.
   * Sólo en pantalla: al imprimir sigue siendo tabla normal. */
  body .doc-overlay .doc-table { display: block; overflow-x: auto; }
  body .doc-overlay .doc-table :is(th, td) { padding-inline: .4rem; }
}
@media screen and (max-width: 420px) {
  /* En la pantalla más angosta la cifra de una tarjeta ya no cabe a dos columnas. */
  .omni-kpis { grid-template-columns: minmax(0, 1fr) !important; }
}

/* Reportes + tareas */
.rep-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
.rep-chart { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 1.3rem; margin-bottom: 1.4rem; }
.rep-chart h4 { font-family: var(--font-sans); font-weight: 700; margin-bottom: 1rem; }
.rep-bar { display: grid; grid-template-columns: 140px 1fr 80px; align-items: center; gap: .8rem; margin-bottom: .6rem; font-size: .9rem; color: var(--ink-2); }
.rep-bar .track { height: 12px; background: var(--cream-2); border-radius: 99px; overflow: hidden; }
.rep-bar .fill { height: 100%; background: linear-gradient(90deg, var(--red), #E86A63); border-radius: 99px; }
.rep-bar b { text-align: right; color: var(--ink); }
.task-item.done b { text-decoration: line-through; color: var(--muted); }

/* Visor de documento imprimible (factura, reporte, cotización) */
.doc-overlay { position: fixed; inset: 0; z-index: 200; background: rgba(0,0,0,.55); overflow-y: auto; padding: 2rem 1rem 4rem; }
.doc-overlay[hidden] { display: none; }
.doc-toolbar { max-width: 820px; margin: 0 auto .8rem; display: flex; gap: .6rem; justify-content: flex-end; }
/* =========================================================================================
   LA FICHA: UN DOCUMENTO Y UN INFORME NO SON LO MISMO
   =========================================================================================

   Por esta pieza salen once pantallas de dos clases que no se parecen:

     UN DOCUMENTO   el recibo de nomina, la constancia anual. Se imprime, se manda por
                    correo, lo guarda una persona. Hoja blanca con membrete: es lo que va
                    a recibir.

     UN INFORME     la poliza CONAC, la corrida en paralelo, el comparativo de la
                    quincena, el entero a terceros. Se mira, se decide y se cierra. Son
                    NUEVE de las once.

   Las once salian igual: hoja blanca, con el membrete del despacho —RFC, direccion,
   telefono— encima de una tabla que dice si la poliza cuadra. Ahi el membrete no es
   neutral: ocupa el primer tercio de la pantalla para decir algo que quien mira ya sabe.

   Y estaba escrito con nueve colores a mano —#fff, #eee, #999, #666, #f0f0f0—, que es
   por lo que no podia seguir al tema aunque se quisiera.

   Ahora son los mismos estilos con dos juegos de color. El informe usa el del panel; la
   hoja los fija. Y AL IMPRIMIR mandan los de la hoja en los dos casos: un informe impreso
   en oscuro se come el toner y no se lee.
   ========================================================================================= */
.doc-page {
  /* El informe: los colores del panel. */
  --doc-fondo: var(--surface);
  --doc-tinta: var(--ink);
  --doc-tinta-2: var(--ink-2);
  --doc-apagado: var(--muted-2);
  --doc-raya: var(--line);
  --doc-raya-fuerte: var(--line-2);
  --doc-marca: var(--red-tinta);

  max-width: 820px; margin: 0 auto;
  background: var(--doc-fondo); color: var(--doc-tinta);
  border: 1px solid var(--doc-raya);
  border-radius: 12px;
  padding: clamp(1.3rem, 3.5vw, 2.4rem);
  box-shadow: 0 20px 60px rgba(0,0,0,.4);
}

/* La hoja. Fija sus colores, asi que se ve igual en los dos temas —que es lo correcto:
   el papel no tiene modo oscuro. */
.doc-page--papel {
  --doc-fondo: #FFFFFF;
  --doc-tinta: #1B1714;
  --doc-tinta-2: #3C352E;
  --doc-apagado: #78706A;
  --doc-raya: #ECE7E0;
  --doc-raya-fuerte: #D8D1C8;
  --doc-marca: #C1272D;
  /* Lo que se pinta dentro con los colores del panel (`var(--muted)` del «Generada por»
     de la póliza, el cargo en las firmas, cajas en crema) seguía al tema: en oscuro salía
     gris claro sobre blanco (2.6:1) y cajas negras en la hoja. Aquí vuelven al claro. */
  --ink: #1B1714; --ink-2: #3C352E; --muted: #6E655C; --muted-2: #78706A;
  --line: #ECE7E0; --line-2: #D8D1C8; --red-tinta: #C1272D;
  --bg: #FFFFFF; --surface: #FFFFFF; --cream: #FBF8F3; --cream-2: #F4EDE3; --realce: #F4F0E9;
  border-radius: 8px;
  border-color: transparent;
}

.doc-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1rem; flex-wrap: wrap;
  border-bottom: 2px solid var(--doc-raya); padding-bottom: 1.1rem; margin-bottom: 1.3rem;
}
.doc-head .em b { font-family: var(--font-display); font-size: 1.4rem; color: var(--doc-marca); }
.doc-head .em span { display: block; font-size: .82rem; color: var(--doc-apagado); }
.doc-head .meta { text-align: right; }
.doc-head .meta .folio { font-family: var(--font-display); font-size: 1.5rem; color: var(--doc-marca); }
.doc-head .meta small { display: block; color: var(--doc-apagado); font-size: .84rem; }

/* El encabezado de un informe: el titulo manda, y va en la tipografia de datos. La serif
   es para un documento que alguien se lleva; un informe que se mira treinta segundos se
   lee mejor en la misma letra que el resto del panel. */
.doc-head--informe { align-items: baseline; }
.doc-head--informe .em b {
  font-family: var(--font-sans); font-size: 1.24rem; font-weight: 700;
  letter-spacing: -.015em; color: var(--doc-tinta);
}
.doc-head--informe .em span { margin-top: .15rem; color: var(--doc-tinta-2); font-size: .88rem; }

.doc-to { margin-bottom: 1.2rem; font-size: .92rem; }
.doc-to h5 { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--doc-apagado); margin-bottom: .3rem; }
.doc-table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
.doc-table th {
  text-align: left; font-size: .7rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--doc-apagado); border-bottom: 2px solid var(--doc-raya-fuerte); padding: .5rem .45rem;
}
.doc-table td { padding: .5rem .45rem; border-bottom: 1px solid var(--doc-raya); font-size: .9rem; }
/* Los importes de una ficha se comparan de arriba abajo igual que los de una tabla del
   panel: el 1 no puede ser mas angosto que el 8. */
.doc-table .r { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* EL BLOQUE DE SUMAS de una ficha: filas de «rotulo / importe» y un renglon final.
 *
 * Se llamaba `.doc-tot`, igual que la lista de totales fiscales de una factura, que es
 * otro componente con otra forma —una <dl> con dt/dd— y que vive mas abajo en esta hoja.
 * A igual especificidad manda la ultima, asi que la rejilla de la factura se aplicaba
 * tambien aqui y cada renglon de este se volvia una CELDA: en el recibo de nomina,
 * «Total percepciones» y «Total deducciones» salian uno al lado del otro.
 *
 * No se arregla subiendo la especificidad de uno de los dos: eso deja la trampa puesta
 * para el tercero que use el nombre. Se separan. */
.doc-sumas { margin-left: auto; max-width: 300px; }
.doc-sumas div { display: flex; justify-content: space-between; gap: 1rem; padding: .28rem 0; font-size: .92rem; font-variant-numeric: tabular-nums; }
.doc-sumas .g {
  border-top: 2px solid var(--doc-raya-fuerte); margin-top: .3rem; padding-top: .5rem;
  font-family: var(--font-display); font-size: 1.35rem;
}
.doc-page--papel .doc-sumas .g { font-family: var(--font-display); }
/* En un informe el total va en la letra de datos, por lo mismo que el titulo. */
.doc-page:not(.doc-page--papel) .doc-sumas .g { font-family: var(--font-sans); font-weight: 700; font-size: 1.15rem; }
.doc-note { margin-top: 1.3rem; font-size: .85rem; color: var(--doc-apagado); line-height: 1.55; }

/* AL IMPRIMIR, TODO ES HOJA. Un informe impreso con el fondo oscuro se come el toner y
   sale ilegible; y la barra de botones no tiene nada que hacer en el papel. */
@media print {
  .doc-overlay { position: static; background: none; padding: 0; overflow: visible; }
  .doc-toolbar { display: none; }
  .doc-page {
    --doc-fondo: #FFFFFF; --doc-tinta: #1B1714; --doc-tinta-2: #3C352E;
    --doc-apagado: #78706A; --doc-raya: #ECE7E0; --doc-raya-fuerte: #D8D1C8;
    --doc-marca: #C1272D;
    --ink: #1B1714; --ink-2: #3C352E; --muted: #6E655C; --muted-2: #78706A;
    --line: #ECE7E0; --line-2: #D8D1C8; --red-tinta: #C1272D;
    --bg: #FFFFFF; --surface: #FFFFFF; --cream: #FBF8F3; --cream-2: #F4EDE3; --realce: #F4F0E9;
    max-width: none; border: none; box-shadow: none; padding: 0;
  }
}
/* Dos maneras de imprimir desde el panel:
   1) Con una hoja abierta (póliza, recibo, estado de cuenta): sólo sale la hoja.
   2) Sin hoja (Balanza, Mayor, Estados, Flujo, Ingresos, Reportes: su botón llama a
      window.print() sobre la pantalla): sale la pantalla sin el marco del panel.
   Antes había un `body * { visibility: hidden }` SIN condición: en el caso 2 no quedaba
   nada visible y salían hojas en blanco; en el caso 1 el panel escondido seguía ocupando
   su alto y detrás de la póliza salían varias hojas vacías. `display: none` no ocupa. */
@media print {
  body:has(> .doc-overlay:not([hidden])) > :not(.doc-overlay) { display: none !important; }
  .doc-overlay { position: static; inset: auto; background: #fff; padding: 0; overflow: visible; }
  .doc-toolbar { display: none !important; }
  .doc-page { box-shadow: none; border-radius: 0; max-width: none; margin: 0; padding: 1rem; }
  .admin-top, .admin-nav, .admin-side, #supBanner, #wsTabs, #modTabs, .cajon, #cmdk, #cmdkOv,
  .admin-main button, .admin-main .btn { display: none !important; }
  .admin-body { display: block !important; }
  .admin-main { padding: 0 !important; margin: 0 !important; overflow: visible !important; max-width: none !important; }
  .admin-main table { break-inside: auto; }
  .admin-main thead { display: table-header-group; }
  .admin-main tr { break-inside: avoid; }
}
/* Imprimir con el tema oscuro puesto: el navegador no imprime fondos, pero sí la letra,
   y la letra del tema oscuro es casi blanca. En papel manda el tema claro. */
@media print {
  :root[data-theme="dark"] {
    color-scheme: light;
    --ink: #1B1714; --ink-2: #39322C; --muted: #6E655C; --muted-2: #767068;
    --red-tinta: #C1272D; --line: #EAE3DA; --line-2: #DED5C9;
    --bg: #FFFFFF; --cream: #FBF8F3; --cream-2: #F4EDE3; --surface: #FFFFFF;
    --realce: #F4F0E9; --tarjeta: #FFFFFF; --red-tint: #FBECED;
    --ok-tinta: #17724A; --aviso-tinta: #8A6520; --info-tinta: #2A5BC4; --mal-tinta: var(--red);
  }
  :root[data-theme="dark"] body { background: #fff; color: var(--ink); }
}
@media print { .header,.topbar,.footer,.newsletter,.fabs,.cookie,.quote-actions,.scroll-progress { display: none !important; } .quote-doc { box-shadow: none; border: none; } }

/* ===== Paleta del constructor de páginas: columna fija con scroll propio ===== */
/* Se queda pegada aunque arrastres por toda la página: nunca se pierde de vista. */
/* Ojo: sin esta regla, display:flex le gana a [hidden] y la paleta sigue ocupando lugar. */
.pg-paleta[hidden] { display: none; }
.pg-paleta { position: sticky; top: 80px; display: flex; flex-direction: column;
  height: calc(100vh - 104px); min-height: 420px; padding: .7rem .7rem .8rem; overflow: hidden; }
.pg-paleta__head { flex: 0 0 auto; padding-bottom: .5rem; border-bottom: 1px solid var(--line); }
.pg-paleta__buscar { width: 100%; margin-top: .45rem; border: 1px solid var(--line); border-radius: 8px;
  padding: .35rem .6rem; font-size: .8rem; background: #fff; color: var(--ink); }
.pg-paleta__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: .5rem .35rem .5rem 0; margin-right: -.35rem; }
.pg-paleta__body::-webkit-scrollbar { width: 8px; }
.pg-paleta__body::-webkit-scrollbar-thumb { background: #d8d2ca; border-radius: 8px; }
.pg-paleta__grupo { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); margin: .8rem 0 .4rem; }
.pg-paleta__grupo:first-child { margin-top: 0; }
.pg-paleta__vacio { font-size: .8rem; color: var(--muted); text-align: center; padding: 1rem .5rem; }
.pg-paleta__foot { flex: 0 0 auto; padding-top: .7rem; border-top: 1px solid var(--line); }

/* Cuadritos: caben muchos a la vista, como en un constructor profesional */
/* Se acomodan solos según lo ancha que esté la columna: 2 o 3 por renglón, nunca aplastados. */
.pg-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: .4rem; }
.pg-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .25rem;
  min-height: 62px; padding: .45rem .25rem; border: 1px solid var(--line); border-radius: 10px;
  background: #fff; color: var(--ink); font: 600 .68rem/1.15 inherit; text-align: center;
  cursor: grab; transition: border-color .12s, box-shadow .12s, transform .12s; }
.pg-tile:hover { border-color: var(--red, #C1272D); box-shadow: 0 3px 10px rgba(0,0,0,.09); transform: translateY(-1px); }
.pg-tile:active { cursor: grabbing; }
.pg-tile__ic { font-size: 1.15rem; line-height: 1; }
.pg-tile span:last-child { display: block; width: 100%; overflow-wrap: anywhere; }
/* Widgets de paga: punto dorado en la esquina */
.pg-tile--prem { position: relative; }
.pg-tile--prem::after { content: '✦'; position: absolute; top: 3px; right: 5px; font-size: .62rem; color: #C79A28; }
.pg-tile.pg-bloq { opacity: .55; cursor: not-allowed; }
/* Secciones reales del sitio: más anchas porque el nombre es largo */
#pgWidgets { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
:root[data-theme="dark"] .pg-tile, :root[data-theme="dark"] .pg-paleta__buscar { background: var(--cream-2, #241f1b); }
@media (max-width: 1100px) { .pg-paleta { position: static; height: auto; max-height: none; } .pg-paleta__body { overflow: visible; } }

/* ===== Integraciones: tarjetas parejas agrupadas por función ===== */
/* Antes usaban .admin-grid (1.6fr/1fr, pensado para contenido + barra lateral):
   quedaban de anchos distintos y con huecos. */
.integr-grupo { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin: 1.8rem 0 .8rem; font-size: 1rem; }
.integr-grupo:first-of-type { margin-top: .4rem; }
.integr-grupo span { font-size: .82rem; font-weight: 400; color: var(--muted); }
/* auto-fill (no auto-fit): una tarjeta sola conserva su ancho en vez de estirarse a todo lo largo. */
/* LAS INTEGRACIONES, EN LISTA.
 *
 * Eran ocho tarjetas en mosaico, cada una con su formulario abierto. Con dos o
 * tres se veía bien; con ocho es una pared de campos donde hay que leerlo todo
 * para encontrar el que se viene a tocar —y a Integraciones se viene a tocar UNO—.
 *
 * Ahora cada una es un renglón que dice su nombre, para qué sirve y si está
 * conectada. Se abre la que interesa y las demás no estorban. El `<details>` es
 * del navegador: no hace falta JavaScript para abrir y cerrar, así que funciona
 * aunque algo más falle en la página.
 */
.integr-lista { display: flex; flex-direction: column; gap: .5rem; margin-bottom: 1.6rem; }

.integr-fila { border: 1px solid var(--line); border-radius: 10px; background: var(--tarjeta); overflow: hidden; }
.integr-fila[open] { border-color: var(--marca); }

.integr-fila > summary {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .85rem 1rem; cursor: pointer; list-style: none;
}
.integr-fila > summary::-webkit-details-marker { display: none; }
/* La flecha la pone el CSS y gira al abrir: dice si hay algo debajo antes de
   pulsar, que es la única pregunta que se hace quien mira una lista cerrada. */
.integr-fila > summary::before {
  content: '›'; color: var(--muted); font-size: 1.2rem; line-height: 1;
  transition: transform .15s ease; display: inline-block;
}
.integr-fila[open] > summary::before { transform: rotate(90deg); }
.integr-fila > summary:hover { background: var(--realce); }

.integr-fila__nom { font-weight: 700; }
.integr-fila__que { color: var(--muted); font-size: .85rem; flex: 1 1 auto; }
/* El estado, a la derecha y con su color. Es lo que convierte la lista en un
   resumen: de un vistazo se ve qué falta por conectar. */
.integr-fila__estado { font-size: .78rem; font-weight: 700; white-space: nowrap; }
.integr-fila__estado[data-on="1"] { color: var(--ok-tinta); }
.integr-fila__estado[data-on="0"] { color: var(--muted); font-weight: 400; }

.integr-fila__cuerpo { padding: 0 1rem 1rem; border-top: 1px solid var(--line); padding-top: .9rem; }

@media (max-width: 640px) {
  .integr-fila__que { flex-basis: 100%; order: 3; }
}

/* stretch + flex: todas las tarjetas del renglón terminan a la misma altura
   y el botón "Probar conexión" queda abajo, alineado entre tarjetas. */
.integr-card { display: flex; flex-direction: column; }
.integr-card > div:last-child { margin-top: auto; padding-top: .6rem; }
.integr-card .field:last-of-type { margin-bottom: .4rem; }
/* El boton de quitar una llave guardada.
   Vive aqui y no repetido ocho veces en el HTML: es una decision, no ocho.
   `align-self` porque `.field` es una columna flex y sin el se estiraria a todo
   el ancho, con el peso visual de una accion principal —y esta es la que borra.
   El rojo es `--red-tinta` porque aqui el rojo es LETRA, no relleno.
   La regla de :hover no sobra: `.btn--ghost:hover` lleva dos clases y le ganaria
   a esta, y el boton perderia el rojo justo con el cursor encima. */
.quitar-llave { align-self: flex-start; margin-bottom: .4rem; color: var(--red-tinta); }
.quitar-llave:hover { color: var(--red-tinta); }
.integr-avanzado { margin-top: .4rem; border-top: 1px solid var(--line); padding-top: .7rem; }
.integr-avanzado > summary { cursor: pointer; font-size: .8rem; font-weight: 700;
  color: var(--ink-2); list-style: none; }
.integr-avanzado > summary::before { content: '▸ '; color: var(--muted); }
.integr-avanzado[open] > summary::before { content: '▾ '; }
.integr-avanzado > summary::-webkit-details-marker { display: none; }
@media (max-width: 760px) { .integr-grid { grid-template-columns: 1fr; } }

/* Arqueo de caja: rejilla de denominaciones */
.pcj-den { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: .5rem; }
.pcj-den__it { display: flex; align-items: center; gap: .4rem; border: 1px solid var(--line); border-radius: 8px; padding: .3rem .5rem; background: #fff; }
.pcj-den__it span { font-weight: 700; font-size: .82rem; color: var(--ink-2); min-width: 38px; }
.pcj-den__it input { width: 100%; border: 0; padding: .25rem; font-size: .9rem; background: transparent; color: var(--ink); }
:root[data-theme="dark"] .pcj-den__it { background: var(--cream-2, #241f1b); }

/* ===== Portal del cliente: seguimiento y facturación ===== */
.portal-aviso { border-left: 3px solid var(--red); margin-bottom: 1.4rem; }
.portal-ped { border: 1px solid var(--line); border-radius: 12px; padding: .9rem 1rem; margin-bottom: .8rem; }
.portal-ped__top { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.portal-ped__acc { margin-top: .7rem; }
/* Línea de etapas: se colorean las ya cumplidas y se marca la actual. */
.portal-track { display: flex; flex-wrap: wrap; gap: .3rem; margin: .6rem 0 0; }
.portal-track__step { font-size: .74rem; font-weight: 600; padding: .2rem .6rem; border-radius: 999px;
  background: var(--surface); color: var(--muted); border: 1px solid var(--line); }
.portal-track__step.on { background: #e8f5ee; color: #1f7a4d; border-color: #bfe3d0; }
.portal-track__step.now { background: #1f9d61; color: #fff; border-color: #1f9d61; }
.portal-track--cancel { color: var(--red-tinta); font-weight: 600; font-size: .85rem; }
@media (max-width: 620px) { .portal-ped__top { flex-direction: column; gap: .2rem; } }

/* ===== Optimizador de SEO ===== */
/* Imita cómo se ve el resultado en Google, para que el usuario entienda qué está editando. */
.seo-serp { border: 1px solid var(--line); border-radius: 10px; padding: .8rem 1rem; background: #fff; max-width: 560px; }
.seo-serp__url { font-size: .76rem; color: #4d7c37; margin-bottom: .15rem; }
.seo-serp__tit { color: #1a0dab; font-size: 1.05rem; line-height: 1.3; margin-bottom: .15rem; }
.seo-serp__desc { font-size: .84rem; color: #4d5156; line-height: 1.45; }
:root[data-theme="dark"] .seo-serp { background: var(--cream-2, #241f1b); }
:root[data-theme="dark"] .seo-serp__tit { color: #8ab4f8; }
:root[data-theme="dark"] .seo-serp__desc { color: #bdc1c6; }
.seo-tip { font-size: .82rem; line-height: 1.45; padding: .3rem .55rem; border-radius: 7px; margin-bottom: .3rem;
  background: rgba(var(--red-rgb),.06); color: var(--ink); border-left: 3px solid var(--red); }
.seo-tip.ok { background: rgba(31,157,97,.07); border-left-color: #1f9d61; color: var(--ink-2); }

/* ===== Pantalla de Ajustes: índice por módulo ===== */
.aj-layout { display: grid; grid-template-columns: minmax(190px, 230px) 1fr; gap: 1.4rem; align-items: start; }
.aj-nav { display: flex; flex-direction: column; gap: .25rem; position: sticky; top: 80px; }
.aj-nav__it { display: flex; align-items: center; gap: .5rem; width: 100%; text-align: left;
  border: 1px solid transparent; background: none; border-radius: 9px; padding: .5rem .7rem;
  font: 600 .87rem/1.2 inherit; color: var(--ink-2); cursor: pointer; }
.aj-nav__it:hover { background: var(--surface); }
.aj-nav__it.on { background: var(--surface); border-color: var(--line); color: var(--red-tinta); }
.aj-nav__it b { margin-left: auto; font-size: .72rem; opacity: .55; font-weight: 600; }
.aj-tit { margin: 0 0 .8rem; font-size: 1rem; }
.aj-tit:not(:first-child) { margin-top: 1.6rem; }
.aj-item { display: flex; align-items: center; gap: .9rem; width: 100%; text-align: left;
  border: 1px solid var(--line); background: #fff; border-radius: 11px; padding: .8rem 1rem;
  margin-bottom: .55rem; cursor: pointer; transition: border-color .12s, box-shadow .12s; }
.aj-item:hover { border-color: var(--red); box-shadow: 0 3px 12px rgba(0,0,0,.07); }
.aj-item b { font-size: .93rem; color: var(--ink); min-width: 210px; }
.aj-item span { font-size: .84rem; color: var(--muted); flex: 1; }
.aj-item i { font-style: normal; color: var(--muted); }
:root[data-theme="dark"] .aj-item { background: var(--cream-2, #241f1b); }
@media (max-width: 820px) { .aj-layout { grid-template-columns: 1fr; } .aj-nav { position: static; flex-direction: row; flex-wrap: wrap; }
  .aj-item { flex-direction: column; align-items: flex-start; gap: .2rem; } .aj-item b { min-width: 0; } }

/* ===== Redes sociales ===== */
.so-redes { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: .8rem; }
.so-red { border: 1px solid var(--line); border-radius: 12px; padding: .9rem; background: #fff; }
.so-red__ic { width: 38px; height: 38px; border-radius: 9px; display: grid; place-items: center; font-size: 1.2rem; margin-bottom: .5rem; }
.so-red b { display: block; margin-bottom: .2rem; }
.so-red p { margin: 0 0 .6rem; font-size: .78rem; }
/* Muro: una columna por cuenta, con scroll propio como en un gestor de redes. */
.so-muro { display: flex; gap: .9rem; overflow-x: auto; padding-bottom: .6rem; }
.so-col { flex: 0 0 300px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); max-height: 70vh; overflow-y: auto; }
.so-col__head { position: sticky; top: 0; background: #fff; border-bottom: 2px solid; padding: .6rem .8rem; font-size: .88rem; }
.so-col__head span { display: block; font-size: .74rem; }
.so-post { background: #fff; border: 1px solid var(--line); border-radius: 10px; margin: .55rem; padding: .7rem; }
.so-post img { width: 100%; border-radius: 8px; margin-bottom: .5rem; display: block; }
.so-post p { margin: 0; font-size: .84rem; line-height: 1.45; white-space: pre-wrap; }
.so-post__pie { display: flex; justify-content: space-between; gap: .5rem; margin-top: .6rem; font-size: .74rem; color: var(--muted); }
.so-cuentas { display: flex; flex-wrap: wrap; gap: .5rem; }
.so-chk { display: flex; align-items: center; gap: .4rem; border: 1px solid var(--line); border-radius: 999px;
  padding: .3rem .75rem; font-size: .84rem; cursor: pointer; background: #fff; }
.so-chk:has(input:checked) { border-color: var(--red); background: rgba(var(--red-rgb),.06); }
:root[data-theme="dark"] .so-red, :root[data-theme="dark"] .so-post, :root[data-theme="dark"] .so-chk,
:root[data-theme="dark"] .so-col__head { background: var(--cream-2, #241f1b); }

/* El mapa no puede salirse de su caja.
 *
 * Leaflet pinta sus capas con z-index hasta 400 y sus controles hasta 1000. Sin esto,
 * el mapa se dibuja ENCIMA de la ventana de captura -que va en 200- y el formulario
 * queda tapado a medias: se ve el titulo y los campos desaparecen debajo del mapa.
 *
 * `isolation: isolate` convierte el contenedor en su propio contexto de apilado, asi
 * que lo de dentro se ordena entre si pero nunca por encima de lo de fuera. Es mejor
 * que bajarle el z-index a las capas una por una: eso romperia el orden interno de
 * Leaflet -los marcadores dejarian de verse sobre los mosaicos-.
 */
.leaflet-container { position: relative; z-index: 0; isolation: isolate; }

/* ===== Ventana de captura (sustituye a los prompt del navegador) ===== */
.pm-fondo { position: fixed; inset: 0; background: rgba(20,16,14,.55); backdrop-filter: blur(3px);
  display: grid; place-items: center; z-index: 1200; padding: 1.2rem; animation: pmIn .14s ease; }
@keyframes pmIn { from { opacity: 0 } to { opacity: 1 } }
.pm-caja { background: #fff; border-radius: 16px; width: min(520px, 100%); max-height: 88vh;
  display: flex; flex-direction: column; box-shadow: 0 24px 60px rgba(0,0,0,.3); overflow: hidden; }
.pm-head { display: flex; align-items: center; gap: .8rem; padding: 1rem 1.2rem; border-bottom: 1px solid var(--line); }
.pm-head__ic { width: 40px; height: 40px; border-radius: 11px; background: var(--surface);
  display: grid; place-items: center; font-size: 1.3rem; flex: none; }
.pm-head b { display: block; font-size: 1rem; }
.pm-head span { display: block; font-size: .8rem; color: var(--muted); }
.pm-x { margin-left: auto; border: 0; background: none; font-size: 1.5rem; line-height: 1;
  color: var(--muted); cursor: pointer; padding: 0 .2rem; }
.pm-x:hover { color: var(--red-tinta); }
.pm-body { padding: 1.1rem 1.2rem; overflow-y: auto; }
.pm-body .field { margin-bottom: .8rem; }
/* Una lista con opciones largas —los regímenes del SAT— no ensancha el cuadro: se corta
   dentro de su campo en vez de sacar una barra horizontal. */
.pm-body { overflow-x: hidden; }
.pm-body .field { min-width: 0; }
.pm-body select { width: 100%; max-width: 100%; min-width: 0; text-overflow: ellipsis; }
.pm-pie { display: flex; justify-content: flex-end; gap: .6rem; padding: .9rem 1.2rem;
  border-top: 1px solid var(--line); background: var(--surface); }
/* Selector de icono */
.pm-iconos { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: .35rem; margin-top: .3rem; }
.pm-ico { border: 1px solid var(--line); background: #fff; border-radius: 9px; padding: .4rem;
  font-size: 1.15rem; cursor: pointer; transition: border-color .12s, transform .12s; }
.pm-ico:hover { border-color: var(--red); transform: translateY(-1px); }
.pm-ico.on { border-color: var(--red); background: rgba(var(--red-rgb),.08); box-shadow: inset 0 0 0 1px var(--red); }
:root[data-theme="dark"] .pm-caja, :root[data-theme="dark"] .pm-ico { background: var(--cream-2, #241f1b); }

/* ===== Bloques del constructor: legibles de un vistazo ===== */
/* El título en una sola línea: antes se partía en tres y descuadraba la tarjeta. */
.pg-block-tit { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: .92rem; }
.pg-block-head > span:first-child { min-width: 0; flex: 1; }
/* Resumen del contenido, para saber qué es sin abrir el código */
.pg-resumen { font-size: .84rem; line-height: 1.5; color: var(--ink-2); background: var(--surface);
  border-radius: 8px; padding: .55rem .7rem; margin-bottom: .4rem; }
.pg-resumen i { opacity: .6; }
.pg-meta { font-size: .72rem; color: var(--muted); margin-bottom: .5rem; }
/* El código va plegado y no se abre solo */
.pg-cod > summary { cursor: pointer; font-size: .78rem; font-weight: 700; color: var(--ink-2);
  list-style: none; padding: .35rem 0; }
.pg-cod > summary::-webkit-details-marker { display: none; }
.pg-cod > summary::before { content: '▸ '; color: var(--muted); }
.pg-cod[open] > summary::before { content: '▾ '; }
.pg-cod textarea { width: 100%; font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: .74rem; line-height: 1.5; tab-size: 2; white-space: pre; overflow-wrap: normal;
  overflow-x: auto; background: #1e1b18; color: #e8e2da; border-color: #3a332c; border-radius: 8px; }
:root[data-theme="dark"] .pg-cod textarea { background: #14110f; }

/* ===== Red de distribución y demos ===== */
.al-etapas { display: flex; gap: .2rem; }
.al-etapa { border: 1px solid var(--line); background: #fff; border-radius: 6px; padding: .2rem .45rem;
  font-size: .68rem; color: var(--muted); cursor: pointer; text-transform: capitalize; }
.al-etapa.on { background: #1f9d61; color: #fff; border-color: #1f9d61; }
.dm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 1rem; }
.dm-card { border: 1px solid var(--line); border-radius: 14px; padding: 1rem; background: #fff; display: flex; flex-direction: column; }
.dm-card__top b { display: block; font-size: 1rem; }
.dm-card__top span { font-size: .74rem; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.dm-card p { margin: .5rem 0 .7rem; flex: 1; }
.dm-datos { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: .8rem; }
.dm-datos span { font-size: .72rem; background: var(--surface); border-radius: 999px; padding: .15rem .6rem; color: var(--ink-2); }
.dm-acc { display: flex; gap: .4rem; flex-wrap: wrap; }
:root[data-theme="dark"] .dm-card, :root[data-theme="dark"] .al-etapa { background: var(--cream-2, #241f1b); }
.mod-lista { font-size: .82rem; color: var(--ink-2); margin-top: .3rem; }

/* ===== Gráficas del panel ===== */
.g-wrap { overflow-x: auto; }
.g-svg { width: 100%; height: auto; display: block; }
.g-linea { stroke: var(--line); stroke-width: 1; }
.g-val { font: 600 10px system-ui; fill: var(--ink-2); }
.g-eje { font: 500 10px system-ui; fill: var(--muted); }
.g-donut-t { font: 500 11px system-ui; fill: var(--muted); }
.g-donut-v { font: 800 15px system-ui; fill: var(--ink); }
.g-pastel { display: flex; gap: 1.6rem; align-items: center; flex-wrap: wrap; }
.g-legs { flex: 1; min-width: 220px; display: flex; flex-direction: column; gap: .3rem; }
.g-leg { display: flex; align-items: center; gap: .5rem; font-size: .85rem; }
.g-leg span { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.g-leg b { margin-left: auto; }
.g-leg i { font-style: normal; color: var(--muted); font-size: .78rem; min-width: 34px; text-align: right; }
.g-hbars { display: flex; flex-direction: column; gap: .5rem; }
.g-hb { display: grid; grid-template-columns: minmax(90px, 190px) 1fr auto; gap: .7rem; align-items: center; }
.g-hb__et { font-size: .85rem; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-hb__barra { background: var(--surface); border-radius: 6px; height: 20px; overflow: hidden; }
.g-hb__barra i { display: block; height: 100%; border-radius: 6px; transition: width .4s cubic-bezier(.2,.8,.2,1); }
.g-hb__val { font-size: .85rem; white-space: nowrap; }
.rv-sep { display: inline-block; width: 1px; height: 20px; background: var(--line); margin: 0 .4rem; vertical-align: middle; }
.toggle--ic { min-width: 34px; text-align: center; }
.g-barra { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.g-total { margin-left: auto; font-size: 1.05rem; }

/* ===== Tabla dinámica ===== */
.piv-barra { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; font-size: .82rem; color: var(--muted); }
.piv-sel { border: 1px solid var(--line); border-radius: 8px; padding: .3rem .5rem; font-size: .84rem; background: #fff; color: var(--ink); }
.piv-barra > button { margin-left: auto; }
.piv-wrap { max-height: 62vh; overflow: auto; }
.piv thead th { position: sticky; top: 0; z-index: 2; background: var(--surface); }
.piv-h { font-size: .74rem; text-transform: uppercase; letter-spacing: .03em; }
.piv-exp { border: 0; background: none; cursor: pointer; font-size: .95rem; color: var(--muted); padding: 0 .2rem; }
.piv-exp:hover { color: var(--red-tinta); }
.piv-n { font-size: .7rem; color: var(--muted); background: var(--surface); border-radius: 999px; padding: .05rem .4rem; }
.piv-fila > td { font-weight: 600; }
.piv-sub > td { background: rgba(0,0,0,.018); font-size: .85rem; font-weight: 400; }
.piv-ind { display: inline-block; width: 22px; }
.piv-cero { color: var(--muted); }
.piv-tot { font-weight: 800; }
.piv-total > td { border-top: 2px solid var(--line); background: var(--surface); font-weight: 700; }
:root[data-theme="dark"] .piv-sel { background: var(--cream-2, #241f1b); }
:root[data-theme="dark"] .piv-sub > td { background: rgba(255,255,255,.03); }

/* ===================================================================================
 *  El sistema Pi Management: los tres paquetes en la portada
 * ===================================================================================
 *
 * Va dentro de una banda oscura (`.section--ink`), que es la que el sitio ya usa para
 * destacar algo del resto. Los colores salen de ahí y no se inventan otros: una paleta
 * nueva sólo para esta sección la haría parecer pegada de otra página.
 */

.erp-puntos {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem;
  margin: 2.6rem 0 3.4rem;
}
.erp-punto {
  border-left: 2px solid #E8A0A3; padding-left: 1.1rem;
  display: flex; flex-direction: column; gap: .4rem;
}
.erp-punto b { font-size: 1.05rem; color: #FFF; }
.erp-punto span { font-size: .93rem; color: #C9BEB2; line-height: 1.6; }

.planes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; align-items: start; }

.plan {
  position: relative;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 16px; padding: 1.8rem 1.5rem;
  display: flex; flex-direction: column; gap: .8rem;
}

/* El de en medio se levanta un poco. Es la señal de «éste» sin tener que escribirlo,
 * y va acompañada del sello: sólo con el color, quien no distingue matices no ve nada. */
.plan--destacado {
  background: rgba(255,255,255,.09);
  border-color: #E8A0A3;
  transform: translateY(-10px);
}
.plan__sello {
  position: absolute; top: -11px; left: 1.5rem;
  background: var(--red); color: #FFF;
  font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: .25rem .7rem; border-radius: 99px;
}

.plan__nom { font-size: 1.25rem; font-weight: 700; color: #FFF; }
.plan__precio {
  font-size: 2.4rem; font-weight: 700; color: #FFF; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.plan__precio span { font-size: .85rem; font-weight: 500; color: #A99E92; letter-spacing: 0; }
.plan__para { font-size: .9rem; color: #C9BEB2; line-height: 1.55; margin: 0; }

.plan__lista { list-style: none; margin: .3rem 0 .6rem; padding: 0; display: flex; flex-direction: column; gap: .45rem; }
.plan__lista li {
  font-size: .9rem; color: #E4DAD0; padding-left: 1.35rem; position: relative; line-height: 1.45;
}
.plan__lista li::before {
  content: '✓'; position: absolute; left: 0; color: #E8A0A3; font-weight: 700;
}

.btn--block { display: block; width: 100%; text-align: center; margin-top: auto; }
.section--ink .btn--ghost { color: #F3ECE3; border-color: rgba(255,255,255,.28); }
.section--ink .btn--ghost:hover { background: #FFF; color: var(--ink); border-color: #FFF; }

.planes__pie { margin-top: 2rem; text-align: center; font-size: .85rem; color: #A99E92; }

@media (max-width: 1200px) {
  .planes { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
  .erp-puntos, .planes { grid-template-columns: 1fr; }
  /* En una columna, levantar el de en medio lo descoloca sin destacar nada: encima y
   * debajo hay otros, así que el sello es lo que lo distingue. */
  .plan--destacado { transform: none; }
}

/* ---- El tour: te lleva a la pantalla y te señala el botón de verdad ----
 *
 * El foco NO es un recuadro dibujado encima: es un hueco. Todo lo demás se oscurece con
 * una sombra enorme que sale de este elemento, así que lo que queda claro es exactamente
 * el botón — y sigue siendo el botón, no una copia pintada encima.
 */
.tour { position: fixed; inset: 0; z-index: 10000; pointer-events: auto; }
.tour__hueco {
  position: fixed; border-radius: 10px; pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(0,0,0,.55), 0 0 0 3px var(--red, #C1272D);
  transition: top .18s ease, left .18s ease, width .18s ease, height .18s ease;
}
.tour__globo {
  position: fixed; max-width: min(340px, calc(100vw - 24px));
  background: var(--tarjeta, #fff); color: var(--ink, #1a1a1a);
  border-radius: 14px; padding: 1rem 1.1rem;
  box-shadow: 0 18px 50px rgba(0,0,0,.35);
}
.tour__paso { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
              color: var(--ink-2, #6b6b6b); margin-bottom: .35rem; }
.tour__que { font-size: 1.05rem; font-weight: 700; line-height: 1.25; }
.tour__sub { font-size: .88rem; color: var(--ink-2, #6b6b6b); margin-top: .35rem; line-height: 1.5; }
.tour__pies { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .9rem; }

.tour__titulo { font-size: .78rem; font-weight: 700; color: var(--red, #C1272D); margin-bottom: .2rem; }
.tour__teclas { font-size: .72rem; color: var(--ink-2, #6b6b6b); margin-top: .55rem; text-align: right; }
.tour__pies .btn:disabled { opacity: .45; cursor: default; }
@media (max-width: 520px) {
  .tour__teclas { display: none; }
  .tour__pies { flex-wrap: wrap; }
}

/* ---- Tutoriales: tarjetas plegables con su avance ---- */
#ayudaTutoriales { display: grid; gap: .6rem; }
.tut { border: 1px solid var(--line); border-radius: 12px; padding: .7rem .9rem; background: var(--tarjeta, transparent); min-width: 0; }
.tut__cab { cursor: pointer; display: grid; gap: .2rem; list-style: none; }
.tut__cab::-webkit-details-marker { display: none; }
.tut__cab:focus-visible { outline: 2px solid var(--red, #C1272D); outline-offset: 3px; border-radius: 6px; }
.tut__tit { font-weight: 700; overflow-wrap: anywhere; }
.tut__meta { font-size: .8rem; color: var(--ink-2, #6b6b6b); }
.tut__barra { display: block; height: 4px; border-radius: 4px; background: var(--line); overflow: hidden; }
.tut__barra i { display: block; height: 100%; background: var(--red, #C1272D); }
.tut--listo .tut__barra i { background: var(--ok-tinta, #1f7a4d); }
.tut__pasos { margin: .6rem 0 .8rem; padding-left: 1.2rem; display: grid; gap: .45rem; }
.tut__pasos li { display: flex; gap: .5rem; align-items: flex-start; justify-content: space-between; min-width: 0; }
.tut__pasos label { display: flex; gap: .45rem; align-items: flex-start; flex: 1; min-width: 0; font-size: .9rem; overflow-wrap: anywhere; }
.tut__pasos small { display: block; color: var(--ink-2, #6b6b6b); font-size: .8rem; }
.tut__pasos .tb-link { flex: none; }

@media (prefers-reduced-motion: reduce) {
  .tour__hueco { transition: none; }
}

/* ===================================================================================
 *  LA HOJA DE REPORTE
 * ===================================================================================
 *
 * Un reporte fiscal o contable no es una lista de registros: es un documento que se
 * lee de arriba abajo y termina en una cifra. La tabla genérica del panel sirve para
 * listados —clientes, productos, comprobantes—, y aplicada a un reporte lo convierte
 * en una rejilla donde el total pesa lo mismo que cualquier renglón.
 *
 * Estas clases son ese documento: encabezado con de quién es, controles en UNA línea,
 * las cifras del mes arriba, el detalle como una hoja de declaración y el resultado
 * destacado. Se usan en Impuestos y de ahí bajan al resto de los reportes.
 *
 * Todo con los tokens de siempre: no hay un color nuevo en este bloque.
 */

.rep { background: var(--tarjeta); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }

/* Encabezado: qué es, de quién, y la acción principal a la derecha. */
.rep__cab { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
  padding: 1rem 1.15rem .9rem; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.rep__titulo { font-family: var(--font-display); font-size: 1.32rem; line-height: 1.15; margin: 0; }
.rep__quien { font-size: .8rem; color: var(--muted); margin: .2rem 0 0; }
.rep__acciones { display: flex; gap: .45rem; align-items: center; flex-wrap: wrap; }

/* Los controles, en una línea y sobre fondo crema para separarlos del contenido. */
.rep__barra { display: flex; flex-wrap: wrap; gap: .55rem; align-items: center;
  padding: .7rem 1.15rem; background: var(--cream); border-bottom: 1px solid var(--line); }
.rep__barra select, .rep__barra input { height: 34px; font-size: .86rem; }
.rep__barra input[type="number"] { max-width: 6.5rem; }
.rep__ayuda { margin-left: auto; font-size: .78rem; color: var(--muted);
  border: 0; background: none; border-bottom: 1px dotted var(--line-2); cursor: pointer; padding: 0 0 1px; }

/* El interruptor de vistas: pocas opciones fijas entre las que se salta a diario. Una
 * lista desplegable esconde las demás y obliga a dos clics para cada cambio. */
.seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: 999px;
  overflow: hidden; background: var(--tarjeta); }
.seg button { border: 0; background: none; font: inherit; font-size: .82rem; color: var(--ink-2);
  padding: .4rem .85rem; cursor: pointer; white-space: nowrap; }
.seg button:hover { background: var(--realce); }
.seg button[aria-pressed="true"] { background: var(--red); color: #fff; }

/* Las cifras del periodo. Sin tarjetas separadas: una rejilla con hilo, que pesa menos
 * y deja la última —el resultado— destacada en rojo. */
/* ===== Un documento que además SE LLENA =====
 *
 * El kit nació para documentos que sólo se leen, así que `.rep` no tiene relleno: los
 * renglones de una balanza llegan al borde a propósito. Un formulario dentro de la misma
 * caja necesita lo contrario, y sobre todo necesita ORDEN: que al mirarlo se entienda
 * qué cosa es cuál sin leer cada etiqueta.
 *
 * La forma que funciona es la de una factura de verdad, y por eso la usan todos los ERP:
 *
 *   · arriba, el título y en qué estado está;
 *   · debajo, dos columnas: a la izquierda A QUIÉN, a la derecha EN QUÉ CONDICIONES;
 *   · en medio, los conceptos en una tabla, con sus impuestos;
 *   · abajo a la derecha, los totales, en columna y alineados por la coma.
 *
 * Cada bloque contesta una pregunta distinta, así que la vista se recorre saltando al
 * bloque que interesa en vez de leyendo de arriba abajo.
 */
.rep__form { padding: 0 0 1.4rem; }

/* ===== QUE PAREZCA UN DOCUMENTO, NO UN FORMULARIO =====
 *
 * Ordenado ya estaba; lo que le faltaba era JERARQUÍA. Con todo del mismo peso —mismo
 * borde, mismo gris, misma letra— la vista no sabe dónde posarse y hay que leerlo entero
 * para encontrar el dato que se venía a buscar.
 *
 * Tres decisiones, y ninguna es adorno:
 *
 * 1) LOS CAMPOS SE VEN COMO DATOS. Una caja con borde por los cuatro lados grita
 *    «formulario»; una línea debajo dice «aquí va un dato» y deja leer el documento de
 *    corrido. Se conserva la línea SIEMPRE —no sólo al pasar por encima— porque un campo
 *    que no se ve no se sabe que se puede escribir, y eso es peor que un borde de más.
 *
 * 2) HAY UN NÚMERO PRINCIPAL. En una suscripción es lo que te depositan, y va con el
 *    tamaño y la letra de un titular. Un total que se ve igual que un subtotal obliga a
 *    leer las etiquetas para saber cuál es cuál.
 *
 * 3) EL ESTADO SE LEE DE UN VISTAZO, en una tira encadenada y no en pastillas sueltas:
 *    la forma dice que hay un camino y en qué punto va.
 */

/* --- El encabezado, con su franja --- */
.rep__cab { background: linear-gradient(180deg, var(--cream) 0%, var(--tarjeta) 100%); }
.rep__titulo { font-size: 1.5rem; letter-spacing: -.01em; }
.rep__quien { font-size: .82rem; margin-top: .3rem; }
.rep__quien code { background: var(--realce); padding: .05rem .35rem; border-radius: 4px; font-size: .78rem; }

/* --- Los campos del documento --- */
.rep__form .doc-campo > label { font-size: .72rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; padding-top: .1rem; }
.doc-cab .doc-campo .val input,
.doc-cab .doc-campo .val select,
.doc-pie .doc-campo .val input {
  border: 0; border-bottom: 1px solid var(--line-2); border-radius: 0;
  background-color: transparent; padding: .35rem .2rem; font-size: .95rem;
  transition: border-color .15s ease, background-color .15s ease;
}

/* EL NAVEGADOR DIBUJA SU PROPIA CAJA EN UN `select`.
 *
 * Aunque se le quite el borde, Chrome y Edge siguen pintando el control nativo con su
 * marco y su botón de flecha, así que el desplegable se veía como una caja al lado de
 * campos que ya no la tienen — justo la mezcla que hace que una pantalla parezca a
 * medio terminar. Se apaga la apariencia nativa y la flecha se dibuja aquí. */
.doc-cab .doc-campo .val select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%238A7F76' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .25rem center; background-size: .65rem;
  padding-right: 1.3rem; cursor: pointer;
}
.doc-cab .doc-campo .val input:hover,
.doc-cab .doc-campo .val select:hover,
.doc-pie .doc-campo .val input:hover { background-color: var(--realce); border-bottom-color: var(--ink-2); }
.doc-cab .doc-campo .val input:focus,
.doc-cab .doc-campo .val select:focus,
.doc-pie .doc-campo .val input:focus {
  outline: 0; background-color: var(--realce); border-bottom-color: var(--red);
  box-shadow: 0 1px 0 0 var(--red);
}
/* El que falta y es obligatorio se marca desde el principio, no al intentar guardar. */
.doc-cab .doc-campo .val select:invalid { border-bottom-color: var(--red); border-bottom-style: dashed; }

/* --- El bloque del cliente: su domicilio, como en el papel --- */
.doc-quien { margin: .55rem 0 .2rem 9.1rem; padding-left: .2rem;
  border-left: 2px solid var(--line); padding: .1rem 0 .1rem .7rem; }
.doc-quien b { font-family: var(--font-display); font-size: 1.02rem; letter-spacing: -.01em; margin-bottom: .1rem; }

/* --- La tira de etapas, encadenada --- */
.doc-etapas { gap: 0; }
.doc-etapas span { position: relative; border-radius: 0; border-right: 0;
  padding: .3rem .95rem .3rem 1.25rem; margin-left: -.55rem;
  clip-path: polygon(0 0, calc(100% - .55rem) 0, 100% 50%, calc(100% - .55rem) 100%, 0 100%, .55rem 50%);
  background: var(--realce); border: 0; font-size: .75rem; font-weight: 600; letter-spacing: .01em; }
.doc-etapas span:first-child { margin-left: 0; padding-left: .85rem;
  clip-path: polygon(0 0, calc(100% - .55rem) 0, 100% 50%, calc(100% - .55rem) 100%, 0 100%); }
.doc-etapas span:last-child { padding-right: 1.1rem;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, .55rem 50%); }
.doc-etapas span:only-child { clip-path: none; border-radius: 999px; }

/* --- Los conceptos --- */
.doc-lineas th { background: var(--cream); letter-spacing: .09em; }
.doc-lineas tbody tr { transition: background .15s ease; }
.doc-lineas tbody tr:hover { background: var(--realce); }
.doc-lineas td { font-size: .92rem; }
.doc-lineas td.r, .doc-lineas th.r { font-variant-numeric: tabular-nums; }
.doc-lineas input { border: 0; border-bottom: 1px solid transparent; border-radius: 0;
  background: transparent; padding: .3rem .2rem; font-size: .92rem; transition: border-color .15s ease; }
.doc-lineas input:hover { border-bottom-color: var(--line-2); }
.doc-lineas input:focus { outline: 0; border-bottom-color: var(--red); box-shadow: 0 1px 0 0 var(--red); }
.doc-chip { background: var(--realce); border: 1px solid var(--line); font-weight: 600;
  letter-spacing: .01em; color: var(--ink-2); }

/* --- Los totales, con un número principal --- */
.doc-tot { gap: .32rem 1.8rem; padding-top: 1.1rem; }
.doc-tot dt { font-size: .84rem; }
.doc-tot dd { font-size: .92rem; }
.doc-tot .raya { border-top: 1px solid var(--line); padding-top: .55rem; margin-top: .35rem; }
.doc-tot dt.fin { font-family: var(--font-display); font-size: 1rem; color: var(--ink); align-self: center; }
.doc-tot dd.fin { font-family: var(--font-display); font-size: 1.55rem; letter-spacing: -.02em;
  color: var(--red-tinta); line-height: 1.1; }
.doc-tot dd.menos { color: var(--red-tinta); opacity: .85; }

/* --- Los contadores de una que ya existe --- */
.doc-conta > div { border-color: var(--line); box-shadow: 0 1px 2px rgba(27,23,20,.04); }
.doc-conta b { letter-spacing: -.01em; }



/* Los contadores de una que ya existe: cuántas facturas lleva y cuánto renta al mes. */
.doc-conta { display: flex; gap: .55rem; flex-wrap: wrap; padding: .75rem 1.25rem;
  border-bottom: 1px solid var(--line); background: var(--cream); }
.doc-conta > div { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 10px;
  padding: .4rem .8rem; min-width: 7.5rem; }
.doc-conta span { display: block; font-size: .64rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.doc-conta b { font-family: var(--font-display); font-size: 1.05rem; }

/* La tira de etapas: en cuál está y cuáles quedan. Un sello suelto dice el estado; la
 * tira dice además por dónde va. */
.doc-etapas { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; }
.doc-etapas span { font-size: .74rem; padding: .28rem .7rem; border-radius: 999px;
  border: 1px solid var(--line-2); color: var(--muted); background: var(--tarjeta); white-space: nowrap; }
.doc-etapas span.on { background: var(--red); border-color: var(--red); color: #fff; font-weight: 600; }
.doc-etapas span.mal { background: var(--red-tint); border-color: var(--red); color: var(--red-tinta); font-weight: 600; }

/* Dos columnas: quién, y en qué condiciones. */
.doc-cab { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: .2rem 2.4rem; padding: 1.15rem 1.25rem 1.2rem; border-bottom: 1px solid var(--line); }

/* Renglón etiqueta → valor. La etiqueta va en gris y con el MISMO ancho en todo el
 * bloque: así los valores caen en columna y se leen de un vistazo, que es justo lo que
 * una etiqueta encima de cada campo no consigue. */
.doc-campo { display: grid; grid-template-columns: 8.2rem minmax(0, 1fr);
  align-items: center; gap: .3rem .9rem; margin-bottom: .55rem; }
.doc-campo > label { font-size: .82rem; color: var(--muted); margin: 0; font-weight: 500; }
.doc-campo > .val { min-width: 0; }
.doc-campo .val > input, .doc-campo .val > select { width: 100%; }
/* Un `select` es tan ancho como su opción más larga si no se le dice otra cosa, y la
 * opción más larga aquí es «RAZON SOCIAL LARGA SA DE CV · RFC». Sin esto se desbordaba
 * de su columna y se montaba encima de la etiqueta de la columna de al lado. */
.doc-campo .val, .doc-campo .val .fila { min-width: 0; }
.doc-campo .val input, .doc-campo .val select { min-width: 0; max-width: 100%; }
.doc-campo .form__note { grid-column: 2; margin: .15rem 0 0; font-size: .76rem; }

/* El bloque del cliente: su nombre y debajo su domicilio fiscal, como en el papel. */
.doc-quien { margin: .1rem 0 0 9.1rem; font-size: .84rem; color: var(--ink-2); line-height: 1.45; }
.doc-quien b { display: block; font-size: .92rem; color: var(--ink); }
.doc-quien code { font-size: .82rem; }
.doc-quien .dato { color: var(--muted); }

/* Los conceptos. */
.doc-lineas { width: 100%; border-collapse: collapse; }
.doc-lineas th { text-align: left; font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; padding: .55rem .7rem; border-bottom: 1px solid var(--line); }
.doc-lineas td { padding: .55rem .7rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
.doc-lineas th.r, .doc-lineas td.r { text-align: right; }
.doc-lineas input { width: 100%; }
.doc-lineas tr:last-child td { border-bottom: 0; }
.doc-chip { display: inline-block; font-size: .74rem; padding: .15rem .55rem; border-radius: 999px;
  background: var(--realce); color: var(--ink-2); white-space: nowrap; }

/* Los totales, a la derecha y alineados por la coma. */
.doc-tot { display: grid; grid-template-columns: max-content minmax(7rem, auto);
  justify-content: end; gap: .3rem 1.6rem; padding: .95rem 1.25rem 0; }
.doc-tot dt { font-size: .85rem; color: var(--ink-2); text-align: right; margin: 0; }
.doc-tot dt small { display: block; font-size: .72rem; color: var(--muted); }
.doc-tot dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; font-size: .9rem; }
/* `sep` a secas ya existe en el panel con otro aspecto —una raya gruesa de color— y
 * se colaba aquí: la raya de los totales tiene su propio nombre. */
.doc-tot .raya { border-top: 1px solid var(--line); padding-top: .5rem; margin-top: .3rem; }
.doc-tot .fin { font-weight: 700; }
.doc-tot dt.fin { font-size: .92rem; color: var(--ink); }
.doc-tot dd.fin { font-family: var(--font-display); font-size: 1.18rem; }
.doc-tot dd.menos { color: var(--red-tinta); }

/* El pie: lo que no es ni quién ni cuánto. */
.doc-pie { padding: 1.1rem 1.25rem 0; }
.doc-pie .fila-chica { display: flex; align-items: center; gap: .5rem; font-size: .86rem;
  color: var(--ink-2); margin: .1rem 0 .55rem; }

@media (max-width: 760px) {
  .doc-cab { grid-template-columns: 1fr; }
  .doc-campo { grid-template-columns: 1fr; }
  .doc-campo > label { margin-bottom: .1rem; }
  .doc-campo .form__note { grid-column: 1; }
  .doc-quien { margin-left: 0; }
  .doc-tot { grid-template-columns: 1fr max-content; }
}

.rep__cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px; background: var(--line); }
.rep__cifra { background: var(--tarjeta); padding: .8rem 1.05rem; }
.rep__cifra span { display: block; font-size: .66rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; }
.rep__cifra b { display: block; font-family: var(--font-display); font-size: 1.35rem; margin-top: .1rem;
  font-variant-numeric: tabular-nums; font-weight: 500; }
.rep__cifra--fin { background: var(--red-tint); }
.rep__cifra--fin span, .rep__cifra--fin b { color: var(--red-700); }
.rep__cifra--ok b { color: var(--ok-tinta); }
.rep__cifra--flojo b { color: var(--muted); }

/* La hoja: concepto a la izquierda, cifra a la derecha, hilo entre renglones. */
.hoja { padding: .9rem 1.15rem; }
.hoja__ren { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
  padding: .5rem 0; border-bottom: 1px solid var(--cream-2); }
.hoja__ren:last-child { border-bottom: 0; }
.hoja__que { font-size: .88rem; }
.hoja__nota { font-size: .74rem; color: var(--muted); margin-top: .12rem; }
.hoja__cif { font-variant-numeric: tabular-nums; font-size: .92rem; white-space: nowrap; }
.hoja__cif--flojo { color: var(--muted); }
/* El resultado: lo único que la mayoría viene a ver. */
.hoja__fin { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: .7rem; padding: .7rem .9rem; background: var(--red-tint); border-radius: var(--r-sm); }
.hoja__fin div { font-size: .9rem; font-weight: 600; color: var(--red-700); }
.hoja__fin b { font-family: var(--font-display); font-size: 1.22rem; color: var(--red-700);
  font-variant-numeric: tabular-nums; font-weight: 500; }
.hoja__fin--ok { background: var(--ok-fondo); }
.hoja__fin--ok div, .hoja__fin--ok b { color: var(--ok-tinta); }

/* Lo que quedó fuera del cálculo: tarjetas con su cifra, no tablas al final que nadie
 * baja a ver —y son justo lo que dice si el total de arriba es definitivo—. */
.montones { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: .6rem; padding: .9rem 1.15rem; border-top: 1px solid var(--line); }
.monton { border: 1px solid var(--line); border-radius: var(--r-sm); padding: .6rem .75rem;
  background: var(--tarjeta); text-align: left; font: inherit; cursor: pointer; }
.monton:hover { border-color: var(--line-2); background: var(--realce); }
.monton__t { display: flex; align-items: center; gap: .4rem; font-size: .85rem; }
.monton__n { font-size: .74rem; color: var(--muted); margin-top: .2rem; line-height: 1.35; }
.monton--ojo .monton__t { color: var(--aviso-tinta); }
.monton--mal .monton__t { color: var(--red-tinta); }

/* La línea de lo declarado: un número y su diferencia, no un formulario de ocho campos. */
.declara { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .75rem 1.15rem; border-top: 1px solid var(--line); background: var(--cream); }
.declara input { height: 34px; max-width: 8rem; text-align: right; font-variant-numeric: tabular-nums; }
.declara__txt { font-size: .84rem; color: var(--ink-2); }
.declara__mas { margin-left: auto; }

/* El selector de empresa dentro de un reporte: mismo alto que los demás controles de la
 * barra, y con el tipo en negrita porque es el dato que evita mirar el número del
 * cliente equivocado. */
.rep-emp { height: 34px; font-size: .86rem; font-weight: 600; max-width: 15rem; }

/* La cuenta contable se ELIGE de la lista de la empresa, no se teclea: un código que no
 * existe manda la póliza a una cuenta fantasma que no aparece en la balanza. */
select.cfs-cta { max-width: 15rem; font-size: .8rem; height: 30px; padding: 0 .4rem; }

/* EL PLAN DE CUENTAS, COMO ÁRBOL
 *
 * Setecientas cuentas en renglones sueltos no dicen de qué mayor cuelga cada detalle.
 * Con la sangría y el triángulo se lee la estructura —que es lo que un contador mira
 * primero— y se abre sólo la rama que interesa. */
.cta-fila { display: flex; align-items: center; gap: .5rem; padding: .3rem .6rem;
  border-bottom: 1px solid var(--cream-2); font-size: .88rem; }
.cta-fila:hover { background: var(--realce); }
.cta-fila:hover .cta-acc { opacity: 1; }
.cta-tog { width: 1.2rem; min-width: 1.2rem; border: 0; background: none; cursor: pointer;
  color: var(--muted); font-size: .8rem; padding: 0; }
.cta-cod { font-family: ui-monospace, Consolas, monospace; font-size: .8rem; color: var(--ink-2);
  min-width: 8.5rem; }
.cta-nom { flex: 1; min-width: 0; }
.cta-sat { font-size: .7rem; color: var(--muted); white-space: nowrap; }
/* Las acciones sólo al pasar por encima: en una lista larga, tres botones por renglón
 * son dos mil botones compitiendo con el dato. */
.cta-acc { display: flex; gap: .5rem; opacity: 0; transition: opacity .12s; }
@media (hover: none) { .cta-acc { opacity: 1; } }


/* =========================================================================================
   EL ARMAZON DEL PANEL
   =========================================================================================

   De que va esto. El panel abria claro, con el menu en una tira de pastillas arriba que se
   envolvia en tres renglones y cambiaba de alto al cambiar de modulo -asi que todo lo de
   abajo saltaba-. Ahora abre oscuro, con el menu en columna fija y una barra de pestanas de
   trabajo, que es como se ve un sistema en el que alguien pasa ocho horas.

   Lo que NO cambia son los colores. El rojo #C1272D con la tinta y el crema calidos son Pi
   Management; el gris azulado que lleva todo panel que se ve igual a otro no lo es. El tema
   oscuro que se usa aqui es el que ya estaba definido arriba, solo que ahora es el que sale
   por omision en el panel -no en el sitio publico, que sigue haciendo caso al sistema
   operativo-.

   Todo lo de aqui esta acotado a `.admin-shell`. Una sola regla suelta que tocara `.panel` o
   `.btn` a secas se llevaria por delante las paginas publicas, que usan las mismas clases.
   ========================================================================================= */

/* ---------- La barra de arriba: mas compacta y mas firme ---------- */
.admin-shell .admin-top {
  padding: .3rem 0;
  /* Una linea, no una sombra. La sombra sobre un fondo oscuro no se ve y deja la barra
     flotando sin borde; una linea si separa. */
  box-shadow: none;
  border-bottom: 1px solid var(--line);
}
.admin-shell .admin-top .container { min-height: 44px; }

/* ---------- Las pestanas de trabajo ---------- */
.wstabs {
  display: flex;
  align-items: stretch;
  gap: .3rem;
  padding: .42rem clamp(.6rem, 2vw, 1.1rem) 0;
  /* LA BARRA VA MAS OSCURA QUE LA HOJA, y la pestana activa del color de la hoja.
     Estaba al reves -barra en crema y pestana activa en el fondo, que es mas oscuro- y
     entonces la pestana abierta parecia un hueco y las cerradas parecian la de delante.
     Es el efecto de la carpeta: la lengueta de la que estas viendo es del mismo color que
     el papel, y por eso se lee como que es la misma pieza. */
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: thin;
  /* Se queda arriba al bajar por una lista larga: es la forma de volver a otra pantalla
     sin subir hasta el principio. El 44px es el alto de la barra de arriba. */
  position: sticky;
  top: 44px;
  z-index: 29;
}
.wstabs[hidden] { display: none; }

.wstab {
  display: inline-flex;
  align-items: center;
  gap: .42rem;
  flex: none;
  max-width: 15rem;
  padding: .42rem .6rem .42rem .55rem;
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: 9px 9px 0 0;
  background: transparent;
  color: var(--muted-2);
  font-size: .82rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  /* El borde de abajo de la barra lo pisa la pestana activa, que es lo que la hace
     parecer la hoja de delante y no un boton mas. */
  margin-bottom: -1px;
}
.wstab:hover { background: var(--realce); color: var(--ink); }
.wstab.on {
  background: var(--cream);
  border-color: var(--line);
  border-bottom: 1px solid var(--cream);
  color: var(--ink);
  font-weight: 600;
}
.wstab b { font-weight: inherit; overflow: hidden; text-overflow: ellipsis; }

/* El punto de color dice de que modulo es la pantalla, con el mismo color que ya usa su
   pestana de modulo y su icono en el lanzador. Con ocho pestanas abiertas es lo que deja
   encontrar la de nomina de un vistazo, sin leer los ocho rotulos. */
.wstab__pt {
  width: 7px; height: 7px; flex: none;
  border-radius: 99px;
  background: var(--mod, var(--muted-2));
}

.wstab__x {
  border: 0; background: none; padding: 0;
  width: 16px; height: 16px; flex: none;
  border-radius: 5px;
  color: var(--muted-2);
  font-size: 1rem; line-height: 1;
  cursor: pointer;
  /* Sale en blanco hasta que el raton entra en la pestana. Ocho cruces siempre visibles
     hacen que la barra parezca una lista de cosas por borrar. */
  opacity: 0;
}
.wstab:hover .wstab__x, .wstab.on .wstab__x { opacity: 1; }
.wstab__x:hover { background: var(--mal-fondo); color: var(--mal-tinta); }
.wstab__x:focus-visible { opacity: 1; outline: 2px solid var(--red-tinta); outline-offset: 1px; }

/* En un telefono la barra es lo primero que estorba: con el menu de modulos arriba, dos
   tiras que se deslizan una encima de otra son mas confusas que utiles. */
@media (max-width: 820px) {
  .wstabs { position: static; }
}

/* ---------- Los cajones laterales ----------
   Un cajon y no una ventana modal, y la diferencia importa: lo que se mira en un cajon
   hace falta MIENTRAS trabajas en otra cosa -los avisos de lo que acaba de pasar, la
   ayuda de la pantalla que tienes delante-. Una modal tapa justo aquello sobre lo que
   estas preguntando.

   El cajon de ayuda que ya existia llevaba todo esto escrito a mano en el atributo
   `style`. Aqui esta una vez, con nombre, para que el siguiente no lo vuelva a copiar. */
.cajon {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(420px, 94vw);
  z-index: 95;
  background: var(--tarjeta);
  border-left: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
}
.cajon[hidden] { display: none; }
.cajon__cab {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .9rem 1.1rem;
  border-bottom: 1px solid var(--line);
}
.cajon__cab b { font-size: 1.02rem; }
.cajon__x {
  border: 0; background: none; cursor: pointer;
  width: 30px; height: 30px; border-radius: 8px;
  font-size: 1.25rem; line-height: 1; color: var(--muted-2);
}
.cajon__x:hover { background: var(--realce); color: var(--ink); }
.cajon__cuerpo { flex: 1; overflow-y: auto; padding: .7rem .9rem; }
.cajon__pie {
  border-top: 1px solid var(--line);
  padding: .8rem 1.1rem;
  display: flex; flex-direction: column; align-items: flex-start; gap: .5rem;
}

/* ---------- La campana y sus avisos ---------- */
.top-campana { position: relative; overflow: visible; }
.noti-n {
  position: absolute; top: -3px; right: -3px;
  min-width: 15px; height: 15px; padding: 0 3px;
  border-radius: 99px;
  background: var(--muted-2); color: #fff;
  font-size: .62rem; font-weight: 700; line-height: 15px;
  text-align: center;
}
.noti-n[hidden] { display: none; }
/* UN AVISO MALO SIN VER VA EN ROJO. Con todo del mismo color, «3 CFDI rechazados» pesa lo
   mismo que «Guardado» y se entra a mirar igual de tarde. */
.noti-n--mal { background: var(--red); }

.noti {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: .5rem;
  padding: .55rem .6rem;
  border-radius: 9px;
  font-size: .86rem;
  line-height: 1.45;
}
.noti + .noti { margin-top: .15rem; }
.noti:hover { background: var(--realce); }
.noti__pt {
  width: 7px; height: 7px; margin-top: .42rem;
  border-radius: 99px; background: var(--ok-tinta);
}
.noti--mal .noti__pt { background: var(--red); }
/* Lo ya visto se apaga en vez de desaparecer: sigue ahi para releerlo, pero deja de
   competir por la vista con lo que acaba de pasar. */
.noti--visto { color: var(--muted-2); }
.noti--visto .noti__pt { opacity: .45; }
.noti__txt { min-width: 0; overflow-wrap: anywhere; }
.noti__veces {
  background: var(--realce); border-radius: 99px;
  padding: 0 .38rem; font-size: .72rem; font-weight: 700; color: var(--muted-2);
}
.noti__hora { font-size: .72rem; color: var(--muted-2); white-space: nowrap; padding-top: .18rem; }

/* ---------- El asistente ----------
   Un cajon y no una modal, y aqui la razon es mas fuerte que en los avisos: lo que se le
   pregunta es casi siempre sobre lo que tienes delante -«¿por que no cuadra ESTA
   poliza?»-, y una modal taparia justo eso. */
.top-ia { gap: .35rem; }
.top-ia svg { width: 14px; height: 14px; }
@media (max-width: 900px) { .top-ia span { display: none; } }

.cajon--ia .cajon__cuerpo { display: flex; flex-direction: column; gap: .55rem; }
/* En que pantalla cree que estas. Va en el encabezado y no escondido, porque es de lo que
   depende que la respuesta sirva: si dice otra cosa de la que tienes delante, la respuesta
   va a ser de otra pantalla y no hay forma de saberlo por el texto. */
.ia-donde {
  margin-left: auto; margin-right: .3rem;
  font-size: .72rem; color: var(--muted-2);
  max-width: 11rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.iamsg { max-width: 92%; font-size: .87rem; line-height: 1.5; }
.iamsg__txt { padding: .55rem .7rem; border-radius: 12px; overflow-wrap: anywhere; }
.iamsg--yo { align-self: flex-end; }
.iamsg--yo .iamsg__txt { background: var(--red-tint); color: var(--ink); border-radius: 12px 12px 3px 12px; }
.iamsg--ia { align-self: flex-start; }
.iamsg--ia .iamsg__txt { background: var(--realce); border-radius: 12px 12px 12px 3px; }
/* Con cual de los dos se contesto y si vio la pantalla entera. Chico y apagado: es
   informacion que hace falta tener pero que no se lee en cada mensaje. */
.iamsg__pie { font-size: .7rem; color: var(--muted-2); padding: .2rem .7rem 0; }
.iamsg--vacio { max-width: none; align-self: stretch; color: var(--muted-2); padding: .4rem .2rem; }
/* EL PLAN, DICHO EN EL ENCABEZADO: «Plan básico» o «Pia · complemento activo». Quien no
   sabe en cuál está cree que lo que ve es lo que compraría. */
.ia-plan { font-size: .7rem; padding: .1rem .45rem; border-radius: 999px; background: var(--realce); color: var(--muted-2); white-space: nowrap; }
.ia-plan--pro { background: var(--ok-fondo, #E8F0EC); color: var(--ok-tinta, #1F6B45); }
/* El consumo del mes: aproximado, con barra; al 80% se pinta de aviso y agotado lo dice. */
.ia-uso { padding: .45rem .9rem .5rem; font-size: .74rem; color: var(--muted-2); border-bottom: 1px solid var(--line, #e5e0d8); }
.ia-uso__barra { height: 5px; border-radius: 3px; background: var(--realce); overflow: hidden; margin-top: .3rem; }
.ia-uso__barra i { display: block; height: 100%; background: var(--ok-tinta, #1F6B45); }
.ia-uso--aviso .ia-uso__barra i { background: #B45309; }
.ia-uso--aviso b, .ia-uso--agotado b { color: #B45309; }
/* Las sugerencias del saludo y las propuestas del asistente. */
.ia-sug { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .55rem; }
.ia-sug button { font: inherit; font-size: .78rem; padding: .3rem .65rem; border-radius: 999px; border: 1px solid var(--line, #d8d2c8); background: transparent; cursor: pointer; color: var(--ink); text-align: left; }
.ia-sug button:hover { border-color: var(--red); }
.ia-prop { margin-top: .5rem; border: 1px dashed var(--line, #ccc); padding: .55rem .6rem; border-radius: 8px; background: var(--bg, #fff); }
.ia-prop__acc { display: flex; gap: .4rem; margin-top: .45rem; flex-wrap: wrap; }
.ia-prop--fuera { opacity: .55; }
.ia-propuesta-aviso { border: 2px dashed var(--red); padding: .6rem .8rem; border-radius: 6px; color: var(--ink); margin-bottom: .8rem; }
/* SOPORTE KERN CON IA (2026-09-30): el cajón tiene dos modos —el asistente de siempre y el
   soporte—, cada respuesta de soporte lleva «¿Te sirvió?» y sus botones (reportar falla,
   pedir ayuda con costo, agendar consultoría). */
.ia-modo { display: flex; gap: .3rem; padding: .45rem .9rem; border-bottom: 1px solid var(--line, #e5e0d8); }
.ia-modo button { font: inherit; font-size: .78rem; padding: .28rem .8rem; border-radius: 999px; border: 1px solid var(--line, #d8d2c8); background: transparent; color: var(--muted-2); cursor: pointer; }
.ia-modo button.on { background: var(--red); border-color: var(--red); color: #fff; }
.ia-sop-info { padding: .4rem .9rem; font-size: .74rem; color: var(--muted-2); border-bottom: 1px solid var(--line, #e5e0d8); }
.ia-acc { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem; }
.ia-util { display: flex; align-items: center; gap: .35rem; font-size: .72rem; color: var(--muted-2); padding: .3rem .7rem 0; }
.ia-util button { font: inherit; font-size: .72rem; padding: .1rem .55rem; border-radius: 999px; border: 1px solid var(--line, #d8d2c8); background: transparent; cursor: pointer; color: var(--ink); }
.ia-util button.on { background: var(--realce); border-color: var(--ink); }
.sop-tipo { font-size: .7rem; padding: .1rem .45rem; border-radius: 999px; white-space: nowrap; background: var(--realce); color: var(--ink); }
.sop-tipo--falla { background: var(--ok-fondo, #E8F0EC); color: var(--ok-tinta, #1F6B45); }
.sop-tipo--ayuda { background: var(--aviso-fondo, #FBF0E0); color: #8A4B08; }

/* La casilla de «mandar lo que veo». A la vista y con su tamano, porque mandar una nomina
   de cuatrocientas personas a un modelo es una decision de quien opera, no un detalle de
   implementacion que se pueda dejar escondido. */
.ia-ver { display: flex; align-items: center; gap: .45rem; font-size: .78rem; color: var(--muted-2); cursor: pointer; }
.ia-ver input { margin: 0; }
.ia-ver b { font-weight: 600; color: var(--muted-2); }

.ia-caja { display: flex; align-items: flex-end; gap: .45rem; width: 100%; }
.ia-caja textarea {
  flex: 1; resize: vertical; min-height: 2.6rem; max-height: 9rem;
  font: inherit; font-size: .87rem;
}

/* =========================================================================================
   LA DENSIDAD DEL PANEL
   =========================================================================================

   POR QUE TODO ESTO VA ACOTADO A `.admin-shell`

   Porque `.panel`, `.field`, `.btn`, `.eyebrow` y `.kpi` los comparten el panel y las
   veintinueve paginas publicas. Ahi el aire editorial es el trabajo: una pagina de venta
   se lee de arriba abajo una vez y el espacio es lo que la hace respirar.

   El panel es lo contrario. Se mira ocho horas, se compara una columna con otra, y cada
   centimetro de aire es una fila de la tabla que hay que ir a buscar desplazandose. Un
   `padding: 1.9rem` repetido en 229 paneles son varias pantallas de nada.

   Asi que son los MISMOS componentes con dos densidades, y no dos juegos de clases: un
   juego aparte obligaria a acordarse de cual toca en cada sitio, y a la tercera pantalla
   alguien pone la que no es.

   LO QUE NO SE TOCA: el tamano del texto que se LEE. Los parrafos de ayuda, los rotulos y
   los importes se quedan como estan. Apretar es quitar hueco, no encoger la letra — un
   panel denso que no se lee no es denso, es ilegible.
   ========================================================================================= */

/* ---------- La tarjeta ---------- */
.admin-shell .panel {
  padding: 1.15rem 1.25rem;
  border-radius: 12px;
  /* SOBRE OSCURO MANDA EL BORDE, NO LA SOMBRA. Una sombra sobre un fondo oscuro no se ve
     —no hay luz que tapar— y la tarjeta queda flotando sin contorno. El borde separa
     igual de bien en los dos temas y no cuesta pintura. */
  box-shadow: none;
  border-color: var(--line);
}
.admin-shell .panel + .panel { margin-top: .9rem; }
.admin-shell .panel h3 { font-size: 1.02rem; margin-bottom: .25rem; }
.admin-shell .panel .eyebrow { margin-bottom: .6rem; }

/* El titulo de la pantalla. 1.5rem es tamano de portada; aqui compite con la fila de
   botones que tiene al lado y roba el alto de dos renglones de tabla. */
.admin-shell .tbl-toolbar h3,
.admin-shell .panel-title { font-size: 1.22rem; }
.admin-shell .tbl-toolbar { margin-bottom: .85rem; gap: .7rem; }
.admin-shell .admin-main { padding: 1rem clamp(.8rem, 2vw, 1.4rem) 2.5rem; }

/* ---------- Los campos ----------
   703 campos. El alto de uno se multiplica por doce en cada formulario, y un alta de
   cliente que no cabe en la pantalla obliga a desplazarse para ver si falta algo. */
.admin-shell .field { gap: .25rem; }
.admin-shell .field label { font-size: .78rem; }
.admin-shell .field input,
.admin-shell .field select,
.admin-shell .field textarea {
  font-size: .89rem;
  padding: .48rem .6rem;
  border-radius: 8px;
}
.admin-shell .field textarea { min-height: 84px; }
/* El anillo del foco se queda, y mas marcado. Es lo unico que dice en que campo estas
   cuando se llena con el teclado, y al apretar los campos estan mas cerca unos de otros. */
.admin-shell .field input:focus,
.admin-shell .field select:focus,
.admin-shell .field textarea:focus { box-shadow: 0 0 0 2px var(--red-tint); }

.admin-shell .form__note { font-size: .8rem; line-height: 1.5; }
.admin-shell .eyebrow { font-size: .66rem; }

/* ---------- Las tablas ----------
   Aqui hay una cosa que no es estetica: LOS ENCABEZADOS SE QUEDAN.

   Una corrida de nomina son cuatrocientos renglones. Al tercer desplazamiento ya no se ve
   que columna es cual, y el que compara «percepciones» con «deducciones» acaba contando
   columnas con el dedo en la pantalla. Es de las cosas que no se reportan como fallo
   porque nadie cree que se pueda arreglar. */
.admin-shell .tabla-odoo { font-size: .845rem; }
.admin-shell .tabla-odoo thead th {
  position: sticky;
  /* DESDE DONDE SE PEGA, Y AQUI HAY DOS CASOS QUE NO SE PARECEN.
   *
   * Una tabla suelta en la pantalla se pega a la VENTANA, asi que tiene que pararse
   * debajo de la barra de arriba y de las pestanas: ese alto lo mide el JS en `--techo`,
   * porque el CSS no puede saber si la barra de pestanas esta o no.
   *
   * Pero casi ninguna tabla esta suelta: `tablaHTML` las envuelve en `.tabla-wrap`, que
   * lleva `overflow-x: auto` — y eso convierte al envoltorio en contenedor de
   * desplazamiento EN LOS DOS EJES, porque un eje en `auto` obliga al otro a dejar de ser
   * `visible`. Dentro de un contenedor asi, `sticky` se pega a LA CAJA, no a la ventana,
   * y un `top` de 59px empuja el encabezado 59px hacia ABAJO dentro de la tabla: se queda
   * flotando encima del segundo renglon, tapandolo.
   *
   * Asi que el valor de fabrica es el de la ventana, y dentro de un envoltorio se pone a
   * cero unas lineas mas abajo. */
  top: var(--techo, 54px);
  z-index: 3;
  padding: .5rem .75rem;
  /* Opaco a proposito: si fuera translucido, las filas pasarian por debajo y se leeria
     el encabezado encima del dato. */
  background: var(--cream-2);
}
.admin-shell .tabla-odoo tbody td { padding: .46rem .75rem; }

/* DENTRO DE UN ENVOLTORIO, DESDE SU PROPIO BORDE.
 *
 * `.tabla-wrap` y `.tabla-scroll` llevan `overflow-x: auto` para que una tabla ancha se
 * deslice en vez de partir la pantalla. El efecto de lado es que se vuelven contenedores
 * de desplazamiento, y el `sticky` de dentro deja de mirar a la ventana.
 *
 * Aqui el cero es lo correcto: el encabezado se para en el borde de arriba de su propia
 * caja. Si la caja tiene alto limitado —como la vista previa de una poliza— se queda
 * quieto mientras las filas corren por debajo, que es justo lo que se queria; y si no lo
 * tiene, se queda en su sitio de siempre y no tapa nada. */
.admin-shell .tabla-wrap .tabla-odoo thead th,
.admin-shell .tabla-scroll .tabla-odoo thead th { top: 0; }

/* LOS NUMEROS SE ALINEAN. En la mayoria de las tipografias el 1 es mas angosto que el 8,
   asi que una columna de importes sale con los puntos decimales bailando y comparar dos
   cifras de un vistazo deja de funcionar. `tabular-nums` le pide a la fuente el ancho fijo
   que ya trae para esto. */
.admin-shell .tabla-odoo td.r,
.admin-shell .tabla-odoo th.r,
.admin-shell .doc-table td.r,
.admin-shell .kpi b { font-variant-numeric: tabular-nums; }

/* ---------- Los indicadores ----------
   El numero va en la tipografia de datos y no en la serif de portada: una serif con
   numeros de altura variable es preciosa en un titular y mala para comparar cuatro cifras
   puestas en fila, que es justo para lo que existe un tablero. */
.admin-shell .kpi { padding: .85rem .95rem; border-radius: 12px; box-shadow: none; }
.admin-shell .kpi b {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.32rem;
  letter-spacing: -.01em;
}
.admin-shell .kpi span { font-size: .68rem; }

/* ---------- Los botones ----------
   No se encogen: se acercan. Un boton chico se falla al apuntarlo, y el que se falla aqui
   es «Timbrar». Lo que baja es el hueco alrededor. */
.admin-shell .fila-acc { gap: .45rem; }

/* En un telefono la barra de arriba no se queda fija igual, asi que el encabezado pegajoso
   se quedaria colgado a mitad de pantalla. */
@media (max-width: 820px) {
  .admin-shell .tabla-odoo thead th { position: static; }
}

/* ---------- El tablero de inicio ----------

   LA CABECERA DICE QUE HAY HOY, no como se llama la pantalla.

   Antes decia «Command Center / Resumen del negocio», que es lo mismo todos los dias y
   por tanto no es informacion: es un rotulo. Ahora lleva la fecha, el saludo con el
   nombre del negocio -importa, porque hay cuentas con varias empresas y el selector esta
   arriba, lejos- y un renglon con lo que hay pendiente.

   Y no lleva degradado ni banda de color. El tablero se abre cada manana durante anos;
   un adorno que se ve mil veces deja de verse y lo unico que queda es el espacio que
   ocupaba. El peso lo lleva la tipografia. */
.omni-head--hero { align-items: flex-start; margin-bottom: 1rem; }
.omni-estado {
  margin: .3rem 0 0;
  font-size: .92rem;
  color: var(--ink-2);
}
/* Los numeros del renglon de pendientes van en la tinta normal y en negrita, no en rojo.
   En rojo, un tablero con cualquier cosa por cobrar parece una emergencia todos los dias
   — y a la tercera manana ya nadie lo mira. El rojo se guarda para lo que de verdad
   esta mal, que es lo que ya hace la tarjeta de tareas pendientes. */
.omni-estado b { color: var(--ink); font-weight: 700; }

/* Las tarjetas de modulo, en el tablero. Mas chicas que en el lanzador: ahi son la
   pantalla entera y aqui son una seccion mas, debajo de los numeros. */
.app-grid--tablero { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: .7rem; }
.app-grid--tablero .app-card { padding: .95rem .6rem; border-radius: 12px; }
.app-grid--tablero .app-ico { width: 38px; height: 38px; border-radius: 11px; margin-bottom: .5rem; }
.app-grid--tablero .app-ico svg { width: 18px; height: 18px; }
.app-grid--tablero .app-card b { font-size: .8rem; }
/* El levantamiento al pasar por encima se queda, pero mas corto: con doce tarjetas en
   rejilla, tres pixeles ya se notan y seis parecen un salto. */
.app-grid--tablero .app-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }

/* Un cajon de PROSA, no de renglones.
   Los avisos y el asistente llevan filas y burbujas que ya traen su propio hueco dentro,
   asi que el cajon les da poco por fuera. La ayuda es un texto seguido de hasta veinte
   renglones: a .9rem del borde se lee apretado contra el cristal, y en 420px de ancho eso
   se nota en cada linea. */
.cajon--prosa .cajon__cuerpo { padding: 1.1rem 1.2rem; }
.ayuda-txt {
  /* Los textos de ayuda se escriben con saltos de linea a mano, no con etiquetas: sin
     esto salen todos pegados en un solo parrafo. */
  white-space: pre-line;
  line-height: 1.6;
  font-size: .9rem;
}

/* =========================================================================================
   EL MENU EN COLUMNA, EN ACORDEON
   =========================================================================================

   Antes se veian los 124 botones de los doce modulos seguidos, en una sola lista, y solo
   el encabezado del modulo en el que estabas: la lista mas larga posible con la menor
   cantidad posible de pistas de donde empieza y acaba cada cosa.

   Ahora cada modulo es un grupo que se abre y se cierra, con su mosaico de color y su
   icono — los mismos que ya tenia en su pestana y en el lanzador. Un modulo con dos
   colores distintos segun donde lo mires no se reconoce en ninguno de los dos.
   ========================================================================================= */
[data-menu="columna"] #adminApp { grid-template-columns: 236px minmax(0, 1fr); }
[data-menu="columna"] .admin-side { padding: .4rem .35rem; }
/* El grupo vuelve a ser una caja: con `display: contents` no habia nada que plegar, y por
   eso el acordeon no se podia hacer sin tocar el HTML de las doce secciones. */
[data-menu="columna"] .admin-side .group { display: block; margin-bottom: .12rem; }

/* Los dos selectores, y hace falta: mas arriba vive
 * `[data-menu="columna"] .admin-side .group.abierto h6`, de cuando el encabezado del
 * grupo abierto era el unico que se veia. Lleva una clase mas que este, asi que sin
 * nombrar `.abierto` aqui, el grupo ABIERTO —justo el que mas se mira— se quedaba con el
 * estilo viejo: mayusculas chiquitas y sin mosaico. */
[data-menu="columna"] .admin-side .group > h6,
[data-menu="columna"] .admin-side .group.abierto > h6 {
  display: flex; align-items: center; gap: .55rem;
  width: 100%; margin: 0; padding: .42rem .45rem;
  border-radius: 9px; cursor: pointer;
  font-size: .82rem; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--ink-2);
}
[data-menu="columna"] .admin-side .group > h6:hover { background: var(--realce); color: var(--ink); }
[data-menu="columna"] .admin-side .group > h6:focus-visible { outline: 2px solid var(--red-tinta); outline-offset: -2px; }
[data-menu="columna"] .admin-side .group.abierto > h6 { color: var(--ink); }

/* El mosaico de color. 26px: bastante para reconocer el modulo de un vistazo y poco para
   que doce seguidos no se conviertan en una tira de colores que no dice nada. */
.grupo__ic {
  width: 26px; height: 26px; border-radius: 8px; flex: none;
  display: grid; place-items: center; color: #fff;
}
.grupo__ic svg { width: 14px; height: 14px; }
.grupo__n { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grupo__ch {
  width: 13px; height: 13px; flex: none; color: var(--muted-2);
  transition: transform .18s;
}
[data-menu="columna"] .admin-side .group.abierto > h6 .grupo__ch { transform: rotate(90deg); }

/* Lo de dentro, plegado. Se sangra a la altura del texto del grupo, no del mosaico: asi
   la lista de pantallas se lee como una columna propia y no como una continuacion. */
[data-menu="columna"] .admin-side .group:not(.abierto) .admin-nav-item { display: none; }
[data-menu="columna"] .admin-side .group.abierto .admin-nav-item {
  display: flex; padding-left: 2.15rem; font-size: .82rem;
}
/* La linea que ata las pantallas a su grupo. Sin ella, al plegar y desplegar no se ve de
   donde salieron los ocho renglones que aparecieron. */
[data-menu="columna"] .admin-side .group.abierto {
  position: relative;
}
[data-menu="columna"] .admin-side .group.abierto::before {
  content: ""; position: absolute; left: 1.13rem; top: 2.1rem; bottom: .2rem;
  width: 1px; background: var(--line-2);
}
/* El contador va a la derecha del todo. Es el hueco que en el diseno del que sale esto
   lleva el codigo de transaccion de SAP; aqui no hay codigos, y el contador si dice algo:
   dice si merece la pena abrir ese modulo. */
[data-menu="columna"] .admin-nav-item .n { margin-left: auto; }

/* En movil manda el menu de arriba y el acordeon no aplica. */
@media (max-width: 820px) {
  [data-menu="columna"] .admin-side .group > h6 { display: none; }
  /* El grupo vuelve a `display: contents`, como en el menu de arriba. Con `block` cada
     modulo era una columna de botones de pantalla alta y la tira ocupaba toda la pantalla
     del telefono (y, fija arriba, tapaba el contenido). Sólo se ven las pantallas del
     módulo abierto; las de los plegados siguen escondidas. */
  [data-menu="columna"] .admin-side .group { display: contents; }
  [data-menu="columna"] .admin-side .group:not(.abierto):not(.collapsed) .admin-nav-item { display: inline-flex; }
  [data-menu="columna"] .admin-side .group.abierto .admin-nav-item { display: inline-flex; }
  [data-menu="columna"] .admin-side .group.abierto::before { display: none; }
  [data-menu="columna"] .admin-side .group.abierto .admin-nav-item { padding-left: .62rem; }
}

/* =========================================================================================
   LAS TABLAS
   =========================================================================================

   Lo que cambia, y por que cada cosa:

   EL ENCABEZADO VA EN BANDA SOLIDA, no en un gris apenas mas oscuro que el cuerpo. Con 44
   tablas en el panel y algunas de cuatrocientos renglones, un encabezado que casi no se
   distingue obliga a mirar dos veces para saber donde empieza el dato. En banda se lee de
   un golpe, y de paso el encabezado pegajoso se ve claramente como lo que es: una cosa
   distinta que se queda quieta mientras lo demas corre por debajo.

   LA TABLA VIVE EN UNA CAJA CON BORDE Y ESQUINAS. Antes flotaba: empezaba y acababa sin
   nada que la delimitara, asi que un listado pegado a un formulario parecian la misma
   cosa.

   LAS COLUMNAS DE CODIGO VAN EN MONOESPACIADA. Una cuenta contable, un RFC, un folio o un
   UUID se leen CARACTER A CARACTER y se comparan con otro de arriba. En proporcional, los
   caracteres angostos juntan unos renglones y separan otros, y dos cuentas que difieren en
   un digito parecen iguales. Es el mismo motivo por el que los importes llevan
   `tabular-nums`.
   ========================================================================================= */

.admin-shell .tabla-odoo thead th {
  background: var(--tabla-cab);
  color: var(--tabla-cab-tinta);
  border-bottom: none;
  font-size: .68rem;
  letter-spacing: .06em;
}
.admin-shell .tabla-odoo thead th.sortable:hover { color: var(--tabla-cab-tinta); opacity: .82; }
/* Las esquinas de la banda, para que no se salgan de la caja. */
.admin-shell .tabla-odoo thead tr th:first-child { border-radius: 9px 0 0 0; }
.admin-shell .tabla-odoo thead tr th:last-child { border-radius: 0 9px 0 0; }

/* La caja. `border-spacing:0` con `border-collapse:separate` es lo que deja que las
   esquinas redondeadas del encabezado se vean: con `collapse` el navegador las ignora. */
/* SIN `overflow: hidden`, y no es un olvido.
 *
 * Era la forma corta de que la banda del encabezado no se saliera de las esquinas
 * redondeadas. Pero `overflow` distinto de `visible` convierte al elemento en contenedor
 * de desplazamiento, y un `position: sticky` de dentro pasa a pegarse A ESA CAJA en vez
 * de a la pantalla: el encabezado se despegaba y bajaba flotando hasta la mitad de la
 * tabla, tapando el segundo renglon. Se veia rarisimo y no daba ningun error.
 *
 * Las esquinas se redondean celda por celda —la primera y la ultima de la primera fila,
 * lo mismo en la ultima—, que es mas verboso y no rompe nada. */
.admin-shell .tabla-odoo {
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
}
.admin-shell .tabla-odoo tbody tr:last-child td:first-child { border-radius: 0 0 0 9px; }
.admin-shell .tabla-odoo tbody tr:last-child td:last-child { border-radius: 0 0 9px 0; }
.admin-shell .tabla-odoo tbody td { border-bottom: 1px solid var(--line); }
.admin-shell .tabla-odoo tbody tr:last-child td { border-bottom: none; }

/* Los codigos: cuentas, folios, RFC, UUID. En el panel ya se escriben dentro de <code>. */
.admin-shell .tabla-odoo td code,
.admin-shell .doc-table td code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: .9em;
  background: none;
  padding: 0;
  color: var(--ink-2);
  white-space: nowrap;
}

/* Y el pequeno detalle que hace que una tabla se lea: la fila bajo el cursor. Ya existia;
   aqui solo se asegura de que gane a la banda del encabezado sin taparla. */
.admin-shell .tabla-odoo tbody tr:hover td { background: var(--realce); }

/* =========================================================================================
   LA CABECERA DE CADA PANTALLA DE MODULO
   =========================================================================================

   166 pantallas abren con la misma pieza —titulo a la izquierda, acciones a la derecha— y
   se veia como un titulo suelto encima de un contenido suelto: nada decia donde empieza la
   pantalla.

   Ahora la cabecera se asienta sobre una banda y se separa con una linea, como en un
   sistema de gestion de verdad. El titulo baja de tamano y sube de peso: en una pantalla de
   trabajo, el titulo compite con la fila de botones que tiene al lado, y lo que hay que
   leer primero es el boton.

   EL CONTADOR SE VUELVE PASTILLA. Ya existia —«Suscripciones 142»— pero iba como texto
   suelto pegado al titulo, del mismo color, y se leia como parte del nombre. En pastilla
   monoespaciada se lee como lo que es: cuantos hay.
   ========================================================================================= */
.admin-shell .tbl-toolbar {
  padding: .7rem .9rem;
  margin-bottom: 1rem;
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: 11px;
}
.admin-shell .tbl-toolbar h3 { font-size: 1.12rem; font-weight: 700; letter-spacing: -.012em; }
/* La primera columna —titulo y contador— se alinea entre si aunque el contador falte. */
.admin-shell .tbl-toolbar > div:first-child {
  display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; min-width: 0;
}

/* Vacio no se pinta. El contador se rellena cuando llega la lista, asi que hasta
   entonces era una pastilla con borde y nada dentro: se leia como un guion suelto pegado
   al titulo, y en 27 pantallas. */
.admin-shell .tbl-count:empty { display: none; }
.admin-shell .tbl-count {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: .72rem; font-weight: 600;
  color: var(--ink-2); background: var(--cream-2);
  border: 1px solid var(--line); border-radius: 99px;
  padding: .06rem .5rem;
  font-variant-numeric: tabular-nums;
}

/* La caja de buscar de la barra: del mismo alto que los botones que tiene al lado. Antes
   heredaba el alto de un campo de formulario y sobresalia medio centimetro por arriba y
   por abajo de la fila. */
.admin-shell .tbl-search {
  font: inherit; font-size: .85rem;
  padding: .36rem .6rem;
  border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); color: var(--ink);
  min-width: 13rem;
}
.admin-shell .tbl-search:focus { outline: none; border-color: var(--red); box-shadow: 0 0 0 2px var(--red-tint); }

/* Los grupos de pestanas dentro de una pantalla —«Suscripciones / Por plan / Cobros por
   mes»—: se aprietan y se meten en una caja, para que se lean como un selector y no como
   tres botones sueltos. */
.admin-shell .toggle-group {
  display: inline-flex; gap: .15rem; padding: .2rem;
  background: var(--cream-2); border: 1px solid var(--line); border-radius: 9px;
}
.admin-shell .toggle-group .toggle {
  border: 0; background: none; font: inherit; font-size: .82rem; font-weight: 600;
  color: var(--muted-2); padding: .3rem .7rem; border-radius: 7px; cursor: pointer;
}
.admin-shell .toggle-group .toggle:hover { color: var(--ink); }
.admin-shell .toggle-group .toggle.on { background: var(--red); color: #fff; }

/* =========================================================================================
   LOS FORMULARIOS DE LOS MODULOS
   ========================================================================================= */

/* ---------- El aviso de arriba ----------

   62 pantallas abren con un parrafo que explica de que va: «Las resenas quedan pendientes
   hasta que las apruebas», «De aqui sale una sola poliza por corrida». Es lo primero que
   hay que leer y lo llevaba la misma clase que las notas al pie de cada campo — mismo
   tamano, mismo gris, misma nada. Asi que no se leia: se saltaba.

   Ahora va en caja, con una marca. No en azul chillon: esto sale en 62 pantallas, y una
   banda de color fuerte repetida sesenta y dos veces deja de significar «leeme» y pasa a
   ser papel pintado. La marca de la izquierda es la que dice que hay algo que leer. */
/* NADA DE `display: grid` AQUI, y es un error que solo se ve mirando.
 *
 * El aviso es un <p> con texto suelto y algun <strong> dentro: «Las resenas quedan
 * <strong>pendientes</strong> hasta que las apruebas». Con grid, cada trozo de texto y
 * cada <strong> se vuelve UNA CELDA propia, asi que la frase se partia en tres pedazos
 * repartidos por la caja. No da error, no rompe nada: solo deja de ser una frase.
 *
 * El icono va colocado por encima con `absolute`, que es lo que hace falta: el texto se
 * queda siendo texto y fluye entero. */
.admin-shell .aviso {
  position: relative;
  margin: 0 0 1.1rem;
  padding: .7rem .9rem .7rem 2.15rem;
  background: var(--cream);
  border: 1px solid var(--line);
  border-left: 3px solid var(--info-tinta);
  border-radius: 0 10px 10px 0;
  font-size: .855rem;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 78ch;
}
.admin-shell .aviso::before {
  content: "";
  position: absolute; left: .82rem; top: .92rem;
  width: 15px; height: 15px;
  background: var(--info-tinta);
  /* El icono como mascara y no como imagen de fondo: asi toma el color del token y sirve
     en los dos temas sin tener que llevar dos archivos. */
  -webkit-mask: var(--ico-info) center / contain no-repeat;
  mask: var(--ico-info) center / contain no-repeat;
}
.admin-shell .aviso strong, .admin-shell .aviso b { color: var(--ink); font-weight: 600; }
.admin-shell .aviso a { color: var(--red-tinta); }

/* ---------- Las secciones de un formulario ----------

   Un alta de empleado son cuatro secciones —quien es, su trabajo, si cobra por tabulador,
   su seguridad social— y cada una se anunciaba con el mismo adorno de marca: una raya roja
   corta. Cuatro rayas rojas en una pantalla dejan de marcar nada.

   Aqui el encabezado de seccion hace lo que tiene que hacer: separar. Una linea que cruza
   el ancho del formulario y el rotulo encima de ella. */
.admin-shell .form > .eyebrow {
  display: block;
  margin: .6rem 0 .1rem;
  padding-bottom: .4rem;
  border-bottom: 1px solid var(--line);
  font-size: .68rem;
  color: var(--muted-2);
}
.admin-shell .form > .eyebrow::before { display: none; }
/* La primera no necesita aire por arriba: ya lo pone la tarjeta. */
.admin-shell .form > .eyebrow:first-child { margin-top: 0; }

/* ---------- La rejilla de campos ----------

   `1fr 1fr` fijo, sin excepcion para pantalla chica: en un telefono de 380px eso son dos
   columnas de 170px con un desplegable dentro. Se desarma cuando ya no caben. */
@media (max-width: 620px) {
  .form .row { grid-template-columns: 1fr; }
}

/* ---------- El pie del formulario ----------

   El boton de guardar iba pegado al ultimo campo, con el mismo hueco que hay entre dos
   campos: se leia como un campo mas. Una linea lo separa y lo convierte en lo que es, el
   final. */
.admin-shell .form > .fila-acc,
.admin-shell .form > button[type="submit"] {
  margin-top: .5rem;
  padding-top: .9rem;
  border-top: 1px solid var(--line);
}
.admin-shell .form > button[type="submit"] { justify-self: start; }

/* ---------- Las casillas ----------

   Una casilla con su texto es UNA cosa, no dos: al ir sueltas, el texto no encendia la
   casilla y habia que apuntar al cuadrito de 13px. */
.admin-shell .fila-chica {
  display: flex; align-items: center; gap: .45rem;
  font-size: .87rem; color: var(--ink-2);
}
.admin-shell label.fila-chica { cursor: pointer; }
.admin-shell .fila-chica input[type="checkbox"],
.admin-shell .fila-chica input[type="radio"] { margin: 0; flex: none; accent-color: var(--red); }

/* ---------- LOS DESPLEGABLES ----------

   El navegador dibuja su propia caja en un `select`: gris, cuadrada, con una flechita
   distinta en cada sistema operativo. Al lado de un campo de texto del panel -redondeado,
   con su borde claro y su anillo de foco rojo- no se parecen en nada, y el formulario
   deja de leerse como una sola cosa.

   Los de dentro de un `.field` ya estaban resueltos. Los SUELTOS no -los de las barras de
   herramientas, los filtros, el de «como se paga esta corrida»-, y son justamente los que
   se ven en medio de una pantalla llena, sin un campo al lado que los disimule.

   La flecha va en gris medio a proposito: es el unico color que se lee igual sobre el
   fondo claro y sobre el oscuro sin tener que dibujarla dos veces. */
.admin-shell select {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  font: inherit; font-size: .87rem;
  padding: .42rem 1.9rem .42rem .6rem;
  border: 1px solid var(--line-2); border-radius: 8px;
  background-color: var(--surface); color: var(--ink);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23908981' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .6rem center;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.admin-shell select:hover { border-color: var(--muted-2); }
.admin-shell select:focus {
  outline: none; border-color: var(--red);
  box-shadow: 0 0 0 2px var(--red-tint);
}
.admin-shell select:disabled { opacity: .55; cursor: default; }
/* Los de dentro de un campo mantienen su alto, que va con el del input de al lado. */
.admin-shell .field select { padding: .48rem 1.9rem .48rem .6rem; font-size: .89rem; }
/* Y la barra de un reporte tiene los suyos mas bajos por su cuenta. */
.admin-shell .rep__barra select { padding-top: 0; padding-bottom: 0; }

/* ---------- UNA BARRA DE CONTROL SOBRE UNA TABLA ----------

   Un `select` suelto en medio de la pagina, con una etiqueta a un lado y una nota al
   otro, se lee como tres cosas sueltas puestas en fila. Metido en una tira con fondo
   propio se lee como lo que es: un control que manda sobre la tabla de debajo. */
.admin-shell .barra-ctrl {
  display: flex; align-items: center; flex-wrap: wrap; gap: .5rem .8rem;
  padding: .55rem .75rem;
  background: var(--realce);
  border: 1px solid var(--line); border-radius: 10px;
}
.admin-shell .barra-ctrl > label {
  font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); margin: 0;
}
.admin-shell .barra-ctrl .form__note { flex: 1 1 14rem; margin: 0; font-size: .78rem; }

/* ---------- COMO SE LE PAGA A CADA QUIEN ----------

   Iba como texto corrido y se partia en tres renglones -«Transferencia / electronica /
   sin cuenta»-, que en una tabla de cuatrocientas filas es lo que hace que una columna
   deje de poder leerse de un vistazo.

   Va en una pastilla que NO SE PARTE, con un punto de color delante. Y el color dice
   algo: el efectivo va en ambar porque casi siempre significa que a esa persona le falta
   la CLABE, que es justo la fila que hay que mirar antes de timbrar. */
.paga {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .12rem .5rem .12rem .42rem;
  border: 1px solid var(--line-2); border-radius: 999px;
  background: var(--surface);
  font-size: .78rem; line-height: 1.55; white-space: nowrap;
}
.paga::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--muted); flex: none;
}
.paga--banco::before   { background: var(--ok-tinta); }
.paga--efectivo::before { background: var(--aviso-tinta); }
.paga--vale::before    { background: var(--info-tinta); }
.paga--nada { color: var(--muted); border-style: dashed; }
.paga--nada::before { display: none; }
/* DE QUIEN ES LA DECISION. Una forma de pago que viene de la ficha de una persona no la
   cambia el selector de arriba; sin decirlo, quien lo mueva esperara que cambie toda la
   columna y creera que el selector no funciona. */
.paga__ficha { font-weight: 700; color: var(--aviso-tinta); }

/* ---------- LA BARRA DE ACCIONES ----------

   Once botones iguales repartidos en dos o tres filas no son un menu: son una pared, y
   quien la mira tiene que leerla entera cada vez para encontrar la que toca -que casi
   siempre es UNA-.

   Aqui el orden significa algo: primero EL PASO QUE TOCA -en rojo-, despues lo que se usa
   en cada corrida, y el resto en «Mas». Y CABE EN UNA FILA, que no es estetica: la
   segunda fila empuja la tabla fuera de la pantalla, y la tabla es lo que hay que mirar
   antes de emitir cuatrocientos comprobantes. */
.admin-shell .barra-acc {
  display: flex; align-items: center; flex-wrap: wrap; gap: .45rem;
}
/* El de «Mas» se va al final de la fila: es el cajon, no una accion mas. */
.admin-shell .barra-acc .mas { position: relative; margin-left: auto; }

/* El cajon. Se abre por encima de todo lo demas, asi que necesita salirse de la barra:
   dentro del flujo empujaria la tabla hacia abajo cada vez que se abre. */
.admin-shell .mas__panel {
  position: absolute; right: 0; top: calc(100% + .35rem); z-index: 40;
  min-width: 15rem; padding: .35rem 0;
  background: var(--tarjeta); border: 1px solid var(--line-2); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.14);
}
.admin-shell .mas__titulo {
  font-size: .66rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); padding: .5rem .8rem .25rem;
}
/* Los titulos no son adorno: sin ellos son ocho renglones seguidos y hay que leerlos
   todos igual que antes. El primero no lleva linea encima porque no separa nada. */
.admin-shell .mas__titulo + .mas__titulo,
.admin-shell .mas__item + .mas__titulo { border-top: 1px solid var(--line); margin-top: .3rem; }
.admin-shell .mas__item {
  display: block; width: 100%; text-align: left;
  font: inherit; font-size: .86rem; color: var(--ink);
  background: none; border: 0; padding: .45rem .8rem; cursor: pointer;
}
.admin-shell .mas__item:hover { background: var(--realce); }
.admin-shell .mas__item:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }

/* ---------- UN CUADRO CON MUCHOS CAMPOS CORTOS ----------

   Doce campos numericos, uno por fila y del ancho de la pantalla, para escribir un «2»:
   hay que desplazarse para ver lo que cabria de un vistazo, y el tamanio de la caja
   promete un dato largo que no existe. La caja tiene que decir cuanto se espera dentro.

   `auto-fit` con un minimo, y no un numero fijo de columnas: en un movil cae a una y en
   una pantalla ancha reparte cuatro, sin una consulta de medios por cada caso. */
.pm-body--rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: .5rem .9rem;
  align-items: start;
}
/* Las notas y los titulos son separaciones, no campos: ocupan la fila entera. */
.pm-body--rejilla > .form__note,
.pm-body--rejilla > .pm-grupo { grid-column: 1 / -1; }
.pm-body--rejilla .field { margin: 0; }
.pm-body--rejilla .field label { font-size: .78rem; }
.pm-body--rejilla .field input { padding: .42rem .55rem; font-size: .88rem; }

/* El titulo de cada grupo. Con doce campos seguidos hay que leerlos todos para encontrar
   el que se viene a cambiar; agrupados se va directo al grupo. */
.pm-grupo {
  font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
  margin: .7rem 0 -.1rem;
  padding-top: .7rem;
  border-top: 1px solid var(--line);
}
/* El primero no lleva linea encima: no separa nada de nada. */
.pm-body--rejilla > .pm-grupo:first-of-type { margin-top: .2rem; padding-top: 0; border-top: 0; }

/* Y la caja se ensancha, porque ahora cabe mas en cada fila. */
.pm-caja--ancha { max-width: min(46rem, 94vw); }

/* ---------- LA ULTIMA COLUMNA SE QUEDA A LA VISTA ----------

   La tabla de una corrida tiene catorce columnas -dias, SD, SBC, gravado, exento, ISR,
   IMSS, otros, percepciones, neto, como se le paga, folio fiscal- y no cabe. Eso no seria
   grave si lo que se corta fuera un numero mas: lo que se corta son los BOTONES, y
   entonces «Recibo» y «Editar» dejan de existir para quien mira.

   No se ve como una tabla ancha, se ve como una pantalla incompleta: el desplazamiento
   horizontal esta abajo del todo, fuera de la vista, y nadie lo busca.

   La ultima columna se pega a la derecha y viaja con el desplazamiento. Se le pone fondo
   propio -si no, el texto de las columnas de abajo se le transparenta encima- y una linea
   a la izquierda, que es lo que dice que ahi hay mas tabla debajo. */
.admin-shell .tabla-scroll { position: relative; }
.admin-shell .tabla-scroll > .tabla-odoo th:last-child,
.admin-shell .tabla-scroll > .tabla-odoo td:last-child {
  position: sticky; right: 0; z-index: 3;
  background: var(--tarjeta);
  border-left: 1px solid var(--line-2);
}
/* El encabezado de esa columna se pega en las dos direcciones a la vez, asi que necesita
   quedar por encima del resto del encabezado, que ya es pegajoso por su cuenta. */
.admin-shell .tabla-scroll > .tabla-odoo thead th:last-child {
  z-index: 5; background: var(--tabla-cab); color: var(--tabla-cab-tinta);
}
/* Y la de las casillas, a la izquierda: marcar a alguien despues de desplazarse a la
   derecha obligaba a volver para encontrar su fila. */
.admin-shell .tabla-scroll > .tabla-odoo th.col-check,
.admin-shell .tabla-scroll > .tabla-odoo td.col-check {
  position: sticky; left: 0; z-index: 3;
  background: var(--tarjeta);
  border-right: 1px solid var(--line-2);
}
.admin-shell .tabla-scroll > .tabla-odoo thead th.col-check {
  z-index: 5; background: var(--tabla-cab);
}

/* ---------- EL ENCABEZADO DE UNA CORRIDA SE QUEDA ----------

   Una corrida son cuatrocientas filas de numeros. Al tercer desplazamiento ya no se sabe
   si la columna que se esta leyendo es el ISR o el IMSS, y para averiguarlo hay que subir
   hasta el encabezado -perdiendo de vista la fila de la persona- y volver a bajar.

   SE PEGA AL BORDE DE SU PROPIA CAJA, NO A LA VENTANA. Lo intente con `top: var(--techo)`
   y salia MAL: `--techo` mide la barra de arriba, pero entre esa barra y la tabla hay dos
   bandas mas -la cuenta con la que se paga y como se paga- que si se van al desplazar.
   El encabezado se quedaba clavado a media pantalla, con filas por encima y por debajo, y
   eso se ve peor que no tenerlo: parece que la tabla se partio en dos.

   Con la tabla en su propia caja de alto limitado no hay nada que calcular: el
   encabezado se para en el borde de la caja, que es un sitio que siempre existe, y las
   filas corren por debajo. Setenta por ciento del alto de la ventana deja ver el
   encabezado, unas quince filas y el final de la pagina a la vez. */
.admin-shell #nmcRecibos > .tabla-wrap {
  max-height: 70vh;
  overflow: auto;
}
.admin-shell #nmcRecibos .tabla-odoo thead th {
  position: sticky;
  top: 0;
  z-index: 4;
}
/* Las dos columnas pegadas a los lados necesitan quedar por encima del encabezado en su
   cruce, o el texto de una se ve a traves de la otra. */
.admin-shell #nmcRecibos .tabla-odoo thead th:last-child,
.admin-shell #nmcRecibos .tabla-odoo thead th.col-check { z-index: 6; }
.admin-shell #nmcRecibos .tabla-odoo td:last-child,
.admin-shell #nmcRecibos .tabla-odoo td.col-check { z-index: 3; }
}

/* ===== A QUE CUENTA VA CADA COSA (polizas automaticas) =====
 * Cincuenta y ocho cuentas. En una columna a lo ancho de la pantalla habria que bajar
 * cincuenta y ocho veces para encontrar la que se viene a cambiar, y cada caja mediria
 * media pantalla para escribir «601-001». */
.pca-bloque { margin-bottom: 1rem; }
.pca-grupo { margin-top: .9rem; }
.pca-grupo h5 { margin: 0 0 .45rem; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-2); font-weight: 600; }
.pca-rej { display: grid; gap: .5rem .9rem;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.pca-campo { display: flex; flex-direction: column; gap: .12rem; min-width: 0; }
.pca-campo__t { font-size: .82rem; color: var(--ink); line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pca-campo input { width: 100%; padding: .32rem .5rem; font-size: .84rem;
  font-variant-numeric: tabular-nums; }
/* La de fabrica SIEMPRE visible: una caja con un numero dentro no dice si ese numero lo
 * puso alguien o venia puesto, y esa diferencia es justo lo que se viene a mirar. */
.pca-campo__f { font-size: .68rem; color: var(--ink-3, var(--ink-2)); line-height: 1.2; }
.pca-campo__n { font-size: .74rem; color: var(--ink-2, inherit); line-height: 1.25; min-height: 1em; }
.pca-campo__n--mal { color: var(--danger, #b42318); }
.pca-campo--propia .pca-campo__t::after { content: ' \2022'; color: var(--brand, #1f6feb); }
.pca-campo--propia input { border-color: var(--brand, #1f6feb); }
.pca-campo--propia .pca-campo__f { color: var(--brand, #1f6feb); }

/* ===== LA REPRESENTACIÓN IMPRESA DE UN CFDI =====
 *
 * El comprobante es el XML; esto es el papel. El SAT obliga a que lleve el folio fiscal,
 * los dos números de certificado, los dos sellos, la cadena original del timbre y el QR,
 * y todo eso son cadenas de cuatrocientos caracteres: en una línea corrida se salen de la
 * hoja, y lo que se sale de la hoja al imprimir no existe. */
.doc-fiscal {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: .45rem 1.2rem; margin: 1rem 0;
  padding: .7rem .85rem; border: 1px solid var(--doc-raya); border-radius: 6px;
}
.doc-fiscal div { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.doc-fiscal span { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--doc-apagado); }
.doc-fiscal b { font-size: .86rem; font-variant-numeric: tabular-nums; word-break: break-word; }

/* Emisor y receptor uno al lado del otro: es la primera comparación que hace quien mira
 * un comprobante, y en dos bloques seguidos hay que subir y bajar para hacerla. */
.doc-dos { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; }
@media (max-width: 560px) { .doc-dos { grid-template-columns: 1fr; } }

.doc-sellos { margin-top: 1.4rem; border-top: 1px solid var(--doc-raya); padding-top: .9rem; }
.doc-sellos h6 {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--doc-apagado); margin: .8rem 0 .25rem; font-weight: 600;
}
/* `break-all` y no `break-word`: un sello es un solo «palabra» de cuatrocientos
 * caracteres sin un hueco donde partirlo, así que sin esto sale una línea que se escapa
 * de la hoja. Y en monoespaciada porque lo que se hace con esto es COMPARARLO carácter a
 * carácter contra el del XML. */
.doc-sellos pre {
  margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .58rem; line-height: 1.35; white-space: pre-wrap; word-break: break-all;
  color: var(--doc-tinta-2, var(--doc-apagado));
}
/* El QR va arriba, junto al folio: es por donde se comprueba el papel, y escondido al pie
 * en dos centímetros no lo enfoca ningún teléfono. */
.doc-head .meta svg { display: inline-block; border: 1px solid var(--doc-raya); border-radius: 4px; }

/* ===== UNA TABLA QUE SE CAPTURA COMO UNA TABLA =====
 * La tarifa del ISR, la prima quinquenal, las fuentes de financiamiento. Se capturaban
 * escribiendo su JSON en una caja de texto, y una coma de más tiraba el ajuste entero sin
 * decirlo. Las celdas van apretadas a propósito: son números cortos, y una caja del ancho
 * de la pantalla para escribir «1.92» promete un dato largo que no existe. */
.te-tabla td { padding: .2rem .25rem; }
.te-tabla th { padding: .4rem .35rem; white-space: nowrap; }
.te-tabla input {
  width: 100%; min-width: 5.5rem; padding: .3rem .45rem; font-size: .85rem;
  font-variant-numeric: tabular-nums;
}
/* Los números a la derecha, como en cualquier tabla de importes: el 1 no puede quedar más
   angosto que el 8 o las columnas dejan de poder compararse de un vistazo. */
.te-tabla input.num { text-align: right; }
.te-suf { color: var(--ink-3, var(--ink-2)); font-weight: 400; }

/* De qué empresa es el registro patronal que se está capturando. Va pegado a la etiqueta
   y no en una nota debajo: es una aclaración sobre ESE campo, y una nota más en una
   pantalla que ya tiene treinta no la lee nadie. */
.rp-de { font-weight: 400; font-size: .8rem; color: var(--brand, #1f6feb); }

/* Un KPI sobre el que hay que HACER algo —lo que falta por facturar— no puede pintarse
   igual que los demás: se lee como un dato más y no lo mira nadie. */
.kpi--mal .kpi__value { color: var(--red, #C1272D); }
.kpi--mal { border-color: color-mix(in srgb, var(--red, #C1272D) 35%, transparent); }

/* ===== LA FICHA DE UNA VENTA (pedido o factura) =====
   Al abrir un documento: arriba el camino de la venta y lo que se puede hacer; a la
   izquierda el documento, sus cobros y lo que ampara; a la derecha su historial. En
   pantalla angosta el historial baja, no se aprieta. */
.ficha-cab { display: flex; flex-wrap: wrap; gap: .6rem 1rem; align-items: center; justify-content: space-between; margin: 0 0 .9rem; }
.ficha-cab h2 { margin: 0; font-size: 1.5rem; }
.ficha-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 1rem; align-items: start; }
@media (max-width: 1100px) { .ficha-grid { grid-template-columns: minmax(0, 1fr); } }
.ficha-caja { background: var(--tarjeta); border: 1px solid var(--line); border-radius: 14px; padding: 1rem 1.1rem; margin: 0 0 1rem; min-width: 0; }
.ficha-caja h4 { margin: 0 0 .6rem; font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.ficha-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .5rem 1.2rem; }
.ficha-datos div span { display: block; font-size: .75rem; color: var(--muted); }

/* El camino: cada paso hecho, el actual o el que falta. Cancelada lo corta en rojo. */
.camino { display: flex; flex-wrap: wrap; gap: 0; margin: 0 0 1rem; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--tarjeta); }
.camino-paso { flex: 1 1 140px; padding: .55rem .8rem; border-right: 1px solid var(--line); color: var(--muted); min-width: 0; }
.camino-paso:last-child { border-right: 0; }
.camino-paso b { display: block; font-size: .85rem; }
.camino-paso small { display: block; font-size: .75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.camino-paso.hecho { color: var(--ok-tinta); background: var(--ok-fondo); }
.camino-paso.actual { color: var(--ink); background: var(--aviso-fondo); box-shadow: inset 0 -3px 0 var(--aviso-tinta); }
.camino-paso.cancelado { color: var(--mal-tinta); background: var(--mal-fondo); }

/* El historial: lo más reciente arriba, con quién lo hizo. */
.historial { list-style: none; margin: 0; padding: 0; }
.historial-item { position: relative; padding: 0 0 .8rem 1rem; border-left: 2px solid var(--line); margin-left: .3rem; font-size: .85rem; }
.historial-item::before { content: ''; position: absolute; left: -6px; top: .2rem; width: 10px; height: 10px; border-radius: 50%; background: var(--line-2); }
.historial-item.error::before { background: var(--mal-tinta); }
.historial-item small { display: block; color: var(--muted); font-size: .75rem; }

/* Las hojas del SAT en Impuestos: menu de regimenes y formulario, como en el SAT. */
.hojas-sat { display: grid; grid-template-columns: 260px 1fr; min-height: 420px; }
.hs-menu { border-right: 1px solid var(--line); padding: .4rem 0; }
.hs-menu button { display: block; width: 100%; text-align: left; padding: .55rem 1rem; background: none; border: 0;
  color: inherit; font: inherit; font-size: .9rem; cursor: pointer; border-left: 3px solid transparent; }
.hs-menu button:hover { background: var(--realce); }
.hs-menu button[aria-current="true"] { background: var(--realce); border-left-color: var(--red); font-weight: 600; }
.hs-grupo { font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); padding: .9rem 1rem .3rem;
  border-top: 1px solid var(--line); margin-top: .3rem; }
.hs-tuyo { font-size: .68rem; color: var(--red-tinta); font-weight: 600; margin-left: .3rem; }
.hs-cont { padding: 1rem 1.15rem; min-width: 0; }
.hs-cab { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; margin-bottom: .8rem; flex-wrap: wrap; }
.hs-tabla td.r, .hs-tabla th.r { text-align: right; }
.hs-tabla th:nth-child(2), .hs-tabla td:nth-child(2), .hs-tabla th:nth-child(3), .hs-tabla td:nth-child(3) { width: 24%; white-space: nowrap; }
.hs-tabla input { width: 100%; max-width: 12rem; text-align: right; }
.hs-tabla .hs-fuerte td { font-weight: 600; }
.hs-calc { font-variant-numeric: tabular-nums; }
.hs-cont .tabla-odoo td:not(:first-child) { white-space: nowrap; }
.hs-dif { color: var(--red-tinta); font-weight: 600; }
.hs-avisos { margin: 0 0 .8rem; padding-left: 1.1rem; color: var(--muted); font-size: .85rem; }
@media (max-width: 760px) {
  .hojas-sat { grid-template-columns: 1fr; }
  .hs-menu { border-right: 0; border-bottom: 1px solid var(--line); max-height: 14rem; overflow: auto; }
}

/* ===================== IMPLEMENTACIÓN Y SERVICIOS (/implementacion) =====================
 * Lo que se contrata además del sistema: horas de asistencia, horas de implementación
 * especial y maquila de nómina. Va en su propia página y no en los planes de la portada:
 * no son lo que cuesta usar Kern, son ayuda opcional. */
.svc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; margin-top: 2.6rem; align-items: stretch; }
.svc { position: relative; display: flex; flex-direction: column; gap: .7rem; padding: 2rem 1.7rem 1.8rem; border: 1px solid var(--line); border-radius: 18px; background: var(--surface); transition: transform .2s, box-shadow .2s; }
.svc:hover { transform: translateY(-3px); box-shadow: 0 16px 40px rgba(27,23,20,.08); }
.svc--destacado { border-color: var(--red); box-shadow: 0 18px 48px rgba(var(--red-rgb),.14); }
.svc__tag { position: absolute; top: -12px; left: 1.7rem; background: var(--red); color: #fff; font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; padding: .3rem .75rem; border-radius: 999px; }
.svc__icono { width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; background: var(--red-tint); color: var(--red-tinta); }
.svc__icono svg { width: 24px; height: 24px; }
.svc h3 { font-size: 1.25rem; margin: .2rem 0 0; }
.svc__que { color: var(--muted); margin: 0; }
.svc__precio { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; margin: .4rem 0 .2rem; padding-bottom: .9rem; border-bottom: 1px dashed var(--line); }
.svc__precio span { font-family: var(--font-display); font-size: 2.4rem; font-weight: 700; color: var(--ink); line-height: 1; }
.svc__precio small { color: var(--muted); font-size: .9rem; }
.svc__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; flex: 1; }
.svc__lista li { position: relative; padding-left: 1.5rem; color: var(--ink-2); }
.svc__lista li::before { content: ""; position: absolute; left: 0; top: .5em; width: .7rem; height: .4rem; border-left: 2px solid var(--red-tinta); border-bottom: 2px solid var(--red-tinta); transform: rotate(-45deg); }
.svc__ideal { margin: .6rem 0 0; padding: .7rem .9rem; border-radius: 10px; background: var(--cream); color: var(--ink-2); font-size: .9rem; }
.svc__pie { text-align: center; color: var(--muted); margin: 1.8rem auto 0; max-width: 720px; }
.horas { max-width: 780px; margin: 2.2rem auto 0; border: 1px solid var(--line); border-radius: 16px; overflow: hidden; background: var(--surface); }
.horas__fila { display: flex; justify-content: space-between; gap: 1.2rem; align-items: center; padding: 1rem 1.3rem; border-top: 1px solid var(--line); }
.horas__fila:first-child { border-top: none; }
.horas__fila b { white-space: nowrap; color: var(--red-tinta); }
.svc-cta { display: flex; justify-content: space-between; align-items: center; gap: 1.5rem; flex-wrap: wrap; padding: 2.2rem 2.4rem; border-radius: 20px; background: var(--ink-band, #1B1714); color: #F2EAE0; }
.svc-cta h2 { color: #F2EAE0; margin: 0 0 .4rem; }
.svc-cta p { color: #CFC4B6; margin: 0; }
/* En la portada: la franja que lleva a esta página. */
.svc-banda { display: flex; justify-content: space-between; align-items: center; gap: 1.2rem; flex-wrap: wrap; margin: 2.2rem auto 0; padding: 1.3rem 1.6rem; border: 1px dashed var(--line-2, var(--line)); border-radius: 16px; background: var(--cream); }
.svc-banda p { margin: 0; color: var(--ink-2); }
@media (max-width: 900px) { .svc-grid { grid-template-columns: 1fr; } .horas__fila { flex-direction: column; align-items: flex-start; } .svc-cta { padding: 1.6rem; } }

/* ===== Organigrama (panel de nómina) =====
 * Árbol con listas anidadas y conectores de CSS puro: sin librerías. El lienzo es el
 * que se desplaza a lo ancho; la página nunca. El zoom usa `zoom` y no `transform`,
 * porque `zoom` sí cambia el tamaño que ocupa y el desplazamiento sigue cuadrando. */
.org-zoom { gap: .4rem; align-items: center; margin-bottom: .5rem; flex-wrap: wrap; }
.org-zoom span { min-width: 3.2rem; text-align: center; font-size: .85rem; color: var(--muted); }
.org-lienzo { max-width: 100%; overflow: auto; background: var(--cream); border: 1px solid var(--line);
  border-radius: 14px; padding: 1.2rem .6rem; max-height: 75vh; -webkit-overflow-scrolling: touch; }
.org-arbol { display: flex; flex-direction: column; align-items: center; gap: 1.6rem; width: max-content; min-width: 100%; }
.org-arbol ul { display: flex; justify-content: center; padding: 1.1rem 0 0; margin: 0; position: relative; list-style: none; }
.org-arbol ul.org-raiz { padding-top: 0; }
.org-arbol li { display: flex; flex-direction: column; align-items: center; position: relative; padding: 1.1rem .4rem 0; }
.org-arbol ul.org-raiz > li { padding-top: 0; }
/* Los conectores: una raya horizontal sobre cada hermano y una vertical hacia su caja. */
.org-arbol li::before, .org-arbol li::after { content: ''; position: absolute; top: 0; width: 50%; height: 1.1rem; border-top: 2px solid var(--line-2); }
.org-arbol li::before { right: 50%; }
.org-arbol li::after { left: 50%; border-left: 2px solid var(--line-2); }
.org-arbol li:first-child::before, .org-arbol li:last-child::after { border-top: 0; }
.org-arbol li:only-child::before { display: none; }
.org-arbol li:only-child::after { border-top: 0; }
.org-arbol li:first-child::after { border-top-left-radius: 8px; }
.org-arbol li:last-child::before { border-right: 2px solid var(--line-2); border-top-right-radius: 8px; }
.org-arbol ul.org-raiz > li::before, .org-arbol ul.org-raiz > li::after { display: none; }
/* Y la vertical que baja de la caja del jefe hacia sus hijos. */
.org-arbol li > ul::before { content: ''; position: absolute; top: 0; left: 50%; height: 1.1rem; border-left: 2px solid var(--line-2); }
.org-caja { position: relative; display: flex; flex-direction: column; gap: .1rem; min-width: 9.5rem; max-width: 13rem;
  padding: .6rem .8rem .7rem; background: var(--tarjeta); border: 1px solid var(--line-2); border-top: 3px solid var(--red);
  border-radius: 10px; box-shadow: var(--shadow-sm); text-align: center; }
.org-nombre { font-weight: 600; color: var(--ink); font-size: .9rem; line-height: 1.2; }
.org-puesto { color: var(--ink-2); font-size: .8rem; line-height: 1.25; }
.org-depto { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; }
.org-nota { color: var(--aviso-tinta); font-size: .72rem; }
.org-caja--vacante { background: transparent; border: 2px dashed var(--aviso-tinta); border-top-width: 2px; box-shadow: none; }
.org-caja--vacante .org-nombre { color: var(--aviso-tinta); }
.org-caja--ciclo { border-color: var(--mal-tinta); border-top-color: var(--mal-tinta); background: var(--mal-fondo); }
.org-toggle { position: absolute; left: 50%; bottom: -.8rem; transform: translateX(-50%); z-index: 1; min-width: 1.6rem; height: 1.6rem;
  padding: 0 .35rem; border-radius: 999px; border: 1px solid var(--line-2); background: var(--surface); color: var(--ink-2);
  font: 600 .75rem/1 var(--font-sans); cursor: pointer; }
.org-toggle:hover { background: var(--realce); }
.org-caja:has(.org-toggle) { margin-bottom: .5rem; }
@media (max-width: 640px) {
  .org-caja { min-width: 7.5rem; max-width: 10rem; padding: .5rem .55rem .6rem; }
  .org-lienzo { max-height: 65vh; }
}
/* La hoja impresa: se abre aparte (orgImprimir) y va en papel blanco y apaisado. */
.org-impresion { background: #fff; color: #111; padding: 1rem; }
.org-impresion__titulo { font-family: var(--font-display); font-size: 1.4rem; margin: 0 0 .2rem; }
.org-impresion__fecha { color: #555; font-size: .85rem; margin: 0 0 1rem; }
.org-impresion .org-toggle { display: none; }
.org-impresion .org-caja { box-shadow: none; break-inside: avoid; }
/* Página con nombre: un `@page { size: landscape }` suelto se aplicaba a TODO lo que se
   imprime en el sitio (pólizas, manual, cotizaciones) y los ponía apaisados. */
@page organigrama { size: landscape; margin: 10mm; }
@media print {
  .org-impresion { page: organigrama; }
  .org-impresion { padding: 0; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
/* ===== Combo con búsqueda (comboBusca en admin.js) =====
   Una caja de texto con su lista debajo. La lista flota sobre lo que sigue y se
   desplaza sola; en un teléfono las opciones miden lo que un dedo. */
.combo { position: relative; width: 100%; }
.combo > input { width: 100%; }
.combo__lista { position: absolute; z-index: 60; left: 0; top: calc(100% + 4px);
  width: max(100%, min(26rem, calc(100vw - 2.5rem)));
  margin: 0; padding: .25rem; list-style: none; max-height: min(320px, 50vh); overflow-y: auto;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line-2, var(--line));
  border-radius: var(--r-sm); box-shadow: var(--shadow); text-align: left; }
.combo__lista li { padding: .5rem .65rem; border-radius: 8px; cursor: pointer; line-height: 1.3;
  display: flex; flex-direction: column; gap: .1rem; min-height: 40px; justify-content: center; }
.combo__lista li:hover, .combo__lista li.is-activo { background: var(--realce); }
.combo__l { font-size: .92rem; overflow-wrap: anywhere; }
.combo__d { font-size: .78rem; color: var(--muted); }
.combo__lista li.combo__vacio { cursor: default; color: var(--muted); font-size: .85rem; }
.combo__lista li.combo__vacio:hover { background: none; }
.combo-nota { display: block; margin-top: .25rem; font-size: .76rem; color: var(--muted); }
/* El botón de actualizar de la pestaña activa: gira al pasar encima. */
.wstab__r { font-size: .95rem; }
.wstab__r:hover { transform: rotate(90deg); transition: transform .2s; background: var(--cream-2, var(--line)); color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .wstab__r:hover { transform: none; } }
/* ============================================================================ *  TABLERO CONTABLE ESTILO BI (admin.js: loadContabilidad)
 *  Series validadas con el validador de paletas (CVD y contraste) en claro y oscuro:
 *  azul = ingresos/entradas, naranja = egresos/salidas, aqua = utilidad/IVA a pagar,
 *  violeta = saldo. El texto nunca va del color de la serie: usa las tintas del panel.
 * =================================================================================== */
:root { --bi-1: #2a78d6; --bi-2: #eb6834; --bi-3: #1baf7a; --bi-4: #4a3aa7; --bi-ref: #8C847B; }
:root[data-theme="dark"] { --bi-1: #3987e5; --bi-2: #d95926; --bi-3: #199e70; --bi-4: #9085e9; --bi-ref: #968B7E; }
.bi { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.bi-cab { display: flex; justify-content: space-between; align-items: flex-end; gap: .6rem; flex-wrap: wrap; }
.bi-filtros { position: sticky; top: var(--techo, 58px); z-index: 20; display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem 1rem;
  padding: .65rem .8rem; background: var(--tarjeta); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-sm); }
.bi-f { display: flex; flex-direction: column; gap: .2rem; font-size: .72rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin: 0; min-width: 0; }
.bi-f select, .bi-f input { font-size: .88rem; text-transform: none; letter-spacing: 0; max-width: 220px; }
.bi-f__par { display: flex; gap: .3rem; flex-wrap: wrap; }
.bi-f__par input { max-width: 150px; }
.bi-f__fijo { font-size: .9rem; color: var(--ink); text-transform: none; letter-spacing: 0; padding: .35rem 0; }
.bi-chk { display: flex; align-items: center; gap: .4rem; font-size: .86rem; color: var(--ink-2); margin: 0 0 .35rem; }
.bi-chip { display: inline-flex; align-items: center; gap: .4rem; border: 1px solid var(--bi-1); color: var(--ink); background: var(--info-fondo);
  border-radius: 999px; padding: .3rem .75rem; font-size: .84rem; font-weight: 600; cursor: pointer; margin-bottom: .25rem; }
.bi-chip span { font-size: 1.05rem; line-height: 1; }
.bi-pend { border: 1px solid var(--line); border-left: 3px solid var(--mal-tinta); border-radius: 12px; background: var(--tarjeta); padding: .6rem .9rem; display: flex; flex-direction: column; gap: .15rem; }
.bi-pend__i { display: flex; justify-content: space-between; gap: 1rem; background: none; border: 0; padding: .3rem 0; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.bi-pend__i b { color: var(--mal-tinta); white-space: nowrap; }
.bi-kpis { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr)); gap: .75rem; }
/* En el teléfono: dos tarjetas por renglón y la barra de filtros deja de pegarse, que
   si no se come media pantalla al bajar. */
@media (max-width: 600px) {
  .bi-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
  .bi-kpi { padding: .6rem .65rem; }
  .bi-kpi__v { font-size: 1.1rem; }
  .bi-filtros { position: static; }
}
.bi-kpi { display: grid; grid-template-rows: auto auto auto 28px; gap: .25rem; min-width: 0; text-align: left; font: inherit; color: inherit;
  background: var(--tarjeta); border: 1px solid var(--line); border-radius: 12px; padding: .8rem .9rem .7rem; }
button.bi-kpi { cursor: pointer; }
button.bi-kpi:hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); }
.bi-kpi__l { font-size: .74rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.bi-kpi__v { font-size: 1.45rem; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.15; overflow-wrap: anywhere; }
.bi-neg { color: var(--mal-tinta); }
.bi-kpi__var { display: flex; gap: .45rem; align-items: baseline; flex-wrap: wrap; font-size: .78rem; min-height: 1.1em; }
.bi-var { font-weight: 600; }
.bi-var-b { color: var(--ok-tinta); }
.bi-var-m { color: var(--mal-tinta); }
.bi-var-n { color: var(--muted); font-weight: 500; }
.bi-var__ant { color: var(--muted); }
.bi-spark { width: 100%; height: 28px; display: block; }
.bi-spark polyline { fill: none; stroke: var(--bi-1); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.bi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: .9rem; }
.bi-card { display: flex; flex-direction: column; min-width: 0; background: var(--tarjeta); border: 1px solid var(--line); border-radius: 12px; padding: .9rem 1rem; }
.bi-w2 { grid-column: span 2; }
@media (max-width: 760px) { .bi-w2 { grid-column: auto; } }
.bi-card header h3 { font-family: var(--font-sans); font-size: .98rem; font-weight: 700; margin: 0; color: var(--ink); }
.bi-card header p { font-size: .78rem; color: var(--muted); margin: .15rem 0 .5rem; }
.bi-card__cuerpo { flex: 1; min-width: 0; }
.bi-graf { width: 100%; min-width: 0; overflow: hidden; }
.bi-svg { display: block; max-width: 100%; }
.bi-eje { font-size: 11px; fill: var(--muted); font-variant-numeric: tabular-nums; }
.bi-rej { stroke: var(--line); stroke-width: 1; }
.bi-cero { stroke: var(--muted); stroke-width: 1.2; }
.bi-foco-banda { fill: var(--info-fondo); }
.bi-hit { fill: transparent; }
.bi-hit[data-bimes] { cursor: pointer; }
.bi-hit:hover, .bi-hit:focus { fill: rgba(128,128,128,.10); outline: none; }
.bi-f-s1 { fill: var(--bi-1); background: var(--bi-1); }
.bi-f-s2 { fill: var(--bi-2); background: var(--bi-2); }
.bi-f-s3 { fill: var(--bi-3); background: var(--bi-3); }
.bi-f-s4 { fill: var(--bi-4); background: var(--bi-4); }
.bi-l-s1, .bi-l-s2, .bi-l-s3, .bi-l-s4, .bi-l-ref { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.bi-l-s1 { stroke: var(--bi-1); }
.bi-l-s2 { stroke: var(--bi-2); }
.bi-l-s3 { stroke: var(--bi-3); }
.bi-l-s4 { stroke: var(--bi-4); }
.bi-l-ref { stroke: var(--bi-ref); }
.bi-punteada { stroke-dasharray: 5 4; }
.bi-p-s1, .bi-p-s2, .bi-p-s3, .bi-p-s4, .bi-p-ref { stroke: var(--tarjeta); stroke-width: 2; }
.bi-p-s1 { fill: var(--bi-1); }
.bi-p-s2 { fill: var(--bi-2); }
.bi-p-s3 { fill: var(--bi-3); }
.bi-p-s4 { fill: var(--bi-4); }
.bi-p-ref { fill: var(--bi-ref); }
.bi-leyenda { display: flex; flex-wrap: wrap; gap: .3rem 1rem; font-size: .8rem; color: var(--ink-2); margin-bottom: .4rem; }
.bi-leyenda span { display: inline-flex; align-items: center; gap: .35rem; }
.bi-sw { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.bi-sw-s1 { background: var(--bi-1); }
.bi-sw-s2 { background: var(--bi-2); }
.bi-sw-s3 { background: var(--bi-3); }
.bi-sw-s4 { background: var(--bi-4); }
.bi-sw-ref { background: var(--bi-ref); }
.bi-sw-linea { height: 3px; border-radius: 2px; width: 16px; }
.bi-sw-punteada { background: repeating-linear-gradient(90deg, var(--bi-ref) 0 5px, transparent 5px 8px); }
.bi-hbar { display: flex; flex-direction: column; gap: .55rem; }
.bi-hbar__fila { min-width: 0; }
.bi-hbar__cab { display: flex; gap: .5rem; align-items: baseline; font-size: .85rem; }
.bi-hbar__n { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-2); }
.bi-hbar__cab b { font-variant-numeric: tabular-nums; color: var(--ink); }
.bi-hbar__pista { position: relative; height: 10px; background: var(--cream-2); border-radius: 4px; margin-top: .2rem; }
.bi-hbar__pista i { display: block; height: 100%; border-radius: 0 4px 4px 0; min-width: 2px; }
.bi-otros { opacity: .55; }
.bi-hbar__marca { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--ink); border-radius: 1px; }
.bi-hbar__nota { font-size: .74rem; color: var(--muted); margin-top: .15rem; }
.bi-sem { font-size: .72rem; font-weight: 600; white-space: nowrap; }
.bi-sem-verde { color: var(--ok-tinta); }
.bi-sem-ambar { color: var(--aviso-tinta); }
.bi-sem-rojo { color: var(--mal-tinta); }
.bi-sem-gris { color: var(--muted); }
.bi-embudo { display: flex; flex-direction: column; gap: .45rem; }
.bi-embudo__f { display: grid; grid-template-columns: 7.5rem 1fr auto; gap: .5rem; align-items: center; font-size: .84rem; color: var(--ink-2); }
.bi-embudo__f div { height: 14px; background: var(--cream-2); border-radius: 4px; }
.bi-embudo__f i { display: block; height: 100%; border-radius: 0 4px 4px 0; }
.bi-embudo__f b { font-variant-numeric: tabular-nums; color: var(--ink); }
.bi-emb-0 { background: #86b6ef; }
.bi-emb-1 { background: #5598e7; }
.bi-emb-2 { background: #2a78d6; }
.bi-emb-3 { background: #256abf; }
.bi-emb-4 { background: #1c5cab; }
.bi-emb-5 { background: #184f95; }
:root[data-theme="dark"] .bi-emb-0 { background: #184f95; }
:root[data-theme="dark"] .bi-emb-1 { background: #1c5cab; }
:root[data-theme="dark"] .bi-emb-2 { background: #256abf; }
:root[data-theme="dark"] .bi-emb-3 { background: #2a78d6; }
:root[data-theme="dark"] .bi-emb-4 { background: #3987e5; }
:root[data-theme="dark"] .bi-emb-5 { background: #6da7ec; }
.bi-hero { display: flex; flex-direction: column; gap: .2rem; padding: .7rem .9rem; border-radius: 10px; margin-bottom: .7rem; }
.bi-hero b { font-size: 1.15rem; }
.bi-hero.bi-ok { background: var(--ok-fondo); }
.bi-hero.bi-mal { background: var(--mal-fondo); }
.bi-hero.bi-ok b, td.bi-ok { color: var(--ok-tinta); }
.bi-hero.bi-mal b, td.bi-mal { color: var(--mal-tinta); }
.bi-hero span { color: var(--ink-2); font-size: .88rem; }
.bi-vacio { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; padding: 1.2rem; border: 1px dashed var(--line-2); border-radius: 10px; color: var(--muted); font-size: .88rem; }
.bi-vacio p { margin: 0; }
.bi-nota { font-size: .76rem; color: var(--muted); margin: .4rem 0 0; }
.bi-datos { margin-top: .5rem; font-size: .82rem; }
.bi-datos summary { cursor: pointer; color: var(--muted); font-size: .78rem; }
.bi-datos__caja { overflow-x: auto; max-width: 100%; }
.bi-datos table, .bi-card__cuerpo table { width: 100%; border-collapse: collapse; font-size: .8rem; }
.bi-datos th, .bi-datos td, .bi-card__cuerpo th, .bi-card__cuerpo td { padding: .3rem .45rem; border-bottom: 1px solid var(--line); text-align: left; white-space: nowrap; }
.bi-datos td.num, .bi-card__cuerpo td.num { text-align: right; font-variant-numeric: tabular-nums; }
.bi-tip { position: fixed; z-index: 1000; pointer-events: none; white-space: pre-line; max-width: 260px; font-size: .8rem; line-height: 1.4;
  background: var(--ink); color: var(--bg); padding: .45rem .6rem; border-radius: 8px; box-shadow: var(--shadow); }

/* ---------- Inteligencia de negocio (complemento 'bi') ----------
   Reusa las tarjetas y gráficas bi-*; aquí sólo las pestañas, la tabla dinámica y el
   aviso de lo que incluye. */
.ibn-tabs { display: flex; gap: .3rem; flex-wrap: wrap; border-bottom: 1px solid var(--line); }
.ibn-tab { background: none; border: 0; border-bottom: 2px solid transparent; padding: .5rem .8rem; font: inherit; font-size: .9rem; color: var(--muted); cursor: pointer; }
.ibn-tab:hover { color: var(--ink); }
.ibn-tab.is-on { color: var(--ink); font-weight: 700; border-bottom-color: var(--bi-1); }
[data-ibnpanel] { display: flex; flex-direction: column; gap: 1rem; margin-top: .9rem; min-width: 0; }
[data-ibnpanel][hidden] { display: none; }
.ibn-piv { max-height: 70vh; }
.ibn-piv thead th { position: sticky; top: 0; background: var(--tarjeta); z-index: 1; }
.ibn-piv tfoot td { font-weight: 700; border-top: 2px solid var(--line-2); }
.ibn-ord { background: none; border: 0; padding: 0; font: inherit; font-weight: 700; color: var(--ink); cursor: pointer; white-space: nowrap; }
.ibn-cel { background: none; border: 0; padding: .1rem .2rem; font: inherit; font-variant-numeric: tabular-nums; color: var(--ink); cursor: pointer; border-radius: 4px; }
.ibn-cel:hover, .ibn-cel:focus-visible { background: var(--cream-2); text-decoration: underline; }
.ibn-cel.bi-neg { color: var(--mal-tinta); }
.ibn-lista { margin: 0 0 .8rem; padding-left: 1.1rem; display: flex; flex-direction: column; gap: .35rem; font-size: .9rem; color: var(--ink-2); }

/* ---------- El manual completo (Ayuda › Manual completo) ----------
   Índice a la izquierda, contenido a la derecha; en el teléfono, uno debajo del otro.
   Los botones del manual son réplicas inertes de los del panel: mismas clases, sin clic. */
.man-barra { align-items: flex-end; }
.man-lay { display: grid; grid-template-columns: minmax(200px, 250px) minmax(0, 1fr); gap: 1.4rem; align-items: start; }
.man-indice { position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; border: 1px solid var(--line); border-radius: 10px; padding: .6rem; background: var(--surface); }
.man-ind__mod { padding: .15rem 0; }
.man-ind__tit { display: block; padding: .35rem .5rem; border-radius: 7px; font-weight: 600; font-size: .88rem; color: var(--ink); text-decoration: none; }
.man-ind__tit:hover { background: var(--realce); }
.man-ind__mod.on .man-ind__tit { background: var(--red-tint); color: var(--red-tinta); }
.man-ind__mod ul { list-style: none; margin: .2rem 0 .4rem; padding: 0 0 0 .6rem; border-left: 2px solid var(--line); }
.man-ind__mod li a { display: block; padding: .22rem .5rem; font-size: .82rem; color: var(--ink-2); text-decoration: none; border-radius: 6px; }
.man-ind__mod li a:hover { background: var(--realce); color: var(--ink); }
.man-doc { min-width: 0; max-width: 860px; overflow-wrap: anywhere; }
.man-cab { margin-bottom: 1.2rem; }
.man-cab h3 { margin: .2rem 0 .4rem; }
.man-sec { border-top: 1px solid var(--line); padding: 1.1rem 0 .6rem; scroll-margin-top: 1rem; }
.man-sec h4 { margin: 0 0 .5rem; font-size: 1.05rem; }
.man-link { color: var(--muted); text-decoration: none; font-weight: 400; margin-left: .3rem; }
.man-link:hover { color: var(--red-tinta); }
.man-que { color: var(--ink-2); margin: 0 0 .8rem; }
.man-res { margin: 1.2rem 0 .2rem; }
.man-pasos { list-style: none; counter-reset: manpaso; margin: 0; padding: 0; }
.man-pasos > li { counter-increment: manpaso; position: relative; padding: .55rem 0 .55rem 2.3rem; border-bottom: 1px dashed var(--line); }
.man-pasos > li::before { content: counter(manpaso); position: absolute; left: 0; top: .5rem; width: 1.6rem; height: 1.6rem; border-radius: 50%; background: var(--red); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: .8rem; }
.man-paso__txt { line-height: 1.5; }
.man-paso__acc { display: flex; flex-wrap: wrap; align-items: flex-start; gap: .5rem .8rem; margin-top: .45rem; }
.man-rep { display: inline-flex; flex-direction: column; gap: .2rem; max-width: 100%; }
.man-inerte { pointer-events: none; cursor: default; user-select: none; align-self: flex-start; max-width: 100%; white-space: normal; text-align: left; }
.man-rep .tb-link.man-inerte { border: 1px dashed var(--line-2); }
.man-rep .admin-nav-item.man-inerte { border: 1px solid var(--line-2); background: var(--surface); }
.man-campo { display: inline-block; min-width: 12rem; padding: .4rem .7rem; border: 1px solid var(--line-2); border-radius: 8px; background: var(--bg, var(--surface)); color: var(--muted); font-size: .85rem; }
.man-donde { color: var(--muted); font-size: .76rem; }
.man-muestra { align-self: flex-start; }
.man-caja { margin: .8rem 0 .2rem; padding: .7rem .9rem; border-radius: 8px; background: var(--surface); border-left: 3px solid var(--line-2); }
.man-caja ul { margin: .35rem 0 0; padding-left: 1.1rem; }
.man-caja dl { margin: .35rem 0 0; }
.man-caja dt { font-weight: 600; margin-top: .4rem; }
.man-caja dd { margin: .1rem 0 0; color: var(--ink-2); }
.man-caja--tip { border-left-color: var(--ok-tinta); }
.man-caja--err { border-left-color: var(--red); }
.man-preg { margin: .5rem 0; }
.man-preg summary { cursor: pointer; font-weight: 600; }
.man-preg p { margin: .35rem 0 0; color: var(--ink-2); }
.man-flujo { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: .4rem 0 1rem; }
.man-flujo__paso { display: inline-flex; align-items: center; gap: .4rem; padding: .45rem .75rem; border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface); color: var(--ink); font-size: .85rem; font-weight: 600; }
.man-flujo__paso b { display: grid; place-items: center; width: 1.3rem; height: 1.3rem; border-radius: 50%; background: var(--red-tint); color: var(--red-tinta); font-size: .72rem; }
.man-flujo__fl { color: var(--muted); font-weight: 700; }
@media (max-width: 760px) {
  .man-lay { grid-template-columns: minmax(0, 1fr); }
  .man-indice { position: static; max-height: 16rem; }
  .man-campo { min-width: 0; }
  .man-flujo { flex-direction: column; align-items: flex-start; }
  .man-flujo__fl { transform: rotate(90deg); margin-left: .8rem; }
}
@media print {
  body.imprime-manual * { visibility: hidden !important; }
  body.imprime-manual #manualDoc, body.imprime-manual #manualDoc * { visibility: visible !important; }
  body.imprime-manual #manualDoc { position: absolute; left: 0; top: 0; max-width: none; width: 100%; }
  body.imprime-manual .man-muestra, body.imprime-manual .man-link { display: none !important; }
  body.imprime-manual .man-sec { break-inside: avoid-page; }
  body.imprime-manual .man-pasos > li::before { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ================= REJILLA DE INCIDENCIAS DEL PERIODO =================
 * Como una hoja de cálculo: encabezado en dos niveles con el grupo ROTULADO (antes era
 * un fondo rosa sin nombre, con el título gris encima que casi no se leía), nombre fijo a
 * la izquierda en una sola línea, encabezado fijo arriba, columnas angostas con cifras
 * alineadas a la derecha y totales al pie. El color del grupo es una raya, no un fondo:
 * así el texto conserva el contraste de siempre en claro y en oscuro. */
:root { --ri-aus: #B3262D; --ri-inc: #8A6520; --ri-ext: #2F5E9A; --ri-esp: #6B4FA0; --ri-imp: #17724A; --ri-des: #9A4A12; --ri-otr: #6E655C; }
:root[data-theme="dark"] { --ri-aus: #E4626A; --ri-inc: #D9A94F; --ri-ext: #7EA7E0; --ri-esp: #B39AE0; --ri-imp: #5CC592; --ri-des: #E08A4F; --ri-otr: #A99E92; }
.nom-seccion { display: block; border-top: 1px solid var(--line); padding-top: 1rem; }
.ri-herr { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .7rem; margin: 0 0 .7rem; }
.ri-herr[hidden] { display: none; }
.ri-herr__tit { font-size: .82rem; font-weight: 600; color: var(--ink-2); }
.ri-herr select, .ri-herr input[type="text"], .ri-herr input[type="search"] { padding: .35rem .55rem; font-size: .86rem; border: 1px solid var(--line-2, var(--line)); border-radius: 6px; background: var(--surface); color: var(--ink); }
.ri-grupos { display: inline-flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.ri-chip { display: inline-flex; align-items: center; gap: .3rem; font-size: .8rem; color: var(--ink); padding: .2rem .55rem; border: 1px solid var(--line); border-left: 4px solid var(--ri-otr); border-radius: 999px; cursor: pointer; background: var(--surface); }
.ri-scroll { overflow: auto; max-height: 70vh; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); -webkit-overflow-scrolling: touch; }
.ri-tabla { border-collapse: separate; border-spacing: 0; font-size: .86rem; width: max-content; min-width: 100%; }
.ri-tabla th, .ri-tabla td { padding: .3rem .45rem; border-bottom: 1px solid var(--line); background: var(--surface); color: var(--ink); }
.ri-tabla thead th { position: sticky; z-index: 2; background: var(--realce); color: var(--ink); font-weight: 600; }
.ri-tabla thead tr:first-child th { top: 0; }
.ri-tabla thead tr:nth-child(2) th { top: 2rem; }
.ri-grupo { height: 2rem; text-align: center; font-size: .74rem; letter-spacing: .04em; text-transform: uppercase; border-top: 3px solid var(--ri-otr); border-left: 1px solid var(--line); }
.ri-col { max-width: 6.2rem; min-width: 4.4rem; white-space: normal; vertical-align: bottom; text-align: right; font-size: .76rem; line-height: 1.2; }
.ri-col__n { display: block; }
.ri-col__u { display: block; font-weight: 400; color: var(--ink-2); font-size: .72rem; }
.ri-g--ausencias.ri-grupo, .ri-chip.ri-g--ausencias { border-top-color: var(--ri-aus); border-left-color: var(--ri-aus); }
.ri-g--incapacidades.ri-grupo, .ri-chip.ri-g--incapacidades { border-top-color: var(--ri-inc); border-left-color: var(--ri-inc); }
.ri-g--extras.ri-grupo, .ri-chip.ri-g--extras { border-top-color: var(--ri-ext); border-left-color: var(--ri-ext); }
.ri-g--especiales.ri-grupo, .ri-chip.ri-g--especiales { border-top-color: var(--ri-esp); border-left-color: var(--ri-esp); }
.ri-g--importes.ri-grupo, .ri-chip.ri-g--importes { border-top-color: var(--ri-imp); border-left-color: var(--ri-imp); }
.ri-g--descuentos.ri-grupo, .ri-chip.ri-g--descuentos { border-top-color: var(--ri-des); border-left-color: var(--ri-des); }
.ri-fijo0 { position: sticky; left: 0; z-index: 1; width: 2.2rem; min-width: 2.2rem; text-align: center; }
.ri-fijo1 { position: sticky; left: 2.2rem; z-index: 1; width: 15rem; min-width: 11rem; max-width: 15rem; text-align: left; font-weight: 400; box-shadow: 1px 0 0 var(--line); }
.ri-tabla thead .ri-fijo0, .ri-tabla thead .ri-fijo1 { z-index: 3; top: 0; }
.ri-nom { display: block; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ri-sub { display: block; font-size: .74rem; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ri-aviso { display: block; font-size: .74rem; color: var(--aviso-tinta); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ri-celda { text-align: right; }
.ri-in { width: 4.4rem; padding: .25rem .35rem; text-align: right; font-variant-numeric: tabular-nums; border: 1px solid var(--line); border-radius: 4px; background: transparent; color: var(--ink); font-size: .86rem; }
.ri-in:hover { border-color: var(--line-2, var(--line)); }
.ri-in:focus { outline: 2px solid var(--ri-ext); outline-offset: -1px; background: var(--surface); }
.ri-in.ri-mal { border-color: var(--mal-tinta); background: var(--mal-fondo); }
.ri-marca { width: 1.05rem; height: 1.05rem; accent-color: var(--ri-ext); }
.ri-tabla tbody tr:hover td, .ri-tabla tbody tr:hover th, .ri-tabla tbody tr:focus-within td, .ri-tabla tbody tr:focus-within th { background: var(--realce); }
.ri-tabla tfoot th, .ri-tabla tfoot td { position: sticky; bottom: 0; z-index: 1; background: var(--realce); font-weight: 600; font-variant-numeric: tabular-nums; border-top: 2px solid var(--line); text-align: right; }
.ri-tabla tfoot .ri-fijo0, .ri-tabla tfoot .ri-fijo1 { z-index: 3; text-align: left; }
@media (max-width: 640px) {
  .ri-fijo1 { width: 9rem; min-width: 9rem; max-width: 9rem; }
  .ri-scroll { max-height: 65vh; }
}

/* LA HOJA DE LA PÓLIZA DE NÓMINA: una sola hoja carta, con 1 o con 400 personas.
   Todo agrupado por cuenta, así que no crece con la plantilla; letra compacta y cifras
   tabulares para comparar de arriba abajo contra la hoja de trabajo propia. En pantalla
   sigue el tema (oscuro legible); al imprimir, la hoja blanca de `@media print`. */
.ph { font-size: .78rem; line-height: 1.3; color: var(--doc-tinta); font-variant-numeric: tabular-nums; }
.ph-cab { display: flex; justify-content: space-between; gap: 1rem; border-bottom: 2px solid var(--doc-raya-fuerte); padding-bottom: .35rem; }
.ph-cab b { font-size: 1rem; display: block; }
.ph-cab span { color: var(--doc-apagado); }
.ph-cab__t { text-align: right; }
.ph-meta { display: grid; grid-template-columns: repeat(6, auto); gap: .2rem .8rem; margin: .35rem 0 .2rem; }
.ph-meta small { display: block; font-size: .62rem; text-transform: uppercase; letter-spacing: .05em; color: var(--doc-apagado); }
.ph-h { font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--doc-apagado); margin: .5rem 0 .15rem; }
.ph-t { width: 100%; border-collapse: collapse; }
.ph-t th { font-size: .62rem; text-transform: uppercase; letter-spacing: .05em; color: var(--doc-apagado); text-align: left; border-bottom: 1.5px solid var(--doc-raya-fuerte); padding: .12rem .3rem; }
.ph-t td { padding: .08rem .3rem; border-bottom: 1px solid var(--doc-raya); }
.ph-t .r { text-align: right; white-space: nowrap; }
.ph-sec td { font-weight: 700; padding-top: .25rem; }
.ph-sec em { font-weight: 400; font-style: normal; color: var(--doc-apagado); font-size: .7rem; }
.ph-sub td { color: var(--doc-tinta-2); font-style: italic; border-bottom-color: var(--doc-raya-fuerte); }
.ph-tot td { font-weight: 700; border-top: 2px solid var(--doc-raya-fuerte); border-bottom: 0; }
.ph-ok { color: var(--ok-tinta, #17724A); font-weight: 700; font-style: normal; }
.ph-mal { color: var(--doc-marca); font-weight: 700; font-style: normal; }
.ph-cajas { display: grid; grid-template-columns: repeat(3, 1fr); gap: .3rem; }
.ph-caja { border: 1px solid var(--doc-raya-fuerte); border-radius: 4px; padding: .2rem .35rem; }
.ph-caja h5 { font-size: .62rem; text-transform: uppercase; letter-spacing: .05em; color: var(--doc-apagado); margin: 0 0 .1rem; }
.ph-caja div { display: flex; justify-content: space-between; gap: .5rem; }
.ph-caja div span { color: var(--doc-tinta-2); }
.ph-caja div:last-child b { border-top: 1px solid var(--doc-raya); }
.ph-cuadres { margin-top: .3rem; }
.ph-avisos { margin: .25rem 0; font-size: .72rem; color: var(--aviso-tinta, #8A6520); }
.ph-avisos p { margin: 0; }
.ph-firmas { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; margin-top: 2.2rem; text-align: center; font-size: .72rem; color: var(--doc-tinta-2); }
.ph-firmas span { display: block; border-top: 1px solid var(--doc-tinta-2); margin-bottom: .15rem; }
@media (max-width: 700px) { .ph-meta { grid-template-columns: repeat(2, auto); } .ph-cajas { grid-template-columns: 1fr; } }
@media print {
  @page { size: letter; margin: 9mm 10mm; }
  .doc-page:has(> .ph) { padding: 0 !important; }
  .ph { font-size: 7.2pt; line-height: 1.22; color: #1B1714; }
  .ph-t td { padding: .02rem .25rem; }
  .ph-h { margin: .3rem 0 .1rem; }
  .ph-firmas { margin-top: 1.6rem; }
  .ph-meta { grid-template-columns: repeat(6, auto); }
  .ph-cajas { grid-template-columns: repeat(3, 1fr); }
  .ph-ok { color: #17724A; } .ph-avisos { color: #8A6520; }
  .ph-t tr, .ph-caja { break-inside: avoid; }
}

/* ===== Checklist de obligaciones (admin.js · obChk*) ===== */
.ob-grupo { margin: 1rem 0 .4rem; font-size: .95rem; display: flex; justify-content: space-between; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.ob-dias { display: block; font-size: .8rem; color: var(--muted); }
.ob-dias--vencida { color: var(--mal-tinta); font-weight: 600; }
.ob-dias--pronto { color: var(--aviso-tinta); font-weight: 600; }
.ob-fund { display: block; font-size: .78rem; color: var(--muted); }
.ob-noaplica { opacity: .6; }
.ob-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin-top: .6rem; }
.ob-cal__dow { font-size: .72rem; text-align: center; color: var(--muted); padding: .2rem 0; }
.ob-cal__dia { min-height: 5.2rem; border: 1px solid var(--line); border-radius: 8px; padding: .3rem; font-size: .72rem; overflow: hidden; }
.ob-cal__dia--fuera { opacity: .35; }
.ob-cal__dia--inhabil { background: var(--neutro-fondo); }
.ob-cal__num { font-weight: 700; display: block; margin-bottom: .15rem; }
.ob-cal__ev { display: block; border-radius: 4px; padding: 1px 4px; margin-top: 2px; background: var(--aviso-fondo); color: var(--aviso-tinta); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ob-cal__ev--hecha { background: var(--ok-fondo); color: var(--ok-tinta); text-decoration: line-through; }
.ob-cal__ev--vencida { background: var(--mal-fondo); color: var(--mal-tinta); }
.ob-perfil { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: .6rem 1rem; padding: .8rem 0; }
.ob-aviso-inicio { margin-bottom: 1.4rem; border-left: 3px solid var(--aviso-tinta); }
@media (max-width: 640px) {
  .ob-cal { gap: 2px; }
  .ob-cal__dia { min-height: 3.6rem; font-size: .62rem; padding: .15rem; }
  .ob-cal__ev { white-space: normal; }
}
@media print {
  body.imprime-obligaciones * { visibility: hidden !important; }
  body.imprime-obligaciones #obChkHoja, body.imprime-obligaciones #obChkHoja * { visibility: visible !important; }
  body.imprime-obligaciones #obChkHoja { position: absolute; left: 0; top: 0; width: 100%; font-size: 10px; }
  body.imprime-obligaciones #obChkHoja button, body.imprime-obligaciones #obChkHoja .ob-no-imprimir { display: none !important; }
  body.imprime-obligaciones #obChkHoja tr { break-inside: avoid; }
  body.imprime-obligaciones .tb-pill { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* «¿DÓNDE ESTÁ CADA COSA?» (kern-mapa.js, 2026-10-01): la bienvenida de cada plan. Un
 * mapa de cajas, una por área, con su renglón por pantalla y su «Ir». Sale sobre el panel
 * como las ventanas de captura (.pm-fondo) y respeta el tema claro y el oscuro. */
.km-fondo { position: fixed; inset: 0; background: rgba(20,16,14,.55); backdrop-filter: blur(3px);
  z-index: 1200; display: flex; align-items: center; justify-content: center; padding: 1rem; }
.km-caja { background: var(--tarjeta); color: var(--ink); border-radius: 16px; width: min(60rem, 100%); max-height: 92vh;
  display: flex; flex-direction: column; box-shadow: var(--shadow); overflow: hidden; }
.km-cab { display: flex; gap: 1rem; align-items: flex-start; padding: 1.1rem 1.3rem .9rem; border-bottom: 1px solid var(--line); }
.km-cab > div { flex: 1; min-width: 0; }
.km-eyebrow { font-size: .7rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--red-tinta); }
.km-cab h2 { margin: .15rem 0 .25rem; font-size: 1.35rem; }
.km-que { margin: 0; color: var(--muted); font-size: .9rem; }
.km-x { border: 0; background: none; font-size: 1.6rem; line-height: 1; cursor: pointer; color: var(--muted); padding: 0 .2rem; }
.km-x:hover { color: var(--red-tinta); }
.km-cuerpo { padding: 1rem 1.3rem; overflow: auto; }
.km-donde { display: flex; flex-direction: column; gap: .15rem; background: var(--realce); border-radius: 10px;
  padding: .7rem .9rem; font-size: .86rem; margin-bottom: .8rem; }
.km-donde b { font-size: .72rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.km-aclara { border-left: 3px solid var(--red-tinta); padding: .55rem .8rem; margin-bottom: .9rem; font-size: .88rem;
  background: var(--surface); border-radius: 0 8px 8px 0; }
.km-mapa { display: grid; grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); gap: .8rem; }
.km-grupo { border: 1px solid var(--line); border-radius: 12px; padding: .7rem .8rem .5rem; background: var(--surface); }
.km-grupo h3 { margin: 0 0 .4rem; font-size: .74rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.km-grupo ul { list-style: none; margin: 0; padding: 0; }
.km-cosa { display: flex; align-items: center; gap: .6rem; padding: .45rem 0; border-top: 1px solid var(--line); }
.km-cosa:first-child { border-top: 0; }
.km-ic { font-size: 1.15rem; width: 1.6rem; text-align: center; flex: none; }
.km-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: .78rem; color: var(--muted); }
.km-txt b { font-size: .88rem; color: var(--ink); }
.km-ir { flex: none; border: 1px solid var(--line); background: var(--tarjeta); color: var(--ink); border-radius: 8px;
  padding: .25rem .7rem; font: inherit; font-size: .8rem; font-weight: 600; cursor: pointer; }
.km-ir:hover { border-color: var(--red-tinta); color: var(--red-tinta); }
.km-cosa--no { opacity: .55; }
.km-noesta { flex: none; font-size: .7rem; color: var(--muted); max-width: 7rem; text-align: right; }
.km-nota { margin: .9rem 0 0; font-size: .82rem; color: var(--muted); }
.km-pie { display: flex; align-items: center; justify-content: space-between; gap: .8rem; flex-wrap: wrap;
  padding: .8rem 1.3rem; border-top: 1px solid var(--line); }
.km-pie__izq { display: flex; gap: .9rem; align-items: center; flex-wrap: wrap; font-size: .8rem; color: var(--muted); }
.km-guia { font-weight: 600; color: var(--red-tinta); }
.km-guia[hidden] { display: none; }
.km-ok { border: 0; border-radius: 10px; background: var(--red); color: #fff; font: inherit; font-weight: 700;
  padding: .55rem 1.2rem; cursor: pointer; }
@media (max-width: 620px) { .km-caja { max-height: 96vh; } .km-cab h2 { font-size: 1.15rem; } .km-reabrir { display: none; } }

/* «Emite: …» arriba de cada captura que crea un documento con emisor (admin.js,
   EMITE_PANELES): de qué empresa sale, su RFC y «Cambiar». Con «Todas las empresas» pide
   elegirla; una empresa de pruebas lleva su franja. */
.emite-banda { margin: 0 0 1rem; border: 1px solid var(--line); border-left: 4px solid var(--info-tinta);
  border-radius: 10px; background: var(--tarjeta); overflow: hidden; }
.emite-banda__fila { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; padding: .6rem .9rem; font-size: .95rem; }
.emite-banda__fila > span:first-child { color: var(--muted); }
.emite-banda__fila b { font-size: 1.05rem; }
.emite-banda__rfc { font-variant-numeric: tabular-nums; color: var(--muted); font-size: .85rem; }
.emite-banda__fila--falta { background: var(--aviso-fondo); color: var(--aviso-tinta); }
.emite-banda[data-falta] { border-left-color: var(--aviso-tinta); }
.emite-banda .emite-sel { max-width: 100%; }
.emite-banda .emite-sel[hidden] { display: none; }
.emite-banda__pruebas { padding: .5rem .9rem; font-weight: 700; color: #fff; letter-spacing: .01em;
  background: repeating-linear-gradient(-45deg, #B45309, #B45309 12px, #92400E 12px, #92400E 24px); }
/* ===== Correos: Para, CC y CCO con chips, cuadro de envío y Empresas › Correos (237) ===== */
.pm-caja.pm-caja--correo { width: min(780px, 100%); }
.dest { display: grid; gap: .4rem; }
.dest-fila { display: flex; gap: .5rem; align-items: flex-start; }
.dest-fila[hidden] { display: none; }
.dest-etq { flex: 0 0 2.6rem; padding-top: .45rem; font-size: .8rem; font-weight: 600; color: var(--muted); }
.dest-caja { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; padding: .3rem .4rem;
  border: 1px solid var(--line); border-radius: 8px; background: var(--surface, #fff); cursor: text; }
.dest-caja:focus-within { border-color: var(--realce, #0E7C86); box-shadow: 0 0 0 2px rgba(14, 124, 134, .15); }
.dest-chips { display: contents; }
.dest-chip { display: inline-flex; align-items: center; gap: .25rem; max-width: 100%; padding: .15rem .25rem .15rem .55rem;
  border-radius: 999px; background: var(--cream, #f3f1ec); border: 1px solid var(--line); font-size: .8rem; line-height: 1.3;
  color: var(--ink); overflow-wrap: anywhere; }
.dest-chip--var { padding: .15rem .55rem; cursor: pointer; font-family: ui-monospace, Menlo, Consolas, monospace; }
.dest-chip--var:hover { border-color: var(--realce, #0E7C86); }
.dest-x { border: 0; background: transparent; color: var(--muted); font-size: 1rem; line-height: 1; padding: 0 .2rem; cursor: pointer; border-radius: 50%; }
.dest-x:hover { color: var(--red-tinta, #b42318); background: rgba(0, 0, 0, .06); }
.dest-caja .dest-in { flex: 1 1 10rem; min-width: 8rem; border: 0; outline: 0; padding: .25rem .2rem; background: transparent; font: inherit; font-size: .88rem; }
.dest-in--mal, .dest-caja .dest-in--mal { color: var(--red-tinta, #b42318); text-decoration: underline wavy; }
input.cc-email.dest-in--mal { border-color: var(--red-tinta, #b42318); }
.dest-mas { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; padding-left: 3.1rem; font-size: .82rem; }
.dest-mas [hidden] { display: none; }
.dest-aviso { color: var(--red-tinta, #b42318); font-size: .8rem; }
.mc-frame { display: block; width: 100%; height: 460px; border: 1px solid var(--line); border-radius: 8px; background: #f2f3f5; margin-top: .5rem; }
.mc-prev > summary, .mc-bit > summary { cursor: pointer; font-weight: 600; font-size: .88rem; margin: .4rem 0; }
.cc-tabla td { vertical-align: middle; }
.cc-tabla input[type="email"] { width: 100%; min-width: 12rem; }
.eco-rejilla { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 1rem; align-items: start; }
.eco-previa .mc-frame { height: 620px; }
.eco-vars { display: flex; flex-wrap: wrap; gap: .3rem; margin: .2rem 0 .3rem; }
@media (max-width: 900px) { .eco-rejilla { grid-template-columns: 1fr; } .eco-previa .mc-frame { height: 480px; } }

/* =========================================================================================
   PANTALLAS COMPLETAS: TABLAS DE TRABAJO (2026-10-03)
   =========================================================================================

   Enrique: «trata que todas las pantallas se vean completas». La columna fija de acciones
   de Suscripciones medía casi 400 px y tapaba «Cobro»; nombres y planes se partían en tres
   renglones; el texto era de lectura, no de trabajo. Lo arregla `tablaHTML` (admin.js,
   bloque TABLA-COMPACTA) y aquí van sus medidas:

   · Un tamaño de trabajo: .875rem, subtextos a .78rem, celdas más bajas y buen
     interlineado; los números en `tabular-nums`.
   · `tb-nw`: folio, fecha, montos y estado no se parten. `tb-largo`: cliente, plan o
     concepto se cortan en dos renglones con «…» (el texto completo va en el title).
   · `tb-oc3` / `tb-oc2`: las columnas de prioridad 3 y 2 se esconden cuando la tabla no
     cabe en su caja.
   · `col-acc`: la columna de acciones, angosta: una acción y «⋯».
   · `tb-desborda`: sólo cuando de verdad hay algo debajo, la columna fija lleva sombra. */
.admin-shell .tabla-odoo { font-size: .875rem; line-height: 1.4; }
.admin-shell .tabla-odoo tbody td { padding: .38rem .65rem; font-variant-numeric: tabular-nums; }
.admin-shell .tabla-odoo thead th { padding: .45rem .65rem; }
.admin-shell .tabla-odoo .tb-sub { font-size: .78rem; line-height: 1.3; }
.admin-shell .tabla-odoo .tb-avatar { width: 26px; height: 26px; font-size: .74rem; }
.admin-shell .tabla-odoo .tb-cell-avatar { gap: .5rem; }
.tabla-odoo .tb-nw, .tabla-odoo td.r, .tb-pill { white-space: nowrap; }
.tabla-odoo .tb-clamp,
.tabla-odoo td.tb-largo > b,
.tabla-odoo td.tb-largo .tb-cell-avatar b {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; max-width: 19rem; min-width: 10rem; overflow-wrap: break-word;
}
.tabla-scroll.tb-pocas > .tabla-odoo { min-width: 0; }
.tabla-scroll.tb-pocas .tb-clamp,
.tabla-scroll.tb-pocas td.tb-largo > b,
.tabla-scroll.tb-pocas td.tb-largo .tb-cell-avatar b { min-width: 4.5rem; }
.admin-shell .tabla-scroll.tb-pocas > .tabla-odoo :is(th, td) { padding-left: .45rem; padding-right: .45rem; }
.tabla-odoo.tb-oc3 .tb-p3,
.tabla-odoo.tb-oc2 .tb-p2 { display: none; }

/* La columna de acciones: lo justo para una acción y «⋯». */
.tabla-odoo td.col-acc, .tabla-odoo th.col-acc { width: 1%; white-space: nowrap; }
.tabla-odoo td.col-acc .tb-actions { gap: .15rem; align-items: center; }
.tb-mas { font-size: 1.05rem; line-height: 1; letter-spacing: .04em; min-width: 1.9rem; padding: .22rem .4rem; }
.tb-mas[aria-expanded="true"] { background: var(--realce); color: var(--ink); }
.tb-link:focus-visible, .tb-mas:focus-visible { outline: 2px solid var(--red); outline-offset: 1px; }
/* El menú va fijo a la ventana (la caja de la tabla recorta lo que se le sale) y su celda
   sube por encima de las de los demás renglones, que también son pegajosas. */
.tabla-odoo td.tb-acc-abierta { z-index: 30 !important; }
.tb-menu {
  position: fixed; z-index: 400; min-width: 11.5rem; max-width: 18rem;
  display: flex; flex-direction: column; gap: 1px; padding: .3rem;
  background: var(--surface, #fff); color: var(--ink);
  border: 1px solid var(--line-2, var(--line)); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0,0,0,.18), 0 2px 6px rgba(0,0,0,.08);
  white-space: nowrap;
}
.tb-menu[hidden] { display: none; }
.tb-menu .tb-menu__item {
  display: flex; align-items: center; gap: .45rem; width: 100%;
  text-align: left; justify-content: flex-start;
  padding: .42rem .65rem; font-size: .85rem; border-radius: 7px; color: var(--ink-2);
}
.tb-menu .tb-menu__item:hover, .tb-menu .tb-menu__item:focus { background: var(--realce); color: var(--ink); outline: none; }
.tb-menu .tb-menu__item:focus-visible { box-shadow: inset 0 0 0 2px var(--red); }
.tb-menu .tb-menu__item.tb-link--danger { color: var(--red-tinta); }
.tb-menu .tb-menu__item.tb-link--danger:hover, .tb-menu .tb-menu__item.tb-link--danger:focus { background: rgba(193,39,45,.09); color: var(--red-tinta); }
.tb-menu__sep { height: 1px; background: var(--line); margin: .25rem .2rem; }
.tb-menu__etq { font-weight: 600; }

/* Sólo si aun así no cabe: la caja se desplaza de lado y la columna fija lo dice con sombra. */
.admin-shell .tabla-scroll.tb-desborda > .tabla-odoo td:last-child,
.admin-shell .tabla-scroll.tb-desborda > .tabla-odoo th:last-child { box-shadow: -8px 0 10px -8px rgba(0,0,0,.35); }

/* LA CABECERA DE CADA PANTALLA. En anchos medianos los botones bajan en orden y no se
   parten; el principal ya no es el doble de alto que los demás. */
.admin-shell .tbl-toolbar__actions { gap: .45rem; justify-content: flex-end; }
.admin-shell .tbl-toolbar__actions > .btn,
.admin-shell .tbl-toolbar__actions > a.btn,
.admin-shell .tbl-toolbar__actions > .toggle-group,
.admin-shell .tbl-toolbar__actions > .tbl-search { white-space: nowrap; }
.admin-shell .tbl-toolbar__actions > .btn:not(.btn--sm),
.admin-shell .tbl-toolbar__actions > a.btn:not(.btn--sm) { padding: .42rem .95rem; font-size: .84rem; line-height: 1.25; }
@media (max-width: 620px) {
  .admin-shell .tbl-toolbar__actions > .btn,
  .admin-shell .tbl-toolbar__actions > a.btn { white-space: normal; }
}

/* ===== Balanza y estados financieros, papel de trabajo (admin.js · loadBalanza/loadEstados, 2026-10-03) =====
 * Cifras a la derecha y tabulares, sin signos (la columna dice el lado), jerarquía por
 * peso y sangría, no por color. Los mismos tokens de siempre. */
.bal-tabla, .ef-tabla { font-variant-numeric: tabular-nums; }
.bal-tabla td, .bal-tabla th, .ef-tabla td, .ef-tabla th { padding: .38rem .6rem; }
.bal-tabla .r, .ef-tabla .r { text-align: right; white-space: nowrap; }
.bal-tabla .c { text-align: center; }
.bal-tabla thead th { border-bottom: 1px solid var(--line); }
.bal-imp-cab { display: none; }
.bal-grupo td { background: var(--realce); font-weight: 700; font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); }
.bal-mayor td { font-weight: 600; }
.bal-sub td { color: var(--ink-2); font-size: .84rem; }
.bal-subtotal td { font-weight: 700; border-top: 1px solid var(--line-2); }
.bal-total td { font-weight: 800; border-top: 2px solid var(--ink); border-bottom: 3px double var(--ink); }
.bal-contra { color: var(--aviso-tinta); font-size: .8em; }
.bal-pie, .ef-pie { margin: .6rem 0 0; }
.bal-tabla .tb-link { font-family: var(--font-mono, monospace); font-size: .82rem; }
.ef-hojas { display: grid; gap: 1.6rem; }
.ef-cab { text-align: center; margin: .6rem 0 .5rem; font-size: .86rem; }
.ef-nombre { font-family: var(--font-display); font-size: 1.15rem; margin-top: .15rem; }
.ef-sub { color: var(--muted); font-size: .8rem; }
.ef-tabla { max-width: 52rem; margin: 0 auto; }
.ef-pct { color: var(--muted); font-size: .8rem; }
.ef-seccion td { font-weight: 800; letter-spacing: .06em; padding-top: .8rem; }
.ef-titulo td { font-weight: 700; padding-top: .6rem; }
.ef-rubro td { font-weight: 600; padding-left: 1rem; }
.ef-cuenta td:first-child { padding-left: 2rem; color: var(--ink-2); }
.ef-subtotal td { font-weight: 700; border-top: 1px solid var(--line-2); }
.ef-total td { font-weight: 800; border-top: 1px solid var(--ink); }
.ef-final td { font-weight: 800; border-top: 2px solid var(--ink); border-bottom: 3px double var(--ink); }
@media print {
  body.imprime-balanza * , body.imprime-estados * { visibility: hidden !important; }
  body.imprime-balanza #balList, body.imprime-balanza #balList *,
  body.imprime-estados .ef-hojas, body.imprime-estados .ef-hojas * { visibility: visible !important; }
  body.imprime-balanza #balList, body.imprime-estados .ef-hojas { position: absolute; left: 0; top: 0; width: 100%; padding: 0 !important; }
  body.imprime-balanza .bal-imp-cab { display: table-row; }
  body.imprime-balanza .bal-imp-cab th { text-align: left; text-transform: none; font-size: 9pt; color: #000; background: none; }
  .bal-tabla, .ef-tabla { font-size: 7.6pt; color: #000; min-width: 0 !important; }
  .bal-tabla thead { display: table-header-group; }
  .bal-tabla tr, .ef-tabla tr { break-inside: avoid; }
  .bal-tabla .tb-link { color: #000; text-decoration: none; }
  .tabla-scroll { overflow: visible !important; }
  body.imprime-estados .ef-hojas > div + div { break-before: page; }
}

/* ===== Teléfono y tableta: que ninguna opción se corte (2026-10-04) =====
 * Enrique: «en dispositivos móviles no salen completas las opciones». Lo que se cortaba a
 * 375 px: las pestañas de Impuestos (.seg: Saldos ISR, DIOT, Anual y Auditoría quedaban
 * fuera por su overflow:hidden), los Estados financieros (la rejilla .ef-hojas tomaba el
 * ancho de la tabla y .rep lo recortaba), las filas .fila de Pólizas automáticas (fecha y
 * «Ver qué haría» salían del panel) y el menú en columna, que en teléfono va en renglón y
 * partía «Punto de venta» en tres líneas. Nada de esto toca el escritorio. */
.ef-hojas { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 720px) {
  .seg { display: flex; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .seg::-webkit-scrollbar { display: none; }
  .seg button { flex: none; }
  .admin-shell .fila { flex-wrap: wrap; gap: .5rem; }
  .admin-shell .fila > * { min-width: 0; max-width: 100%; }
  .admin-shell .fila-acc, .admin-shell .rep__acciones { flex-wrap: wrap; }
  .admin-shell .btn { max-width: 100%; }
  .admin-shell input, .admin-shell select, .admin-shell textarea { max-width: 100%; }
  [data-menu="columna"] .admin-side .admin-nav-item { white-space: nowrap; width: auto; }
  .tabla-wrap, .tabla-scroll { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .pm-caja, .km-caja { max-height: calc(100dvh - 2rem); }
  .pm-fondo, .km-fondo { padding: 1rem; }
}
@media (max-width: 480px) {
  .admin-shell .btn { white-space: normal; }
  .pm-fondo, .km-fondo { padding: .5rem; }
  .pm-caja, .km-caja { max-height: calc(100dvh - 1rem); }
}

/* HERRAMIENTAS ▾ (admin.js, herrRefrescar): menú de herramientas de cada pantalla y su
   hoja lateral. Las herramientas guardadas no ocupan lugar en la lista. */
details.herr-guardado:not(.herr-en-modal) { display: none !important; }
.herr { position: relative; display: inline-flex; }
.herr[hidden] { display: none; }
.herr__menu {
  position: absolute; top: calc(100% + .35rem); right: 0; z-index: 60;
  min-width: 17rem; max-width: min(24rem, 90vw); padding: .35rem;
  background: var(--surface, #fff); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, .16);
  display: flex; flex-direction: column;
}
.herr__menu[hidden] { display: none; }
.herr__item {
  appearance: none; background: none; border: 0; border-radius: 8px; text-align: left;
  font: inherit; font-size: .92rem; color: var(--ink); padding: .6rem .75rem; cursor: pointer;
}
.herr__item:hover, .herr__item:focus { background: var(--cream, #f4f1ea); outline: none; }
.herr__item:focus-visible { box-shadow: inset 0 0 0 2px var(--realce, #2563eb); }
/* Menús con opciones fijas (data-menu-fijo: «Subir ▾», «Acciones ▾» de CFDI del SAT). */
.herr__item--peligro { color: var(--red, #b91c1c); }
.herr__item[disabled] { opacity: .5; cursor: not-allowed; }
.herr__sep { border: 0; border-top: 1px solid var(--line); margin: .25rem .2rem; }
.herr__btn[disabled] { opacity: .55; cursor: not-allowed; }
.herr-modal { position: fixed; inset: 0; z-index: 900; }
.herr-modal[hidden] { display: none; }
.herr-modal__fondo { position: absolute; inset: 0; background: rgba(15, 23, 42, .45); }
.herr-modal__hoja {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(760px, 100%);
  background: var(--surface, #fff); box-shadow: -12px 0 32px rgba(15, 23, 42, .2);
  overflow-y: auto; overscroll-behavior: contain;
}
.herr-modal__cab {
  position: sticky; top: 0; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .9rem 1.15rem; background: var(--surface, #fff); border-bottom: 1px solid var(--line);
}
.herr-modal__cab h3 { margin: 0; font-size: 1.05rem; }
.herr-modal__cuerpo { padding: 1rem 1.15rem 2rem; }
.herr-modal__cuerpo > details.herr-en-modal { margin: 0 !important; border: 0; box-shadow: none; padding: 0; background: none; }
.herr-modal__cuerpo > details.herr-en-modal > summary { display: none; }
body.herr-modal-abierto { overflow: hidden; }
@media (max-width: 640px) {
  .herr__menu {
    position: fixed; top: auto; left: 0; right: 0; bottom: 0; max-width: none; min-width: 0;
    border-radius: 16px 16px 0 0; padding: .6rem .6rem calc(.6rem + env(safe-area-inset-bottom));
    box-shadow: 0 -12px 32px rgba(15, 23, 42, .22);
  }
  .herr__item { padding: .85rem .9rem; font-size: 1rem; }
  body.herr-menu-abierto::after { content: ''; position: fixed; inset: 0; background: rgba(15, 23, 42, .35); z-index: 59; }
  .herr-modal__hoja { top: auto; left: 0; width: 100%; max-height: 92dvh; border-radius: 16px 16px 0 0; box-shadow: 0 -12px 32px rgba(15, 23, 42, .22); }
}

/* ENCABEZADOS DE TABLA SIEMPRE A LA VISTA (pedido de Enrique, 2026-10-06).
 *
 * En un listado largo, al bajar se perdía qué decía cada columna. Como `.tabla-wrap` y
 * `.tabla-scroll` desplazan de lado (`overflow-x: auto`), son contenedores de
 * desplazamiento y un `sticky` de la página no funcionaría dentro. Así que el propio
 * contenedor desplaza también hacia abajo con un alto máximo, y la cabecera se pega a
 * SU borde superior — igual que `.piv-wrap`. Una tabla corta no cambia nada: el tope
 * sólo actúa cuando la tabla es más alta que la pantalla. */
.tabla-wrap, .tabla-scroll { max-height: calc(100vh - 150px); overflow: auto; }
.tabla-wrap > .tabla-odoo > thead > tr > th, .tabla-scroll > .tabla-odoo > thead > tr > th,
.tabla-wrap > .tabla > thead > tr > th, .tabla-scroll > .tabla > thead > tr > th {
  position: sticky; top: 0; z-index: 2; background: var(--realce);
  box-shadow: inset 0 -1px 0 var(--line);
}
@media print { .tabla-wrap, .tabla-scroll { max-height: none; overflow: visible; } .tabla-wrap thead th, .tabla-scroll thead th { position: static; } }
/* En el panel la banda del encabezado es oscura (`--tabla-cab`, letra clara): la regla de
 * arriba le ponía fondo claro y el texto claro se perdía. */
.admin-shell .tabla-wrap > .tabla-odoo > thead > tr > th,
.admin-shell .tabla-scroll > .tabla-odoo > thead > tr > th { background: var(--tabla-cab); }

/* ---------- COLUMNAS FIJAS A LA IZQUIERDA (reutilizable) ----------
 *
 * `col-fija-izq` en las celdas de una columna (en tablaHTML: `cl: 'col-fija-izq'`) la pega
 * al borde izquierdo de la caja al desplazarse de lado, igual que la de acciones a la
 * derecha. La segunda fija lleva además `col-fija-izq-2` (su `left` es el ancho de la
 * primera, en `--fija-izq-2`) y la última fija, `col-fija-ult`, la que pinta la sombra
 * cuando hay tabla debajo. Fondo opaco para que no se transparente lo de abajo. El
 * encabezado sube un piso, y su cruce con una columna fija otro más: se pega en los dos
 * sentidos y debe quedar encima de todo. */
.admin-shell .tabla-scroll > .tabla-odoo td.col-fija-izq {
  position: sticky; left: 0; z-index: 3; background: var(--tarjeta);
}
.admin-shell .tabla-scroll > .tabla-odoo th.col-fija-izq { position: sticky; left: 0; z-index: 6; }
.admin-shell .tabla-scroll > .tabla-odoo:has(.col-fija-izq) > thead > tr > th { z-index: 4; }
.admin-shell .tabla-scroll > .tabla-odoo:has(.col-fija-izq) > thead > tr > th.col-fija-izq,
.admin-shell .tabla-scroll > .tabla-odoo:has(.col-fija-izq) > thead > tr > th:last-child { z-index: 6; }
.admin-shell .tabla-scroll > .tabla-odoo :is(th, td).col-fija-izq-2 { left: var(--fija-izq-2, 2.6rem); }
.admin-shell .tabla-scroll > .tabla-odoo :is(th, td).col-fija-ult { border-right: 1px solid var(--line-2); }
.admin-shell .tabla-scroll.tb-desborda > .tabla-odoo :is(th, td).col-fija-ult { box-shadow: 8px 0 10px -8px rgba(0,0,0,.35); }

/* La lista de un combo fija a la ventana (comboBusca con `fijo`): ni la caja que desplaza
 * la recorta ni las columnas pegajosas la tapan. El JS pone left/top/ancho. */
.combo__lista.combo__lista--fija { position: fixed; z-index: 500; top: 0; left: 0; }

/* ---------- ADMINISTRADOR DE CFDIs: ANCHOS QUE NO SE AMONTONAN ---------- */
.cfa-tabla .tabla-odoo :is(th, td).cfa-c-sel { width: 2.6rem; min-width: 2.6rem; max-width: 2.6rem; box-sizing: border-box; padding-left: .55rem; padding-right: .4rem; text-align: center; }
.cfa-tabla .tabla-odoo td.cfa-c-emisor { min-width: 12rem; max-width: 16rem; }
.cfa-tabla .tabla-odoo td.cfa-c-emisor .tb-clamp { min-width: 10rem; max-width: 15rem; font-weight: 600; }
.cfa-tabla .tabla-odoo td.cfa-c-fecha { white-space: nowrap; }
.cfa-tabla .tabla-odoo td.cfa-c-folio { min-width: 6.5rem; }
.cfa-tabla .tabla-odoo td.cfa-c-folio .tb-pill { display: inline-block; margin-top: .15rem; }
.cfa-tabla .tabla-odoo td.cfa-c-forma .tb-clamp { min-width: 6.5rem; max-width: 10rem; }
.cfa-tabla .tabla-odoo td.cfa-c-cta { min-width: 12.5rem; width: 12.5rem; }
.cfa-tabla .cfa-cta { width: 100%; font-size: .8rem; padding: .2rem .4rem; }
.cfa-tabla .cfa-cta-nom {
  max-width: 12rem; white-space: normal; overflow: hidden; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
}
.cfa-tabla .tabla-odoo td.cfa-c-receptor { max-width: 10rem; font-size: .8rem; }
.cfa-tabla .tabla-odoo td.cfa-c-receptor .tb-clamp { min-width: 6rem; max-width: 9.5rem; }
.cfa-tabla .cfa-ed { font-size: .8rem; padding: .2rem .4rem; box-sizing: border-box; }
.cfa-tabla .tabla-odoo td code { white-space: nowrap; }

/* ---------- TABLA EN TARJETAS EN EL TELÉFONO (reutilizable: tablaHTML con `tarjetas`) ----------
 *
 * En 375 px una tabla de quince columnas sólo se lee desplazándose de lado, y la columna
 * fija se come media pantalla. Aquí cada renglón se vuelve una tarjeta: cada dato lleva su
 * etiqueta (data-l), los campos editables ocupan su ancho y la caja deja de desplazar (la
 * página baja normal, sin scroll de lado). */
@media (max-width: 640px) {
  .tabla-wrap:has(> .tb-tarjetas) { max-height: none; overflow: visible; background: none; border: 0; box-shadow: none; }
  .admin-shell .tabla-scroll.tb-tarjetas { max-height: none; overflow: visible; }
  .admin-shell .tabla-scroll.tb-tarjetas > .tabla-odoo { min-width: 0; width: 100%; display: block; }
  .tb-tarjetas > .tabla-odoo > thead { display: none; }
  .tb-tarjetas > .tabla-odoo > tbody { display: block; }
  .admin-shell .tb-tarjetas > .tabla-odoo > tbody > tr {
    position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: .45rem .75rem;
    margin: 0 0 .7rem; padding: .7rem .8rem; background: var(--tarjeta);
    border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 1px 2px rgba(0,0,0,.04);
  }
  .admin-shell .tb-tarjetas > .tabla-odoo > tbody > tr > td {
    position: static; display: block; min-width: 0; max-width: none; width: auto;
    padding: 0; border: 0; box-shadow: none; background: none; white-space: normal;
  }
  /* Las columnas fijas no tienen nada de qué despegarse en una tarjeta. */
  .admin-shell .tabla-scroll.tb-tarjetas > .tabla-odoo td:is(.col-fija-izq, .col-fija-ult) {
    position: static; border-right: 0; box-shadow: none; background: none;
  }
  .tb-tarjetas > .tabla-odoo > tbody > tr > td[data-l]::before {
    content: attr(data-l); display: block; font-size: .7rem; font-weight: 600; letter-spacing: .02em;
    text-transform: uppercase; color: var(--muted); margin-bottom: .1rem;
  }
  .admin-shell .tb-tarjetas > .tabla-odoo > tbody > tr > td.col-acc { grid-column: 1 / -1; border-top: 1px solid var(--line); padding-top: .4rem; }
  .tb-tarjetas .tb-clamp { min-width: 0; max-width: none; }
  .tb-tarjetas input:not([type="checkbox"]) { width: 100%; font-size: 16px; min-height: 2.25rem; }

  /* El CFDI: casilla y emisor arriba, el total grande a su lado; la cuenta, a lo ancho. */
  .admin-shell .cfa-tabla .tabla-scroll.tb-tarjetas td.cfa-c-sel.col-fija-izq { position: absolute; top: .75rem; left: .75rem; width: auto; min-width: 0; max-width: none; }
  .cfa-tabla .tb-tarjetas td.cfa-c-sel input { width: 1.25rem; height: 1.25rem; margin: 0; }
  .cfa-tabla .tb-tarjetas > .tabla-odoo > tbody > tr > td:is(.cfa-c-sel, .cfa-c-emisor, .cfa-c-total)::before { display: none; }
  /* Arriba de la tarjeta: el emisor a lo ancho (junto a la casilla) y el total, grande. */
  .admin-shell .cfa-tabla .tb-tarjetas td.cfa-c-emisor { padding-left: 2rem; order: -2; grid-column: 1 / -1; }
  .admin-shell .cfa-tabla .tb-tarjetas td.cfa-c-emisor .tb-clamp { font-size: .95rem; min-width: 0; max-width: none; }
  .admin-shell .cfa-tabla .tb-tarjetas td.cfa-c-total { order: -1; grid-column: 1 / -1; padding-left: 2rem; font-size: 1.25rem; font-weight: 700; text-align: left; }
  .admin-shell .cfa-tabla .tb-tarjetas td:is(.cfa-c-cta, .cfa-c-receptor) { grid-column: 1 / -1; }
  .cfa-tabla .tb-tarjetas .cfa-cta-nom { max-width: none; }
  .cfa-tabla .tb-tarjetas .cfa-ed { width: 100% !important; }
  .cfa-tabla .tb-tarjetas td.cfa-c-chico { font-size: .8rem; }
}

/* =========================================================================
   TEMA «DESPACHOS» — /admin dentro de Kern Despachos (iframe incrustado de la ficha
   del cliente) o en una cuenta solo_despacho / kern_despacho. Sólo cambia tokens hacia
   la paleta de solo.css (navy #1F3864, acero #2E5496, oro #B8933E, gris-azulado
   #f5f7fa, líneas #e3e8ef). El rojo queda sólo para errores y borrar.
   Lo enciende admin.js con document.documentElement.dataset.marca = 'despachos'.
   ========================================================================= */
:root[data-marca="despachos"] {
  --red: #1F3864; --red-600: #2E5496; --red-700: #17294a; --red-tint: #e8edf6;
  --red-rgb: 31,56,100; --red-tinta: #2E5496;
  --ink: #1b2330; --ink-2: #2f3a4b; --muted: #5d6878; --muted-2: #6b7686;
  --line: #e3e8ef; --line-2: #d3dbe6;
  --cream: #f5f7fa; --cream-2: #eceff3; --realce: #eef2f7; --ink-band: #1F3864;
  --mal-tinta: #c0392b; --mal-fondo: #fdecec;
  --info-tinta: #2E5496; --info-fondo: rgba(46,84,150,.10);
  --neutro-fondo: #eceff3;
  --tabla-cab: #1F3864; --tabla-cab-tinta: #ffffff;
  --font-display: "Segoe UI", -apple-system, Roboto, Helvetica, Arial, sans-serif;
  --font-sans: "Segoe UI", -apple-system, Roboto, Helvetica, Arial, sans-serif;
  --serie-facturado: #1F3864; --kpi-linea: #b8c2d0;
  --doc-marca: #1F3864;
}
:root[data-marca="despachos"][data-theme="dark"] {
  --red: #3b5f9e; --red-600: #4a71b4; --red-tint: #1a2436; --red-rgb: 106,145,214; --red-tinta: #8fb0e8;
  --ink: #e6ebf2; --ink-2: #c9d2de; --muted: #9aa6b6; --muted-2: #8e9aab;
  --line: #2a3342; --line-2: #364153;
  --bg: #11161f; --cream: #161c27; --cream-2: #1d2532; --realce: #232c3b; --surface: #19202c; --tarjeta: #1d2532;
  --mal-tinta: #F0757B; --mal-fondo: #2C1618; --info-tinta: #8fb0e8;
  --tabla-cab: #24314a; --tabla-cab-tinta: #e6ebf2;
}
/* Foco con el oro de Despachos; borrar y los KPI malos siguen rojos. */
:root[data-marca="despachos"] :focus-visible { outline-color: rgba(184,147,62,.8); }
:root[data-marca="despachos"] .btn--primary:hover { background: #2E5496; box-shadow: inset 0 -2px 0 #B8933E; }
:root[data-marca="despachos"] .tb-link--danger,
:root[data-marca="despachos"] .tb-menu .tb-menu__item.tb-link--danger,
:root[data-marca="despachos"] .kpi--mal .kpi__value { color: #c0392b; }
:root[data-marca="despachos"] .kpi--mal { border-color: rgba(192,57,43,.35); }
:root[data-marca="despachos"][data-theme="dark"] .tb-link--danger,
:root[data-marca="despachos"][data-theme="dark"] .tb-menu .tb-menu__item.tb-link--danger,
:root[data-marca="despachos"][data-theme="dark"] .kpi--mal .kpi__value { color: #F0757B; }
/* Incrustado: sin fondo de página propio, toma el de la ficha. */
html.kern-incrustado[data-marca="despachos"],
html.kern-incrustado[data-marca="despachos"] body { background: transparent; }

/* ================= VACACIONES: DOS COLUMNAS =================
 * Izquierda la lista de personas, derecha la elegida (periodos, registrar, tomas).
 * Sólo tokens: con el tema despachos el resaltado y el botón salen navy/oro solos.
 * Debajo de 1200px (con el menú lateral ya no caben dos) va en una columna y «← Empleados» regresa a la lista. */
.vac-dos { display: grid; grid-template-columns: minmax(0, 38fr) minmax(0, 62fr); gap: 1rem; align-items: start; }
.vac-col { min-width: 0; padding: 1rem; }
.vac-col--emp { position: sticky; top: var(--techo, 54px); max-height: calc(100vh - var(--techo, 54px) - 1rem); display: flex; flex-direction: column; }
.vac-cab { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; margin-bottom: .6rem; }
.vac-col--emp > input[type=search] { width: 100%; margin-bottom: .5rem; padding: .4rem .6rem; font: inherit; font-size: .88rem; border: 1px solid var(--line-2, var(--line)); border-radius: 6px; background: var(--surface); color: var(--ink); }
.vac-filtros { display: flex; gap: .35rem; flex-wrap: wrap; margin-bottom: .6rem; }
.vac-chip { border: 1px solid var(--line-2); background: transparent; color: var(--ink-2); border-radius: 999px; padding: .2rem .65rem; font: inherit; font-size: .8rem; cursor: pointer; }
.vac-chip.is-on { background: var(--red); border-color: var(--red); color: #fff; }
.vac-lista { overflow: auto; min-height: 0; border: 1px solid var(--line); border-radius: 8px; outline: none; }
.vac-lista:focus-visible { box-shadow: 0 0 0 2px rgba(var(--red-rgb), .35); }
.vac-tabla { width: 100%; border-collapse: collapse; font-size: .86rem; }
.vac-tabla th { position: sticky; top: 0; background: var(--surface); text-align: left; font-weight: 600; color: var(--muted); font-size: .74rem; padding: .45rem .5rem; border-bottom: 1px solid var(--line); }
.vac-tabla td { padding: .45rem .5rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
.vac-tabla .num { text-align: right; font-variant-numeric: tabular-nums; }
.vac-tabla tbody tr { cursor: pointer; }
.vac-tabla tbody tr:hover, .vac-tabla tbody tr.is-foco { background: rgba(var(--red-rgb), .05); }
.vac-tabla tbody tr.is-sel { background: rgba(var(--red-rgb), .1); box-shadow: inset 3px 0 0 var(--red); }
.vac-tabla .tb-pill, .vac-tabla td:nth-child(2), .vac-tabla .num, .vac-nw { white-space: nowrap; }
#vacPeriodos th { white-space: nowrap; }
#vacPeriodos table { font-size: .84rem; }
#vacPeriodos th, #vacPeriodos td, #vacTomadas th, #vacTomadas td { padding-left: .45rem; padding-right: .45rem; }
.tb-pill--neutro { background: var(--neutro-fondo); color: var(--neutro-tinta); }
.vac-volver { display: none; margin-bottom: .6rem; }
.vac-quien { display: flex; justify-content: space-between; align-items: flex-start; gap: .6rem; flex-wrap: wrap; padding-bottom: .7rem; margin-bottom: .7rem; border-bottom: 1px solid var(--line); }
.vac-quien__nombre { font-size: 1.08rem; }
.vac-quien__saldo { font-size: .9rem; }
.vac-mal { color: var(--mal-tinta); }
.vac-aviso-tinta { color: var(--aviso-tinta); }
.vac-aviso { border-left: 3px solid var(--mal-tinta); background: var(--mal-fondo); border-radius: 6px; padding: .45rem .7rem; margin-bottom: .8rem; font-size: .88rem; }
.vac-aviso summary { cursor: pointer; }
#vacPeriodos tr.vac-clic { cursor: pointer; }
#vacPeriodos tr.vac-clic:hover { background: rgba(var(--red-rgb), .05); }
.vac-rejilla { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .6rem .8rem; }
.vac-rejilla .field { margin: 0; min-width: 0; }
.vac-rejilla .field input, .vac-rejilla .field select { width: 100%; }
.vac-rejilla .vac-ancho { grid-column: span 2; }
.vac-rejilla input[readonly] { background: var(--cream, transparent); color: var(--ink-2); }
.vac-prima { width: 4.2rem; text-align: right; }
@media (max-width: 1199px) {
  .vac-dos { grid-template-columns: minmax(0, 1fr); }
  .vac-col--emp { position: static; max-height: none; }
  .vac-lista { max-height: 60vh; }
  .vac-dos.is-detalle .vac-col--emp { display: none; }
  .vac-dos:not(.is-detalle) .vac-col--det { display: none; }
  .vac-volver { display: inline-flex; }
}
@media (max-width: 560px) {
  .vac-rejilla { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vac-col { padding: .75rem; }
  .vac-tabla th:nth-child(2), .vac-tabla td:nth-child(2) { display: none; }
}

/* Vacaciones: la tabla de periodos es corta y no necesita la última columna pegada a la
 * derecha; pegada, tapaba la fecha del plazo. Que quepa sin desplazarse de lado. */
.admin-shell #vacPeriodos .tabla-scroll > .tabla-odoo { min-width: 0; }
.admin-shell #vacPeriodos .tabla-scroll > .tabla-odoo th:last-child,
.admin-shell #vacPeriodos .tabla-scroll > .tabla-odoo td:last-child { position: static; border-left: 0; }
.admin-shell #vacPeriodos .tabla-odoo th, .admin-shell #vacPeriodos .tabla-odoo td { padding-left: .45rem; padding-right: .45rem; }
.admin-shell #vacPeriodos .tb-pill { white-space: nowrap; }
