
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Figtree:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500;600;700&family=Rajdhani:wght@400;500;600;700&family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&display=swap');

/* ═══════════════════════════════════════════════════════════════════
   EL SISTEMA DE DISEÑO — 1 STEP UNIFICADO
   ═══════════════════════════════════════════════════════════════════ */
:root {
  /* ── UNIDAD BASE Y RADIOS DERIVADOS ── */
  --u: 11px;
  --r-btn: calc(var(--u) * 0.75);      /* ~8px */
  --r-card: calc(var(--u) * 1.25);     /* ~14px */
  --r-panel: calc(var(--u) * 1.5);     /* ~16px */
  --r-chip: calc(var(--u) * 0.5);      /* ~5.5px */
  --r-pill: 9999px;

  /* Retrocompatibilidad */
  --r1: var(--r-chip);
  --r2: var(--r-btn);
  --r3: var(--r-card);

  /* ── ESPACIADO ── */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;

  /* ── TIPOGRAFÍA ── */
  --display: 'Outfit', 'Rajdhani', -apple-system, system-ui, sans-serif;
  --body: 'Figtree', 'Montserrat', -apple-system, system-ui, sans-serif;
  --mono: 'JetBrains Mono', monospace;
  --t-micro: 10px; --t-eti: 11px; --t-min: 12px; --t-sm: 13px;
  --t-base: 14px; --t-md: 15px; --t-lg: 17px; --t-xl: 20px;
  --t-2xl: 24px; --t-3xl: 29px;
  --tr-eti: .15em; --tr-lbl: .08em; --tr-tit: -.005em; --tr-disp: -.018em;

  /* ── MARCA Y PALETA OSCURA (Por Defecto) ── */
  --oro: #D4AF37; --oro-viva: #F5C542; --oro-osc: #BB860B; --oro-cl: #F0D77B;
  --sobre-oro: #0B0B0C;
  --plata: #C0C0C0; --bronce: #cd7f32; --azul: #0055A4; --azul-mar: #001E3C;
  --oro-t1: rgba(212,175,55,.06);
  --oro-t2: rgba(212,175,55,.12);
  --oro-t3: rgba(212,175,55,.28);

  --canvas: #0B0B0C;
  --bg: #0B0B0C;
  --pozo: #050505;
  --deep: #070707;
  --panel: #131416;
  --panel2: #1A1C20;
  --card: var(--panel);
  --card2: var(--panel2);
  --hover: #22252B;
  --line: #22252A;
  --line2: #2E323A;
  --line3: #606060;

  --ink: #FFFFFF;
  --ink2: #A1A7B4;
  --ink3: #6E7583;
  --txt: var(--ink);
  --txt2: var(--ink2);
  --txt3: var(--ink3);
  --txt4: #808080;

  --go: #2ECC71;
  --ok: var(--go);
  --warn: #F39C12;
  --stop: #E74C3C;
  --bad: var(--stop);
  --bad-cl: #ffb4ae;
  --azul-cl: #60a5fa; --violeta: #c084fc; --gris-d: #525252;

  /* Elevación */
  --luz-1: inset 0 1px 0 0 rgba(255,255,255,.067);
  --luz-2: inset 0 1px 0 0 rgba(212,175,55,.14);
  --sombra-c: 3,5,7;
  --sombra-1: 0 3px 5px -2px rgba(var(--sombra-c),.28), 0 7px 14px -5px rgba(var(--sombra-c),.30);
  --sombra-2: 0 8px 18px -6px rgba(var(--sombra-c),.55), 0 22px 42px -18px rgba(var(--sombra-c),.55);
  --pozo-1: inset 0 1px 4px 0 rgba(var(--sombra-c),.34), inset 0 1px 0 0 rgba(0,0,0,.5);
  --malla: rgba(255,255,255,.028);

  /* Movimiento */
  --ease-1: cubic-bezier(.22,1,.36,1);
  --dur-0: 80ms; --dur-1: .12s; --dur-2: .16s; --dur-3: .26s; --esc: 40ms;

  /* Armazón */
  --side: 236px; --top: 52px;
}

/* ── MODO CLARO ── */
:root[data-theme="light"] {
  --canvas: #F8F9FA;
  --bg: #F8F9FA;
  --pozo: #EDEFF2;
  --deep: #FFFFFF;
  --panel: #FFFFFF;
  --panel2: #F1F3F5;
  --card: var(--panel);
  --card2: var(--panel2);
  --hover: #E9ECEF;
  --line: #E2E6EA;
  --line2: #CED4DA;
  --line3: #ADB5BD;

  --ink: #111418;
  --ink2: #495057;
  --ink3: #6C757D;
  --txt: var(--ink);
  --txt2: var(--ink2);
  --txt3: var(--ink3);
  --txt4: #868E96;

  --oro: #B8860B; --oro-viva: #D4AF37; --oro-osc: #996515; --oro-cl: #F3E5AB;
  --sobre-oro: #0B0B0C;
  --oro-t1: rgba(184,134,11,.08);
  --oro-t2: rgba(184,134,11,.15);
  --oro-t3: rgba(184,134,11,.32);

  --go: #27AE60;
  --ok: var(--go);
  --warn: #D35400;
  --stop: #C0392B;
  --bad: var(--stop);
  --bad-cl: #FDEDEC;

  --sombra-1: 0 2px 6px rgba(0,0,0,.06), 0 4px 12px rgba(0,0,0,.04);
  --sombra-2: 0 8px 24px rgba(0,0,0,.08), 0 2px 6px rgba(0,0,0,.04);
  --luz-1: inset 0 1px 0 0 rgba(255,255,255,.8);
  --luz-2: inset 0 1px 0 0 rgba(212,175,55,.2);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0B0B0C;
    --card: #131416;
    --card2: #1A1C20;
    --txt: #FFFFFF;
    --txt2: #A1A7B4;
    --txt3: #6E7583;
  }
}

:root[data-theme="dark"] {
  --bg: #0B0B0C;
  --card: #131416;
  --card2: #1A1C20;
  --txt: #FFFFFF;
  --txt2: #A1A7B4;
  --txt3: #6E7583;
}

/* EL LIENZO */
body {
  background-color: var(--bg);
  background-image:
    radial-gradient(120% 100% at 50% 0%, rgba(0,30,60,.28) 0%, transparent 70%),
    radial-gradient(90% 70% at 100% 100%, rgba(212,175,55,.03) 0%, transparent 60%);
  background-attachment: fixed;
  margin: 0;
  color: var(--txt);
  font: 400 17px/1.62 var(--body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
  letter-spacing: .002em;
}
:root[data-theme="light"] body {
  background-image:
    radial-gradient(120% 100% at 50% 0%, rgba(0,30,60,.06) 0%, transparent 70%),
    radial-gradient(90% 70% at 100% 100%, rgba(212,175,55,.04) 0%, transparent 60%);
}
* { box-sizing: border-box; }
html, body { min-height: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  margin: 0;
  letter-spacing: var(--tr-tit);
  line-height: 1.15;
  text-wrap: balance;
}
h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); letter-spacing: var(--tr-disp); }
h2 { font-size: var(--t-2xl); letter-spacing: var(--tr-disp); }
h3 { font-size: var(--t-lg); }
h4 { font-size: var(--t-md); }
p { max-width: 64ch; margin: 0 0 var(--s3); }
.eyebrow {
  font-family: var(--display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--tr-eti);
  text-transform: uppercase;
  color: var(--txt3);
  margin-bottom: var(--s1);
}
/* numeros SIEMPRE tabulares: sin esto las columnas bailan al actualizar */
.num,.kpi b,.tbl td.num,.tag,.col-h b,time,.money{font-variant-numeric:tabular-nums lining-nums}
/* microetiquetas: el detalle que hace que se vea caro */
.eti{font-family:var(--display);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-eti);text-transform:uppercase;color:var(--txt3)}
/* texto largo: medida legible, nunca de borde a borde */
.prosa{max-width:68ch;font-size:var(--t-md);line-height:1.72;color:var(--txt)}
.prosa strong{color:var(--txt);font-weight:600}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:var(--deep)}
::-webkit-scrollbar-thumb{background:var(--txt4);border-radius:var(--r-pill)}
::-webkit-scrollbar-thumb:hover{background:var(--txt3)}
:focus-visible{outline:2px solid var(--oro);outline-offset:2px;border-radius:var(--r-chip)}
input:-webkit-autofill{-webkit-text-fill-color:var(--txt);
  -webkit-box-shadow:0 0 0 40px var(--pozo) inset;caret-color:var(--txt)}
/* selector de idioma: etiqueta + opciones, no tres botones iguales */
.lang{display:flex;align-items:center;gap:7px;justify-content:center;margin-top:16px}
.lang .eti{margin-right:2px}
.lang a{padding:5px 11px;border-radius:var(--r-chip);border:1px solid var(--line2);
  font-family:var(--display);font-size:var(--t-min);font-weight:600;letter-spacing:var(--tr-lbl);
  text-transform:uppercase;color:var(--txt2);transition:border-color var(--dur-2),color var(--dur-2)}
.lang a:hover{color:var(--txt);border-color:var(--txt3)}
.lang a.on{color:var(--oro);border-color:var(--oro);background:var(--oro-t1)}

/* ══ ARMAZON ══ */
.app{display:flex;min-height:100dvh}
.side{width:var(--side);min-width:var(--side);background:var(--deep);
  border-right:1px solid var(--line);display:flex;flex-direction:column;
  position:sticky;top:0;align-self:flex-start;height:100dvh;overflow-y:auto}
.side-logo{padding:14px var(--s4) 12px;border-bottom:1px solid var(--line)}
.brand{font-family:var(--display);font-weight:700;font-style:italic;font-size:var(--t-2xl);line-height:.95;letter-spacing:var(--tr-disp)}
.brand i{color:var(--oro);font-style:italic}
.brand em{color:var(--plata);font-style:italic}
.sub{font-family:var(--display);font-size:var(--t-micro);letter-spacing:var(--tr-eti);color:var(--txt3);
  font-weight:600;margin-top:3px}
.side-sec{font-family:var(--display);font-size:var(--t-micro);letter-spacing:var(--tr-eti);color:var(--txt3);
  font-weight:600;text-transform:uppercase;padding:14px var(--s4) 5px}
.nav-i{display:flex;align-items:center;gap:10px;padding:8px var(--s4);color:var(--txt2);
  font-size:var(--t-sm);font-weight:500;border-left:2px solid transparent;
  transition:background var(--dur-2),color var(--dur-2);cursor:pointer;min-height:36px}
.nav-i:hover{background:var(--card);color:var(--txt)}
.nav-i.on{background:linear-gradient(90deg,var(--oro-t2),transparent);
  color:var(--oro);border-left-color:var(--oro)}
.nav-i .ico{flex:none}
.nav-i .cnt{margin-left:auto;font-size:var(--t-eti);color:var(--txt3);font-variant-numeric:tabular-nums}
.ico{display:inline-flex;width:17px;height:17px}
.ico svg{width:100%;height:100%}
.side-foot{margin-top:auto;padding:12px var(--s4);border-top:1px solid var(--line)}
.who{font-size:var(--t-min);font-weight:600}
.who small{display:block;color:var(--txt3);font-size:var(--t-micro);font-family:var(--display);
  letter-spacing:var(--tr-eti);text-transform:uppercase;margin-top:1px}

.body{flex:1;display:flex;flex-direction:column;min-width:0;min-height:100dvh}
.top{height:var(--top);min-height:var(--top);display:flex;align-items:center;
  position:sticky;top:0;z-index:30;
  gap:var(--s3);padding:0 var(--s5);border-bottom:1px solid var(--line);background:var(--deep)}
.top h1{font-size:1.25rem;letter-spacing:var(--tr-tit);line-height:1.2;margin:0}
.top .crumb{font-family:var(--display);font-size:var(--t-micro);letter-spacing:var(--tr-eti);
  color:var(--txt3);text-transform:uppercase}
.spacer{flex:1}
.view{flex:1;padding:var(--s5)}

/* ══ TARJETAS Y KPI ══ */
.card{background:var(--panel);border:1px solid var(--line2);border-radius:var(--r-card);
  margin-bottom:var(--s4);box-shadow:var(--luz-1),var(--sombra-1)}
.card-h{display:flex;align-items:center;gap:8px;padding:11px var(--s4);
  border-bottom:1px solid var(--line2);
  background:linear-gradient(180deg,rgba(255,255,255,.035),transparent)}
.card-h h3{font-size:var(--t-sm);letter-spacing:var(--tr-lbl);text-transform:uppercase;color:var(--txt2)}
.card-b{padding:var(--s4)}
.kpis{display:grid;gap:var(--s3);grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
  margin-bottom:var(--s4)}
.kpi{background:linear-gradient(145deg,var(--panel2),var(--panel));
  border:1px solid var(--line2);border-radius:var(--r-card);padding:13px var(--s4);
  position:relative;overflow:hidden;box-shadow:var(--luz-2),var(--sombra-1)}
.kpi:before{content:'';position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--oro)}
.kpi b{display:block;font-family:var(--display);font-size:var(--t-3xl);font-weight:700;line-height:1.02;
  font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.kpi small{font-family:var(--display);color:var(--txt3);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-eti);text-transform:uppercase}
.kpi.g b{color:var(--oro)} .kpi.ok b{color:var(--ok)}

/* ══ TABLAS DENSAS ══ */
.tbl{width:100%;border-collapse:collapse;font-size:var(--t-sm)}
/* La REJILLA es la interfaz en un producto denso. El filete de --line
   sobre --card daba 1,17:1: bajo sol directo desaparecia y el vendedor
   leia la fila de al lado. --line3 da 3,0:1, el minimo de WCAG 1.4.11
   para un elemento no textual que transmite estructura. Solo en .tbl:
   el resto de bordes no cambia. Ni un pixel de alto de fila.          */
.tbl th{position:sticky;top:0;background:var(--card2);text-align:left;font-family:var(--display);
  color:var(--txt3);font-size:var(--t-micro);font-weight:600;letter-spacing:var(--tr-lbl);text-transform:uppercase;
  padding:9px var(--s3);border-bottom:1px solid var(--txt4);white-space:nowrap}
.tbl td{padding:9px var(--s3);border-bottom:1px solid var(--line3);vertical-align:middle}
.tbl tbody tr{transition:background var(--dur-1);cursor:pointer}
.tbl tbody tr:hover{background:var(--hover)}
.tbl .num{font-variant-numeric:tabular-nums;text-align:right}
/* .wrap solo da scroll HORIZONTAL a tablas anchas. Antes tenia max-height y
   creaba un segundo scroll vertical dentro del scroll de la pagina: el
   contenido de abajo (formularios, leyendas) quedaba inalcanzable.        */
.wrap{overflow-x:auto;overflow-y:visible;max-height:none}
/* primer lugar de la tabla de posiciones: se marca SIN romper la rejilla */
.tbl tr.fila-top td,.tbl tr.fila-top th{background:var(--oro-t1)}
.tbl tr.fila-top td:first-child,.tbl tr.fila-top th:first-child{
  box-shadow:inset 2px 0 0 var(--oro)}
.tbl tr.fila-top td{color:var(--txt)}
/* Encabezado de FILA: es un dato, no una microetiqueta de columna.
   Con el estilo de <th> salia en mayusculas, diminuto y gris: fallaba AA. */
.tbl tbody th[scope="row"]{font-family:var(--body);font-size:var(--t-sm);
  font-weight:600;letter-spacing:0;text-transform:none;color:var(--txt);
  border-bottom:1px solid var(--line3);padding:9px var(--s3)}
.tbl tbody th[scope="row"] a{display:inline-flex;align-items:center;gap:7px;color:var(--txt)}
.tbl tbody th[scope="row"] a:hover{color:var(--oro)}
/* la linea de tiempo es una lista, sin vinetas ni numeros decorativos */
ul.time,ol.time{list-style:none;margin:0;padding-left:15px}
ul.time>li,ol.time>li{list-style:none}
ul.time>li::marker,ol.time>li::marker{content:''}
.ev-lead{font-weight:600;color:var(--txt);background:none;border:0;padding:0}
.ev-lead:hover{color:var(--oro)}
a.ev-lead{text-decoration:underline;text-decoration-color:var(--oro-t3);
  text-underline-offset:3px}
.ev{display:flex;flex-wrap:wrap;align-items:baseline;gap:7px}
.ev-lead{font-weight:600;color:var(--txt)}
.por{color:var(--txt2);font-size:var(--t-min)}
.ev time,.ev small{color:var(--txt3);font-size:var(--t-min)}

/* ══ CONTROLES ══ */
label{display:block;font-family:var(--display);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-eti);text-transform:uppercase;color:var(--txt3);margin:10px 0 4px}
input,select,textarea{font:inherit;width:100%;padding:9px 11px;border-radius:var(--r-btn);
  border:1px solid var(--line2);background:var(--pozo);color:var(--txt);min-height:40px;
  transition:border-color var(--dur-2)}
input::placeholder,textarea::placeholder{color:var(--txt3)}
textarea{min-height:74px;resize:vertical}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:10px 18px;border:1px solid transparent;border-radius:var(--r-btn);font-family:var(--display);font-weight:700;
  font-size:var(--t-sm);letter-spacing:var(--tr-lbl);text-transform:uppercase;cursor:pointer;min-height:40px;
  background:linear-gradient(135deg,var(--oro-viva),var(--oro-osc));color:var(--sobre-oro);
  box-shadow:0 2px 8px rgba(212,175,55,.25);
  transition:background 150ms var(--ease-1),border-color 150ms var(--ease-1),
             color 150ms var(--ease-1),transform 120ms var(--ease-1),
             box-shadow 150ms var(--ease-1),filter 150ms var(--ease-1);width:auto;user-select:none}
.btn:hover{filter:brightness(1.1);transform:translateY(-1px);box-shadow:0 4px 14px rgba(212,175,55,.35)}
.btn:active{transform:translateY(1px);filter:brightness(0.95);box-shadow:0 1px 4px rgba(212,175,55,.2)}
.btn:focus-visible{outline:2px solid var(--oro);outline-offset:2px}
.btn:disabled,.btn[disabled]{opacity:.45;cursor:not-allowed;pointer-events:none;transform:none;box-shadow:none}

/* Nivel 2: Secundario */
.btn.line,.btn.secundario{background:transparent;border:1px solid var(--line2);color:var(--ink);box-shadow:none}
.btn.line:hover,.btn.secundario:hover{border-color:var(--oro);color:var(--oro);background:var(--oro-t1);filter:none;box-shadow:0 2px 10px rgba(0,0,0,.15)}
.btn.line:active,.btn.secundario:active{background:var(--oro-t2)}

/* Nivel 3: Fantasma */
.btn.ghost,.btn.fantasma{background:transparent;border-color:transparent;color:var(--ink2);box-shadow:none}
.btn.ghost:hover,.btn.fantasma:hover{background:var(--oro-t1);color:var(--ink);border-color:transparent;filter:none;transform:none}
.btn.ghost:active,.btn.fantasma:active{background:var(--oro-t2)}

.btn.sm{padding:6px 12px;min-height:32px;font-size:var(--t-min);border-radius:var(--r-chip)}
.btn.full{width:100%}
.row{display:flex;gap:var(--s2);flex-wrap:wrap}
.grid{display:grid;gap:var(--s3);grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}

/* ══ ETIQUETAS ══ */
.tag{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:var(--r1);
  font-family:var(--display);font-size:var(--t-eti);font-weight:600;letter-spacing:var(--tr-lbl);
  text-transform:uppercase;background:var(--oro-t2);color:var(--oro);
  border:1px solid var(--oro-t3);white-space:nowrap}
.tag.mute{background:var(--card2);color:var(--txt3);border-color:var(--line2)}
.tag.ok{background:rgba(63,185,80,.12);color:var(--ok);border-color:rgba(63,185,80,.3)}
.tag.bad{background:rgba(248,81,73,.11);color:var(--bad);border-color:rgba(248,81,73,.3)}

/* ══ PIPELINE ══ */
/* El 190px estaba calibrado para el armazon viejo, donde .view era el que
   desplazaba. Ahora desplaza la pagina y el tablero arranca ~300px abajo:
   con 190 se salia 108px por el borde. Medido, no adivinado.          */
.board{display:flex;gap:var(--s3);overflow-x:auto;height:calc(100dvh - 310px);
  min-height:320px;padding-bottom:var(--s2)}
.col{min-width:232px;flex:1;display:flex;flex-direction:column;background:var(--deep);
  border:1px solid var(--line);border-radius:var(--r3)}
.col-h{display:flex;align-items:center;justify-content:space-between;padding:9px var(--s3);
  border-bottom:1px solid var(--line);font-family:var(--display);font-size:var(--t-eti);font-weight:600;
  letter-spacing:var(--tr-eti);text-transform:uppercase;color:var(--txt2)}
.col-h b{font-variant-numeric:tabular-nums;color:var(--oro)}
.col-b{padding:var(--s2);overflow-y:auto;flex:1}
.lead{display:block;background:var(--card);border:1px solid var(--line);border-left:2px solid var(--oro);
  border-radius:var(--r2);padding:9px 11px;margin-bottom:7px;transition:border-color var(--dur-2),background var(--dur-2)}
.lead:hover{background:var(--card2);border-left-color:var(--oro-cl)}
.lead b{display:block;font-size:var(--t-sm);font-weight:600}
.lead small{color:var(--txt3);font-size:var(--t-eti);font-variant-numeric:tabular-nums}

/* ══ CATALOGO ══ */
.pkgs{display:grid;gap:var(--s3);grid-template-columns:repeat(auto-fill,minmax(268px,1fr))}
.pkg{display:block;background:var(--card);border:1px solid var(--line);border-radius:var(--r3);
  padding:var(--s4);transition:border-color var(--dur-2),transform var(--dur-1);position:relative;overflow:hidden}
.pkg:hover{border-color:var(--oro-t3);transform:translateY(-1px)}
.pkg:after{content:'';position:absolute;right:-34px;top:-34px;width:88px;height:88px;
  background:linear-gradient(135deg,var(--oro-t2),transparent);transform:rotate(45deg)}
.pkg .n{font-family:var(--display);font-size:var(--t-micro);letter-spacing:var(--tr-eti);color:var(--txt3)}
.pkg h3{font-size:var(--t-lg);margin:6px 0 3px}
.pkg .tl{color:var(--oro);font-size:var(--t-min)}
.pkg .mt{color:var(--txt3);font-size:var(--t-eti);margin-top:9px;display:flex;align-items:center;gap:6px}
.pkg .badge{position:absolute;top:var(--s4);right:var(--s4);width:34px;height:34px;
  display:flex;align-items:center;justify-content:center;border-radius:var(--r2);
  background:var(--oro-t1);border:1px solid var(--oro-t2);color:var(--oro)}
.pkg .badge .ico{width:19px;height:19px}

/* ══ LINEA DE TIEMPO ══ */
.time{border-left:1px solid var(--line2);padding-left:15px;margin-left:5px}
.ev{position:relative;padding-bottom:14px;font-size:var(--t-sm)}
.ev:before{content:'';position:absolute;left:-19.5px;top:6px;width:7px;height:7px;
  border-radius:var(--r-pill);background:var(--oro);box-shadow:0 0 0 3px var(--card)}
.ev small{color:var(--txt3);font-size:var(--t-eti);font-variant-numeric:tabular-nums}

.aviso{background:var(--oro-t1);border:1px solid var(--oro-t3);color:var(--oro-cl);
  padding:10px 13px;border-radius:var(--r2);margin-bottom:var(--s3);font-size:var(--t-sm)}
.aviso.bad{background:rgba(248,81,73,.07);border-color:rgba(248,81,73,.3);color:var(--bad-cl)}
.empty{color:var(--txt3);text-align:center;padding:38px var(--s4);font-size:var(--t-sm)}
.empty .ico{width:28px;height:28px;margin-bottom:9px;opacity:.5}

.av{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;
  border-radius:50%;background:var(--card);border:1px solid var(--line2);flex:none}
.av img{width:100%;height:100%;object-fit:cover;display:block}
.av-ini{font-family:var(--display);font-weight:700;color:var(--txt3)}
.av-xl{width:96px;height:96px}.av-xl .av-ini{font-size:var(--t-3xl)}
.av-sm{width:30px;height:30px}.av-sm .av-ini{font-size:var(--t-min)}
.who-fila{display:flex;align-items:center;gap:9px}
.con-av{display:inline-flex;align-items:center;gap:8px}
.av-fila{display:flex;gap:var(--s4);align-items:center;flex-wrap:wrap}
.av-fila form{display:grid;gap:var(--s2)}
.aviso-ok{margin:0 0 1rem;padding:.7rem .9rem;border-radius:0 var(--r2) var(--r2) 0;font-size:var(--t-sm);
  border:1px solid var(--line2);border-left:2px solid var(--ok);background:rgba(63,185,80,.06)}

.pago-h{font-size:var(--t-lg);margin:0 0 .6rem;color:var(--txt2)}
.kpi.ok b{color:var(--ok)}

/* ── clases que las vistas YA usan y que NUNCA se definieron ──────────
   Medido: .mute suelta (no .tag.mute) en catalogo.js:240, micuenta.js:47,
   pkgnuevo.js:29 y podio.js:79; .pill suelta en catalogo.js:263 y
   podio.js:52; .aviso-idioma en catalogo.js:265/279, micuenta.js:14 y
   pkgnuevo.js:8 (solo existia dentro de .cat, no global).
   Sin regla, una nota de ayuda salia con el MISMO brillo que el texto
   principal y la insignia "TU" del podio salia como texto pelado. Eso es
   justo el aspecto de plantilla. Cero colores nuevos: solo tokens de marca.
   Contraste medido sobre --card #0e0e0e (WCAG AA pide 4.5:1):
     .mute          --txt2 #a8a8a8                 -> 8.12:1  OK
     .pill          --oro #D4AF37 sobre tinte .14  -> 7.91:1  OK
     .aviso-idioma  --txt2 sobre tinte oro .05     -> 7.61:1  OK              */
.mute{color:var(--txt2)}
p.mute{font-size:var(--t-sm);line-height:1.6;margin:var(--s3) 0 0;max-width:64ch}
.pill{display:inline-flex;align-items:center;gap:4px;padding:1px 8px;border-radius:var(--r-pill);
  font-family:var(--display);font-size:var(--t-micro);font-weight:700;letter-spacing:var(--tr-eti);
  text-transform:uppercase;color:var(--oro);background:var(--oro-t2);
  border:1px solid var(--oro-t3);white-space:nowrap;line-height:1.75}
.aviso-idioma{margin:0 0 1.1rem;padding:.7rem .9rem;font-size:var(--t-sm);color:var(--txt2);
  border:1px solid var(--line2);border-left:2px solid var(--oro);
  border-radius:0 var(--r2) var(--r2) 0;background:var(--oro-t1)}

/* Grafica de columnas del podio. Sin SVG, sin libreria: alturas en %. */
.graf{display:flex;align-items:flex-end;gap:clamp(8px,2.4vw,22px);height:190px;
  padding:14px 4px 0;margin:0 0 var(--s4);overflow-x:auto}
/* La regla global .col (columna del PIPELINE, linea 196) le mete background,
   border y border-radius. .graf .col no los anulaba, asi que cada columna de
   la grafica salia dentro de una cajita con borde: parecia una tabla, no una
   grafica. Medido en la cascada, no adivinado. */
.graf .col{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
  height:100%;flex:1 1 0;min-width:38px;
  background:none;border:0;border-radius:0;padding:0}
.graf .col-v{font-family:var(--display);font-size:var(--t-min);font-weight:700;
  color:var(--txt2);margin-bottom:6px;font-variant-numeric:tabular-nums}
/* flex:none y padding:0 NO son adorno, son EL arreglo. La regla global
   .col-b (linea 202) trae flex:1 y padding:8px. flex:1 == flex:1 1 0%, y en
   un contenedor flex en columna el flex-basis GANA sobre height: por eso
   TODAS las barras salian de la misma altura y --h no pintaba nada. El
   keyframe 'sube' tampoco servia por lo mismo. Con flex:none manda height.
   El segundo inset (--oro-cl a .55) es el filo metalico de arriba. */
.graf .col-b{flex:none;padding:0;
  width:100%;max-width:46px;height:var(--h);border-radius:var(--r1) var(--r1) 2px 2px;
  background:linear-gradient(180deg,rgba(212,175,55,.85),var(--oro-t2));
  box-shadow:0 0 0 1px var(--oro-t2) inset,0 1px 0 rgba(240,215,123,.55) inset;
  animation:sube .6s cubic-bezier(.22,1,.36,1) both}
.graf .col.p1 .col-b{background:linear-gradient(180deg,var(--oro),var(--oro-t2));
  box-shadow:0 0 18px -4px rgba(212,175,55,.5)}
.graf .col.p2 .col-b{background:linear-gradient(180deg,var(--plata),rgba(216,216,216,.12))}
.graf .col.p3 .col-b{background:linear-gradient(180deg,var(--bronce),rgba(205,127,50,.12))}
.graf .col.yo .col-v{color:var(--oro)}
.graf .col-n{margin-top:8px;font-size:var(--t-micro);letter-spacing:var(--tr-lbl);color:var(--txt3);
  font-family:var(--display);font-weight:600}
@keyframes sube{from{height:0}to{height:var(--h)}}
@media(prefers-reduced-motion:reduce){.graf .col-b{animation:none}}

/* Botones: dejaron de estirarse a todo lo ancho dentro de un grid.
   Un boton de 900 px de ancho se ve barato, no premium. */
.card-b form.grid > button,.card-b form.campos > button{justify-self:start;
  min-width:170px;width:auto}
.card-b form.grid,.card-b form.campos{align-items:end}

/* El dueno lo dijo claro: las barras HORIZONTALES se ven horribles. Se quitan.
   La comparacion ya la hace la grafica de columnas VERTICALES de arriba
   (.graf); duplicarla en horizontal detras del nombre solo ensuciaba la tabla.
   Queda un rail de 2px en la celda de posicion — el MISMO lenguaje que .kpi:before.
   podio.js sigue emitiendo style="--barra:X%": queda como propiedad personalizada
   muerta, no pinta nada y no hace falta tocar la vista.
   #c9c9c9 y #cd7f32 ya estaban en este archivo (lineas .pod.p2/.p3): cero colores nuevos. */
.tbl tr.pod > th:first-of-type{position:relative;padding-left:10px}
.tbl tr.pod > td:first-child{position:relative}
.tbl tr.pod.p1 > td:first-child::before,
.tbl tr.pod.p2 > td:first-child::before,
.tbl tr.pod.p3 > td:first-child::before{content:'';position:absolute;
  left:0;top:3px;bottom:3px;width:2px;border-radius:2px}
.tbl tr.pod.p1 > td:first-child::before{background:var(--oro)}
.tbl tr.pod.p2 > td:first-child::before{background:var(--plata)}
.tbl tr.pod.p3 > td:first-child::before{background:var(--bronce)}

/* Podio: oro/plata/bronce con CSS, sin imagenes. */
.tbl tr.pod .pos{font-family:var(--display);font-weight:700;color:var(--txt3)}
.tbl tr.pod.p1{background:var(--oro-t2)}
.tbl tr.pod.p1 .pos{color:var(--oro)}
.tbl tr.pod.p2{background:rgba(190,190,190,.07)}
.tbl tr.pod.p2 .pos{color:var(--plata)}
.tbl tr.pod.p3{background:rgba(205,127,50,.08)}
.tbl tr.pod.p3 .pos{color:var(--bronce)}
.tbl tr.pod.yo th{color:var(--oro)}
.tbl tr.pod.yo .pill{background:var(--oro-t2);border-color:var(--oro)}
.tbl td.num,.tbl th.num{text-align:right;font-variant-numeric:tabular-nums}
.tbl td.pos,.tbl th.pos{width:3rem}

/* ══ MOVIL ══ */
.burger{display:none;background:none;border:0;color:var(--txt);padding:6px;cursor:pointer}
@media(max-width:860px){
  :root{--side:0px}
  .side{position:fixed;inset:0 auto 0 0;width:250px;min-width:250px;z-index:60;
    transform:translateX(-100%);transition:transform .22s ease-out;
    box-shadow:var(--sombra-2)}
  #m:checked ~ .app .side{transform:none}
  #m:checked ~ .app .scrim{opacity:1;pointer-events:auto}
  .scrim{position:fixed;inset:0;background:rgba(0,0,0,.62);z-index:50;opacity:0;
    pointer-events:none;transition:opacity .22s}
  .burger{display:inline-flex}
  .view{padding:var(--s3)}
  .top{padding:0 var(--s3)}
  .hide-sm{display:none}
  .kpis{grid-template-columns:repeat(2,1fr)}
  .board{height:auto;flex-direction:column}
  .col{min-width:0}
}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ── Formularios dentro de tarjetas ──────────────────────────────────
   El boton iba dentro de un form.row y heredaba flex:1: se estiraba y
   quedaba alineado con la ETIQUETA en vez de con el control.            */
form.row{align-items:flex-end;gap:var(--s3)}
form.row>.grid,form.row>span.grid{flex:1 1 auto;min-width:0;margin:0}
form.row>button,form.row>.btn{flex:0 0 auto;margin:0;min-width:180px;height:40px}
form.row label{margin-top:0}
form.row textarea{min-height:40px}
/* Si la tarjeta ya lleva titulo, la etiqueta repetida se oculta a la vista
   pero sigue existiendo para el lector de pantalla.                      */
.card-h + .card-b form > label:first-of-type,
form.row > .grid > label.dup{position:absolute;width:1px;height:1px;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0}

/* EXCEPCION: la regla de arriba oculta la PRIMERA etiqueta "porque el titulo
   ya lo dice". Eso vale para un buscador de un solo campo. En un formulario de
   varios campos hace desaparecer un campo entero — paso de verdad: se perdio
   Nombre, Contrasena actual y el selector de archivo. */
.card-h + .card-b form.grid > label:first-of-type,
.card-h + .card-b form.campos > label:first-of-type{position:static;width:auto;
  height:auto;overflow:visible;clip-path:none;white-space:normal;margin:0}
@media(max-width:720px){
  form.row{flex-direction:column;align-items:stretch}
  form.row>button,form.row>.btn{width:100%;min-width:0}
}

/* ── Pestañas de linea de negocio ────────────────────────────────────
   Iban en un <ul> y salian con viñeta. En movil se apilaban y comian
   la pantalla entera: ahora ruedan en horizontal, como en una app.     */
.board-tabs,.tabs-linea,.view ul.row,.view ol.row{list-style:none;margin:0 0 var(--s3);
  padding:0;display:flex;gap:7px;overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;scroll-snap-type:x proximity}
.board-tabs::-webkit-scrollbar,.tabs-linea::-webkit-scrollbar,
.view ul.row::-webkit-scrollbar{display:none}
.board-tabs>li,.tabs-linea>li,.view ul.row>li{list-style:none;flex:0 0 auto;
  scroll-snap-align:start;min-width:0}
.board-tabs>li::marker,.tabs-linea>li::marker,.view ul.row>li::marker{content:''}
.view ul.row>li>a,.board-tabs a{white-space:nowrap}

/* Foco programatico: al enviar, la vista mueve el foco al resultado para
   que el lector de pantalla lo anuncie. El anillo va en oro, no en blanco. */
[tabindex]:focus-visible,h1:focus-visible,h2:focus-visible,h3:focus-visible,
[role="status"]:focus-visible,section:focus-visible{
  outline:2px solid var(--oro);outline-offset:4px;border-radius:var(--r1)}
[tabindex="-1"]:focus:not(:focus-visible){outline:none}

/* ── kpi-fix ──────────────────────────────────────────────────────────
   Las tarjetas del mapa traen icono + numero + etiqueta en linea y salian
   empalmados: "⊞8PUERTAS". Se apilan: icono arriba, numero grande, etiqueta
   debajo. Se arregla aqui y no en la vista para que valga en TODAS.        */
.kpi{display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  padding:13px var(--s4) 14px}
/* El mismo icono repetido en los 5 KPI no aporta informacion: es adorno.
   Fuera. El numero es el protagonista. (Si algun dia cada KPI lleva SU
   icono distinto, se quita este display:none.)                            */
.kpi > .ico{display:none}
.kpi b,.kpi > span,.kpi strong{display:block;width:100%}
.kpi small{display:block;width:100%;margin-top:1px;line-height:1.35}
/* Avisos con icono: separacion real entre el simbolo y el texto */
.aviso{display:flex;align-items:flex-start;gap:9px;line-height:1.5}
.aviso > .ico{flex:none;width:16px;height:16px;margin-top:2px}
/* Botones y pestañas con icono: idem */
.btn > .ico,.tag > .ico{flex:none;margin-right:1px}
.card-h > .ico{flex:none}

/* Una direccion en una fila de tabla es un ENLACE, no un boton. Con .btn
   dorado cada fila gritaba lo mismo y la tabla perdia jerarquia: el dato
   que importa es el ESTADO, no la direccion.                              */
.tbl td .btn,.tbl th .btn{background:none;border:0;color:var(--txt);
  padding:0;min-height:0;font-family:var(--body);font-size:var(--t-sm);
  font-weight:600;letter-spacing:0;text-transform:none;text-align:left;
  justify-content:flex-start}
.tbl td .btn:hover{color:var(--oro);filter:none}
.tbl td .btn > .ico{display:none}

/* ── scroll-visible ──────────────────────────────────────────────────
   La barra era casi negra sobre fondo negro: el usuario creia que la
   pagina estaba cortada cuando solo faltaba desplazarse. Ahora se ve.   */
.view{scrollbar-width:auto;scrollbar-color:var(--txt4) var(--deep);
  scroll-behavior:smooth;padding-bottom:var(--s6)}
.view::-webkit-scrollbar{width:12px}
.view::-webkit-scrollbar-track{background:var(--deep);border-left:1px solid var(--line)}
.view::-webkit-scrollbar-thumb{background:var(--txt4);border-radius:var(--r3);
  border:3px solid var(--deep)}
.view::-webkit-scrollbar-thumb:hover{background:var(--oro-osc)}


/* == ANCHO DE BOTON =====================================================
   "full" = ancho del contenedor. En una tarjeta de 1100px eso es un boton
   de ~900px: justo lo que el dueno dijo que se ve barato. Casos medidos:
   cerebro.js:83 y equipo.js:183/:312. En movil sigue al 100%: ahi el pulgar
   lo agradece. .login-submit se excluye: su tarjeta mide 420px.          */

/* == PASADA PREMIUM =====================================================
   Solo presentacion. Ni un color nuevo: todo sale de :root. Va al FINAL a
   proposito: se revierte borrando este bloque entero.                    */

/* Titulo de tarjeta unificado.
   :not(h1) NO es adorno: leads.js:189 y :228 ponen <h1 class="row card-t">
   DENTRO de .card > .card-h. Sin la exclusion, el titulo de /leads y /nuevo
   pasaba de 20px #f2f2f2 a 13px MAYUSCULAS gris. Verificado en navegador. */
.card > .card-h > h2:not(h1),.card > .card-h > h3,
.card > .card-h > .card-t:not(h1){
  font-family:var(--display);font-size:var(--t-sm);font-weight:700;letter-spacing:var(--tr-lbl);
  text-transform:uppercase;color:var(--txt2);margin:0;line-height:1.3}

/* El :not(.btn .ico) evita oro-sobre-oro: pipeline.js:94 mete un <a class="btn sm">
   dorado DENTRO de .card-h; su icono heredaba #1a1200 (13.01:1) y pasaba a
   oro sobre oro = 1.47:1, cuando WCAG 1.4.11 pide 3:1. */
.card-h > .ico,.card-h > a:not(.btn) .ico,.card-h > h2 .ico,.card-h > h3 .ico{
  color:var(--oro);opacity:.9}

/* KPI: filo en degradado + brillo de esquina, el mismo lenguaje que .pkg:after. */
.kpi:after{content:"";position:absolute;right:-26px;top:-26px;width:70px;height:70px;
  background:linear-gradient(135deg,var(--oro-t2),transparent);
  transform:rotate(45deg);pointer-events:none;z-index:0}
.kpi b,.kpi small,.kpi dt,.kpi dd{position:relative;z-index:1}

/* Tabla: cebra casi invisible (alfa .013).
   El :not(:hover) es OBLIGATORIO: sin el, la cebra (0,4,2) MATA a
   .tbl tbody tr:hover (0,2,2) y la MITAD de las filas de todas las tablas
   dejaban de reaccionar al raton, mientras cursor:pointer seguia diciendo
   que eran clicables. Medido en navegador.                               */
.tbl tbody tr:nth-child(even):not(.pod):not(.fila-top):not(:hover){
  background:rgba(255,255,255,.013)}
.tbl tbody tr:hover td:first-child,.tbl tbody tr:hover th:first-child{
  box-shadow:inset 2px 0 0 var(--oro)}

/* .tbl td .btn es, a proposito, el ENLACE de la direccion: sin esta
   exclusion cada fila quedaba con raya blanca y halo dorado. */
.tbl td .btn,.tbl th .btn,.tbl td .btn:hover,.tbl th .btn:hover{box-shadow:none}
@media(prefers-reduced-motion:reduce){.btn,.btn:hover{transition:none}}

/* ═══════════════════════════════════════════════════════════════════
   CAPA PREMIUM 2 — de los 15 recursos de UI, filtrados por la realidad
   del proyecto (sin dependencias externas, sin build, CSP cerrada).
   Cero <script src>. Ordenada de MAS a MENOS impacto.
   ═══════════════════════════════════════════════════════════════════ */

/* ── ELEVACION — una sola familia para toda la interfaz ── */
.pkg{box-shadow:var(--luz-1),var(--sombra-1)}

/* ── B2 · MALLA TECNICA, enmascarada bajo la cabecera ─────────────── */
body::before{
  content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(to right,var(--malla) 1px,transparent 1px),
    linear-gradient(to bottom,var(--malla) 1px,transparent 1px);
  background-size:14px 24px;
  -webkit-mask-image:radial-gradient(ellipse 62% 46% at calc(50% + var(--side)/2) 0%,#000 62%,transparent 100%);
          mask-image:radial-gradient(ellipse 62% 46% at calc(50% + var(--side)/2) 0%,#000 62%,transparent 100%);
}

/* ── C1 · EL PODIO DEJA DE MENTIR ─────────────────────────────────
   Las etiquetas salen del flujo: asi el 100% de --h cabe EXACTO. El tope
   provisional de la tanda 1 (max-height) recortaba toda barra por encima
   del 78%, o sea que dos vendedores al 100% y al 85% salian IGUALES.
   Esto lo sustituye y ya no hace falta tocar podio.js.                 */
.graf .col{background:none;border:0;border-radius:0;
  position:relative;padding:22px 0 20px}
.graf .col-v{position:absolute;top:0;left:0;right:0;margin:0;text-align:center}
.graf .col-n{position:absolute;bottom:0;left:0;right:0;margin:0;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.graf .col-b{flex:0 0 auto;padding:0;overflow:visible;max-height:none;
  transform-origin:bottom;animation:barra var(--dur-3) var(--ease-1) backwards}
@keyframes barra{from{transform:scaleY(0)}}
.graf .col:nth-child(2) .col-b{animation-delay:calc(var(--esc)*1)}
.graf .col:nth-child(3) .col-b{animation-delay:calc(var(--esc)*2)}
.graf .col:nth-child(4) .col-b{animation-delay:calc(var(--esc)*3)}
.graf .col:nth-child(5) .col-b{animation-delay:calc(var(--esc)*4)}
.graf .col:nth-child(6) .col-b{animation-delay:calc(var(--esc)*5)}
.graf .col:nth-child(7) .col-b{animation-delay:calc(var(--esc)*6)}
.graf .col:nth-child(n+8) .col-b{animation-delay:calc(var(--esc)*7)}

/* ── C6 · el resplandor del 1o se cortaba: .graf clipa en ambos ejes ── */
.graf .col.p1 .col-b{
  background:
    radial-gradient(72% 30px at 50% 0%,rgba(212,175,55,.55),rgba(212,175,55,0) 100%),
    linear-gradient(180deg,var(--oro),var(--oro-t2));
  box-shadow:0 0 0 1px var(--oro-t3) inset}

/* ── C10 · una sola plata y un solo bronce (habia 3 y 4) ──────────── */
.graf .col.p2 .col-b{background:linear-gradient(180deg,var(--plata),color-mix(in srgb,var(--plata) 12%,transparent))}
.graf .col.p3 .col-b{background:linear-gradient(180deg,var(--bronce),color-mix(in srgb,var(--bronce) 12%,transparent))}
.tbl tr.pod.p2 .pos{color:var(--plata)}
.tbl tr.pod.p3 .pos{color:var(--bronce)}

/* ── B3 · ESTADOS QUE NO EXISTIAN ─────────────────────────────────
   BUG VIVO: public/app.js deshabilita TODO form[method=post] durante 8s
   y en styles.js no habia NI UNA regla :disabled. El boton seguia dorado
   y el hover lo iluminaba mientras estaba inerte.                      */
.btn:disabled,.btn[aria-disabled="true"]{
  background:var(--card2);color:var(--txt3);
  box-shadow:inset 0 0 0 1px var(--line2);
  cursor:not-allowed;filter:none;transform:none}
.btn:disabled:hover,.btn[aria-disabled="true"]:hover{
  filter:none;transform:none;color:var(--txt3);background:var(--card2)}
.btn.line:disabled{background:transparent;box-shadow:none;
  border-color:var(--line);color:var(--txt3)}
.btn{position:relative;overflow:hidden}
.btn[data-enviando]::after{content:'';position:absolute;left:0;bottom:0;
  height:2px;width:100%;background:currentColor;opacity:.55;
  transform-origin:left;animation:cargando 1.1s var(--ease-1) infinite}
@keyframes cargando{0%{transform:scaleX(0);opacity:.55}
  70%{transform:scaleX(1);opacity:.55}100%{transform:scaleX(1);opacity:0}}
::selection{background:var(--oro);color:var(--azul-mar);text-shadow:none}
::-moz-selection{background:var(--oro);color:var(--azul-mar);text-shadow:none}
.tbl tbody tr:active{background:var(--card2)}
.nav-i:active,.lead:active{background:var(--hover)}
.tbl tbody tr:focus-within{background:var(--hover)}
.tbl tbody tr:focus-within > th:first-of-type{box-shadow:inset 2px 0 0 var(--oro)}

/* ── C4 · habia DOS reglas de foco contradictorias y ganaba la que lo
   APAGA (linea 165 pisaba a la 53). El anillo del campo no existia.    */
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--oro);outline-offset:1px;border-color:var(--oro);
  box-shadow:0 0 0 3px var(--oro-t2),var(--pozo-1)}
input:focus:not(:focus-visible),select:focus:not(:focus-visible),
textarea:focus:not(:focus-visible){outline:none;border-color:var(--oro);
  box-shadow:var(--pozo-1)}

/* ── C5 · el boton responde como materia, con UNA sola curva ──────── */
.btn{transition:filter var(--dur-2) var(--ease-1),
                transform var(--dur-2) var(--ease-1),
                border-color var(--dur-2) var(--ease-1),
                color var(--dur-2) var(--ease-1)}
.btn:active{transform:scale(.97);transition-duration:var(--dur-0)}
.btn.line:hover{background-color:var(--hover)}
.tbl tbody tr{transition:background var(--dur-1) var(--ease-1)}
.nav-i{transition:background var(--dur-2) var(--ease-1),color var(--dur-2) var(--ease-1)}
.lead{transition:border-color var(--dur-2) var(--ease-1),background var(--dur-2) var(--ease-1)}
.pkg{transition:border-color var(--dur-2) var(--ease-1),transform var(--dur-1) var(--ease-1)}
input,select,textarea{transition:border-color var(--dur-2) var(--ease-1)}
/* :396 desnuda los .btn de dentro de una tabla y los vuelve enlaces de
   texto. Un enlace no se aplasta. */
.tbl td .btn:active,.tbl th .btn:active{transform:none}

/* ── B6 · el trazo de navegacion se DIBUJA, no aparece de golpe ───── */
.nav-i{position:relative}
.nav-i::before{content:'';position:absolute;left:-2px;top:0;bottom:0;width:2px;
  background:var(--oro);transform:scaleY(0);transform-origin:center;
  transition:transform var(--dur-3) var(--ease-1)}
.nav-i:hover::before{transform:scaleY(1)}

/* ── B4 · entrada escalonada, solo donde los hermanos son homogeneos ── */
@keyframes entra{from{opacity:0;transform:translateY(10px)}}
.kpis>.kpi,.pkgs>.pkg{animation:entra var(--dur-3) var(--ease-1) backwards}
.kpis>.kpi:nth-child(2),.pkgs>.pkg:nth-child(2){animation-delay:calc(var(--esc)*1)}
.kpis>.kpi:nth-child(3),.pkgs>.pkg:nth-child(3){animation-delay:calc(var(--esc)*2)}
.kpis>.kpi:nth-child(4),.pkgs>.pkg:nth-child(4){animation-delay:calc(var(--esc)*3)}
.kpis>.kpi:nth-child(5),.pkgs>.pkg:nth-child(5){animation-delay:calc(var(--esc)*4)}
.kpis>.kpi:nth-child(n+6),.pkgs>.pkg:nth-child(n+6){animation-delay:calc(var(--esc)*5)}
@keyframes aparece{from{opacity:0}}
.tbl tbody tr:not(.pod){animation:aparece .3s var(--ease-1) backwards}
.tbl tbody tr:not(.pod):nth-child(2){animation-delay:calc(var(--esc)*1)}
.tbl tbody tr:not(.pod):nth-child(3){animation-delay:calc(var(--esc)*2)}
.tbl tbody tr:not(.pod):nth-child(4){animation-delay:calc(var(--esc)*3)}
.tbl tbody tr:not(.pod):nth-child(5){animation-delay:calc(var(--esc)*4)}
.tbl tbody tr:not(.pod):nth-child(n+6){animation-delay:calc(var(--esc)*5)}

/* ── C8 · el pulgar del scroll fallaba contraste (2.27:1 -> 3.51:1).
   --txt4 #666 estaba declarado y NO lo usaba nadie.                    */
::-webkit-scrollbar-thumb{background:var(--txt4)}
::-webkit-scrollbar-thumb:hover{background:var(--txt3)}
.view{scrollbar-color:var(--txt4) var(--deep)}
.view::-webkit-scrollbar-thumb{background:var(--txt4);border:3px solid var(--deep)}

/* ── C11 · botones que se estiran (queja literal del dueno) ────────
   Sustituye al tope provisional de la tanda 1. Acotado a .card-b, asi
   login.js conserva su 100% (su caja mide 420px y ahi es lo correcto). */
.card-b > .btn.full,.card-b .row > .btn.full{width:auto;min-width:220px;max-width:100%}
@media(max-width:720px){.card-b > .btn.full,.card-b .row > .btn.full{width:100%}}

/* ── B7 · remate estatico ─────────────────────────────────────────
   Cromo no seleccionable; los DATOS siempre copiables. Critico: :396
   convierte .tbl td .btn en el ENLACE de la direccion — bloquear su
   seleccion impediria copiar la direccion. Va exento.                  */
.btn,.nav-i,.burger,.card-h h2,.card-h h3,.col-h,.tbl thead th,
.kpi small,.eti,.side-sec,.brand,.sub,.tag{-webkit-user-select:none;user-select:none}
.tbl tbody td,.tbl tbody th[scope="row"],.tbl td .btn,.tbl th .btn,
.lead b,.lead small,.kpi b,.num,.money,.prosa,input,textarea{
  -webkit-user-select:text;user-select:text}
:target,.card[id],section[id],h2[id],h3[id]{scroll-margin-top:calc(var(--top) + var(--s3))}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%}
.prosa,.empty,.aviso,.por,.pkg .tl,.lead small{text-wrap:pretty}

/* ── B8 · TACTIL — importa de verdad: el vendedor trabaja en la puerta.
   Los campos heredan 14px y Safari hace ZOOM cada vez que toca uno.
   16px es el umbral exacto. Solo en tactil: el escritorio conserva la
   densidad 9/10 intacta. input ya trae min-height:40px, 16px cabe.     */
html{-webkit-tap-highlight-color:rgba(0,0,0,0)}
@media(pointer:coarse){input,select,textarea{font-size:16px}}

/* ── B9 · el :hover se queda PEGADO al tocar en movil ─────────────── */
@media(hover:none){
  .btn:hover{filter:none}
  .btn.line:hover{border-color:var(--line2);color:var(--txt)}
  .tbl tbody tr:hover{background:transparent}
  .lead:hover{background:var(--card);border-left-color:var(--oro)}
  .pkg:hover{border-color:var(--line);transform:none}
}

/* ── B10 · MOVIMIENTO REDUCIDO ────────────────────────────────────
   El bloque global de :326 usa el selector universal, que NO casa con
   todo lo que anima en un ::before/::after quedaba FUERA de esa red.    */
@media(prefers-reduced-motion:reduce){
  html,body,.view{scroll-behavior:auto!important}
  .btn[data-enviando]::after{animation:none!important;transform:scaleX(1)}
  .nav-i::before{transition:none!important}
  .kpis>.kpi,.pkgs>.pkg,.tbl tbody tr:not(.pod){animation:none!important}
  .graf .col-b{animation:none!important;transform:none!important}
}


/* ── C12 · EL <label> OCULTO SIGUE ROMPIENDO FORMULARIOS ───────────
   La regla de :376 oculta el PRIMER <label> de todo form dentro de
   .card-h + .card-b "porque el titulo ya lo dice". Eso vale para un
   buscador de un campo. En un formulario de varios campos hace
   desaparecer un campo ENTERO. La lista blanca de :384 se mantiene a
   mano (form.grid, form.campos) y por eso se sigue escapando gente:
   views/catalogo.js:245 usa <form class="subir-foto"> y su primer
   <label> ENVUELVE al <input type=file> -> el selector de archivo
   desaparece y no se puede subir una foto de producto.
   En vez de añadir una cuarta clase a mano, se invierte la condicion:
   solo se oculta si NO hay mas etiquetas detras, que es exactamente el
   caso para el que se escribio. Especificidad 0,4,2 > 0,3,2: gana sin
   !important y sin tocar las reglas existentes.                       */
.card-h + .card-b form > label:first-of-type:has(~ label){
  position:static;width:auto;height:auto;overflow:visible;
  clip-path:none;white-space:normal;margin:10px 0 4px}

/* ── C7 · LA CIFRA DEL KPI DESBORDA — y ahi SI hay dinero ──────────
   views/automatizaciones.js pinta <div class="kpi"><b class="num">
   con money(), que devuelve importes con 2 decimales. "$195,430.00"
   son 11 caracteres a 29px de Rajdhani dentro de una rejilla
   minmax(158px,1fr) que en movil pasa a 2 columnas: desborda.
   cqi = ancho del CONTENEDOR, no del viewport: el desborde ocurre en
   tarjeta estrecha sobre pantalla ancha, asi que vw seria el eje
   equivocado. Tarjeta de 158px -> 20,5px; de 300px -> topa en 29px,
   exactamente como hoy.                                              */
.kpi{container-type:inline-size}
.kpi b{font-size:clamp(var(--t-xl),13cqi,var(--t-3xl))}


/* ═══════════════════════════════════════════════════════════════════
   GRAFICAS — CSS puro. La CSP bloquea toda libreria (script-src self),
   asi que ninguna libreria externa carga. Esto es el sustituto:
   conic-gradient para la dona, gradientes para barras y medidor, y SVG
   en linea para la chispa. Cero JavaScript.
   Idea tomada del KPI Command Center: numero grande con resplandor,
   barra fantasma detras de la real, y medidor contra objetivo.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Rejilla de graficas ─────────────────────────────────────────── */
.gs{display:grid;gap:var(--s4);grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  margin:0 0 var(--s4)}
.g-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r3);
  padding:var(--s4);box-shadow:var(--luz-1),var(--sombra-1);position:relative;
  container-type:inline-size;
  /* Columna flexible: el titulo arriba y el cuerpo ocupando el resto. Sin
     esto las tres tarjetas salian con alturas distintas y la del medidor
     quedaba medio vacia. */
  display:flex;flex-direction:column;min-height:250px}
.g-card > .g-t{flex:none}
/* El cuerpo se centra en el espacio sobrante: mata el hueco muerto de abajo. */
.g-card > .dona,.g-card > .bh,.g-card > .med,.g-card > .g-vacio{
  flex:1;align-content:center;justify-content:center}
.g-card > .bh{align-content:center}
.g-t{font-family:var(--display);font-size:var(--t-eti);font-weight:600;
  letter-spacing:var(--tr-eti);text-transform:uppercase;color:var(--txt3);
  margin:0 0 var(--s3)}

/* ── DONA (conic-gradient). Las porciones se pasan por --g desde la
      vista, ya calculadas en el servidor. El hueco central lleva el
      total: sin eso una dona es decorativa, no informativa. ───────── */
/* ── DONA en SVG en linea ─────────────────────────────────────────
   Se paso de conic-gradient a SVG porque el gradiente conico es UN solo
   fondo: no se puede poner el raton sobre una porcion. Con SVG cada tramo
   es un elemento propio, hoverable y con su <title> nativo.
   La CSP no estorba: SVG en linea es marcado, no un script.            */
.dona{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;
  justify-content:center}
.dona-fig{--tam:clamp(190px,64cqi,300px);width:var(--tam);height:var(--tam);
  position:relative;flex:none}
.dona-fig svg{width:100%;height:100%;display:block;overflow:visible}

/* Cada porcion responde al raton y al teclado. El grosor crece hacia fuera
   y hacia dentro por igual, asi que el agujero no se mueve. */
.dona-fig .tramo{transition:stroke-width var(--dur-2) var(--ease-1),
  opacity var(--dur-2) var(--ease-1);cursor:pointer;transform-origin:80px 80px}
.dona[data-activo] .tramo{opacity:.38}
.dona[data-activo] .tramo[data-on]{opacity:1;stroke-width:32}

/* Texto del centro. Se acota al diametro interior: R=60 con grosor 26 deja
   un radio libre de 47 sobre 80, o sea el 58% del ancho de la caja. */
.dona-c{position:absolute;inset:0;display:grid;place-content:center;
  text-align:center;z-index:1;pointer-events:none}
.dona-c b{display:block;font-family:var(--display);
  font-size:calc(var(--tam) * .125);
  font-variant-numeric:tabular-nums;line-height:1.05;white-space:nowrap;
  max-width:calc(var(--tam) * .52);margin:0 auto;
  overflow:hidden;text-overflow:ellipsis}
.dona-c small{display:block;font-size:calc(var(--tam) * .048);
  letter-spacing:var(--tr-eti);text-transform:uppercase;color:var(--txt3);
  white-space:nowrap;margin-top:2px}

/* Leyenda: tambien responde, y en los dos sentidos (leyenda <-> porcion). */
.dona-leg{display:grid;gap:4px;flex:1;min-width:170px;margin:0;padding:0}
.dona-leg li{display:flex;align-items:center;gap:9px;font-size:var(--t-sm);
  list-style:none;padding:5px 7px;border-radius:var(--r2);cursor:pointer;
  transition:background var(--dur-2) var(--ease-1),opacity var(--dur-2) var(--ease-1)}
.dona-leg li:hover,.dona-leg li[data-on]{background:var(--hover)}
.dona[data-activo] .dona-leg li{opacity:.45}
.dona[data-activo] .dona-leg li[data-on]{opacity:1}
.dona-leg .pt{width:11px;height:11px;border-radius:var(--r1);flex:none;background:var(--c)}
.dona-leg .et{color:var(--txt2);flex:1}
.dona-leg .vl{font-variant-numeric:tabular-nums;font-weight:600}
.dona-leg .pc{color:var(--txt3);font-size:var(--t-min);min-width:38px;text-align:right}

@media(prefers-reduced-motion:reduce){
  .dona-fig .tramo,.dona-leg li{transition:none}
}

/* ── BARRAS HORIZONTALES CON FANTASMA ────────────────────────────
      El fantasma (el carril tenue) es lo que deja leer la proporcion
      de un vistazo: sin el, una barra corta no se distingue de un
      dato pequeño frente a uno grande. --p es el % ya calculado. ─── */
.bh{display:grid;gap:var(--s3);margin:0;padding:0}
.bh li{list-style:none;display:grid;gap:5px;padding:5px 7px;border-radius:var(--r2);
  transition:background var(--dur-2) var(--ease-1);cursor:default}
.bh li:hover,.bh li:focus-visible{background:var(--hover);outline:none}
.bh li:focus-visible{box-shadow:inset 0 0 0 1px var(--oro)}
/* Al pasar el raton la barra se engorda un poco: confirma cual estas mirando
   sin mover nada de sitio (el carril ya reserva el alto). */
.bh li:hover .bar,.bh li:focus-visible .bar{filter:brightness(1.12)}
.bh .pc{color:var(--txt3);font-size:var(--t-min);min-width:34px;text-align:right;
  flex:none}
.bh .fila{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s2);
  font-size:var(--t-sm)}
.bh .nm{color:var(--txt2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bh .vl{font-variant-numeric:tabular-nums;font-weight:700;flex:none}
.bh .car{height:9px;border-radius:var(--r-pill);background:rgba(255,255,255,.045);
  overflow:hidden;position:relative}
.bh .bar{height:100%;width:var(--p);border-radius:var(--r-pill);
  background:linear-gradient(90deg,var(--oro-osc),var(--oro));
  box-shadow:0 1px 0 rgba(240,215,123,.4) inset;
  transform-origin:left;animation:crece var(--dur-3) var(--ease-1) backwards}
.bh li:nth-child(2) .bar{animation-delay:calc(var(--esc)*1)}
.bh li:nth-child(3) .bar{animation-delay:calc(var(--esc)*2)}
.bh li:nth-child(4) .bar{animation-delay:calc(var(--esc)*3)}
.bh li:nth-child(n+5) .bar{animation-delay:calc(var(--esc)*4)}
@keyframes crece{from{transform:scaleX(0)}}
/* El primero destaca: es el lenguaje del podio, no un color nuevo. */
.bh li:first-child .bar{background:linear-gradient(90deg,var(--oro),var(--oro-cl))}

/* ── MEDIDOR (progreso contra objetivo) ──────────────────────────
      Semaforo por tramo, como pide el KPI Command Center: verde/ambar/
      rojo segun cumplimiento, no un color fijo que no dice nada. ─── */
.med{display:grid;gap:8px}
.med-top{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s2)}
.med-top b{font-family:var(--display);font-size:var(--t-2xl);
  font-variant-numeric:tabular-nums;line-height:1}
.med-top small{color:var(--txt3);font-size:var(--t-min)}
.med-car{height:12px;border-radius:var(--r2);background:rgba(255,255,255,.045);
  overflow:hidden;box-shadow:var(--pozo-1)}
.med-bar{height:100%;width:var(--p);border-radius:var(--r2);
  background:linear-gradient(90deg,var(--oro-osc),var(--oro));
  animation:crece var(--dur-3) var(--ease-1) backwards;transform-origin:left}
.med.ok  .med-bar{background:linear-gradient(90deg,color-mix(in srgb,var(--ok) 62%,#000),var(--ok))}
.med.warn .med-bar{background:linear-gradient(90deg,color-mix(in srgb,var(--warn) 62%,#000),var(--warn))}
.med.bad  .med-bar{background:linear-gradient(90deg,color-mix(in srgb,var(--bad) 62%,#000),var(--bad))}
.med-pie{display:flex;justify-content:space-between;font-size:var(--t-min);
  color:var(--txt3)}

/* ── CHISPA (sparkline) en SVG en linea ─────────────────────────── */
.chispa{width:100%;height:44px;display:block;overflow:visible}
.chispa path{fill:none;stroke:var(--oro);stroke-width:2;stroke-linecap:round;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.chispa .area{fill:url(#gOro);stroke:none}

/* ── ESTADO VACIO — honesto, no una grafica falsa ────────────────
      Regla del proyecto: no se pinta una grafica con menos de 3 datos.
      Es mejor decir por que que dibujar una linea recta que miente. */
.g-vacio{display:grid;place-items:center;gap:6px;padding:var(--s5) var(--s3);
  text-align:center;color:var(--txt3);font-size:var(--t-sm);
  border:1px dashed var(--line2);border-radius:var(--r3)}
.g-vacio b{color:var(--txt2);font-size:var(--t-sm);font-weight:600}

@media(prefers-reduced-motion:reduce){
  .bh .bar,.med-bar{animation:none!important;transform:none!important}
}



/* ── SELECTOR DE NIVEL DEL PODIO ──────────────────────────────────
   Son ENLACES, no botones con JavaScript: el nivel vive en la URL, asi
   que "el podio de mi region" se comparte por WhatsApp y se guarda en
   favoritos. Y funciona aunque no cargue nada.                       */
.niveles{display:flex;align-items:center;gap:7px;flex-wrap:wrap;
  margin:0 0 var(--s3)}
.niveles .eti{margin-right:3px}
.niv{padding:7px 14px;border-radius:var(--r-pill);border:1px solid var(--line2);
  font-family:var(--display);font-size:var(--t-min);font-weight:600;
  letter-spacing:var(--tr-lbl);text-transform:uppercase;color:var(--txt2);
  background:var(--card);white-space:nowrap;
  transition:border-color var(--dur-2) var(--ease-1),
             color var(--dur-2) var(--ease-1),
             background var(--dur-2) var(--ease-1)}
.niv:hover{border-color:var(--oro);color:var(--txt)}
/* El activo en oro solido: #1a1200 sobre #D4AF37 da 8,83:1, AA de sobra. */
.niv.on{background:linear-gradient(135deg,var(--oro-cl),var(--oro-osc));
  border-color:transparent;color:var(--sobre-oro)}

/* Marco nacional: el total contra el que se compara el nivel que miras. */
.marco{margin:0 0 var(--s4);font-size:var(--t-sm);color:var(--txt2)}
.marco b{color:var(--txt);font-family:var(--display);font-size:var(--t-md)}


/* ── KPI CLICABLE (mapa de territorios) ───────────────────────────
   Las 6 tarjetas de /mapa pasan de <div> a <a>: cada una filtra el
   listado de puertas de abajo (?f=). Sin JS: la CSP es script-src
   'self' y todo el CRM navega con enlaces y recarga de servidor.
   El estado activo NO depende solo del color: sube el rail a 3px.  */
a.kpi{cursor:pointer;
  transition:background var(--dur-1) var(--ease-1),
             border-color var(--dur-1) var(--ease-1),
             transform var(--dur-1) var(--ease-1)}
a.kpi:hover{background:var(--hover);border-color:var(--line2);transform:translateY(-1px)}
a.kpi:active{transform:none}
a.kpi:focus-visible{outline:2px solid var(--oro);outline-offset:3px}
a.kpi[aria-current="true"]{border-color:var(--oro);background:var(--card2)}
a.kpi[aria-current="true"]:before{width:3px;background:var(--oro)}
a.kpi[aria-current="true"] .num{color:var(--oro)}
/* El numero del KPI del mapa a la misma jerarquia que el resto del CRM:
   hoy salia a tamaño de texto normal y la tarjeta parecia de otra pantalla. */
a.kpi .num{display:block;width:100%;font-family:var(--display);
  font-size:clamp(var(--t-xl),13cqi,var(--t-3xl));font-weight:700;
  line-height:1.02;letter-spacing:-.01em}

/* La nota de la puerta en la tabla. El esceptico tenia razon: max-width en
   un <td> NO acota nada con table-layout automatico, el navegador lo
   ignora. El recorte real se hace en el servidor; aqui solo el aspecto,
   y el ancho se acota en un <span> en linea, que si lo respeta. */
.tbl td.nota{color:var(--txt2);font-size:var(--t-min)}
.tbl td.nota > span{display:inline-block;max-width:34ch;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}

@media(prefers-reduced-motion:reduce){ a.kpi{transition:none} }


/* ═══════════════════════════════════════════════════════════════════
   CAPA LUXURY & HUD MODERNO
   Acabados de lujo, iluminacion fisica y micro-interacciones tacticas.
   ═══════════════════════════════════════════════════════════════════ */

/* ── 1. LA BARRA SUPERIOR ── */
.top {
  background: rgba(7, 7, 7, .85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line2);
  box-shadow: 0 1px 0 0 var(--oro-t1);
}

/* ── 2. JERARQUIA DEL KPI ────────────────────────────────────────
   Ocho KPI seguidos con ocho railes de oro es jerarquia PLANA: cuando
   todo esta acentuado, nada lo esta. Aqui el rail SIGNIFICA algo:
     oro   = lo que esta EN JUEGO (.kpi.g) o el filtro activo del mapa
     verde = lo ya CERRADO (.kpi.ok)
     gris  = contexto
   El rail no desaparece — es el lenguaje de la marca — deja de gritar.
   Coste en espacio: CERO. Misma altura, mismas filas.                 */
.kpi:before{background:linear-gradient(180deg,var(--line2),transparent)}
.kpi.g:before,a.kpi[aria-current="true"]:before{
  background:linear-gradient(180deg,var(--oro),rgba(212,175,55,0))}
.kpi.ok:before{background:linear-gradient(180deg,var(--ok),transparent)}
.kpi b{color:var(--txt)}
.kpi.g b{color:var(--oro-cl)}

/* ── 3. BOTONES ─────────────────────────────────────────────────
   El halo dorado alrededor del boton en REPOSO es el tell mas viejo del
   boton "premium" de plantilla: en 2026 lee barato, no caro. Se retira.
   Queda el filo metalico superior (inset) — eso si es acabado — y una
   sombra de contacto neutra. El oro solo se enciende al pasar el raton. */
.btn:not(.line){
  background:linear-gradient(135deg,var(--oro-cl) 0%,var(--oro) 52%,var(--oro-osc) 100%);
  color:var(--sobre-oro);font-weight:700;border:0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.42),inset 0 -1px 0 rgba(0,0,0,.25);
  transition:filter var(--dur-2) var(--ease-1),transform var(--dur-1) var(--ease-1),
             box-shadow var(--dur-2) var(--ease-1)}
.btn:not(.line):hover{filter:brightness(1.06);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 4px 12px -8px rgba(212,175,55,.6)}
.btn:not(.line):active{transform:scale(.975);
  box-shadow:inset 0 1px 3px rgba(0,0,0,.4)}
.btn.line{background:rgba(255,255,255,.02);border:1px solid var(--line2);
  color:var(--txt);box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}
.btn.line:hover{border-color:var(--oro-osc);color:var(--oro-cl);
  background:var(--oro-t1);box-shadow:none}

/* ── 4. TABLAS ── cabecera que se distingue de verdad del cuerpo. */
.tbl thead th{background:var(--card2);color:var(--txt2);letter-spacing:var(--tr-lbl)}
.tbl tbody tr:hover{
  background:linear-gradient(90deg,var(--oro-t1) 0%,var(--hover) 15%,var(--hover) 100%)}
.tbl tbody tr:hover td:first-child,
.tbl tbody tr:focus-within td:first-child{box-shadow:inset 2px 0 0 var(--oro)}
/* Celda sin dato: un guion tenue, no un hueco. Dos vistas resolvian esto
   de dos maneras (una dejaba el blanco, otra pintaba "— — —") y eso es
   justo lo que hace que un producto parezca ensamblado y no disenado.
   Es CSS puro: no toca la consulta ni el marcado.                     */
.tbl tbody td:empty:after,
.tbl tbody td>span:empty:only-child:after{content:'–';color:var(--txt4)}
/* Todo lo que sea dinero se alinea a la derecha, con cifras tabulares. */
.tbl td.money,.tbl th.money{text-align:right;font-variant-numeric:tabular-nums lining-nums}

/* ── 5. NAVEGACION ── */
.nav-i{border-radius:var(--r1);margin:1px var(--s2);padding:8px 12px}
.nav-i:hover{background:rgba(255,255,255,.03);color:var(--txt)}
.nav-i.on{background:linear-gradient(90deg,var(--oro-t2) 0%,transparent 100%);
  color:var(--oro-cl);border-left:2px solid var(--oro);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}

/* ── 6. INSIGNIAS ── sin resplandor: una insignia no emite luz. */
.tag{background:var(--oro-t2);border:1px solid var(--oro-t3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08)}
.pill{background:var(--oro-t2);border:1px solid var(--oro-t3);box-shadow:none}

/* ── 7. CAMPOS ── el pozo sale del token, no de un tercer negro. */
input,select,textarea{background:var(--pozo);border:1px solid var(--line2);
  box-shadow:var(--pozo-1)}

/* ═══════════════════════════════════════════════════════════════════
   T6 · TERRENO — AUDITORIA DE ACTIVIDAD EN CAMPO
   Prefijo exclusivo .tr-. Cero librerias: SVG puro + CSS.
   ═══════════════════════════════════════════════════════════════════ */

.tr-vista {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  background: var(--bg);
}

/* ── HUD Y METRICAS ── */
.tr-hud {
  background: var(--card);
  border: 1px solid var(--line2);
  border-radius: var(--r3);
  padding: var(--s4);
  box-shadow: var(--luz-1), var(--sombra-1);
}
.tr-hud-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  flex-wrap: wrap;
  margin-bottom: var(--s3);
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--s3);
}
.tr-titulo {
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 700;
  letter-spacing: var(--tr-tit);
  color: var(--txt);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}
.tr-glifo { color: var(--oro); }
.tr-subtitulo {
  font-family: var(--display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--tr-eti);
  color: var(--txt3);
  text-transform: uppercase;
}
.tr-filtros-bar { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.tr-lbl {
  font-family: var(--display);
  font-size: var(--t-eti);
  font-weight: 600;
  letter-spacing: var(--tr-lbl);
  color: var(--txt3);
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 6px;
}
.tr-input-dia, .tr-select {
  background: var(--pozo);
  border: 1px solid var(--line2);
  color: var(--txt);
  padding: 6px 10px;
  border-radius: var(--r2);
  font-family: var(--body);
  font-size: var(--t-sm);
  min-height: 36px;
}

.tr-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--s3);
}
.tr-kpi {
  background: var(--deep);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  padding: 10px 14px;
  border-left: 2px solid var(--line2);
}
.tr-kpi b {
  display: block;
  font-family: var(--display);
  font-size: var(--t-2xl);
  font-weight: 700;
  color: var(--txt);
  line-height: 1.05;
}
.tr-kpi small {
  display: block;
  font-family: var(--display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--tr-eti);
  color: var(--txt3);
  text-transform: uppercase;
  margin-top: 2px;
}
.tr-kpi.ok { border-left-color: var(--ok); }
.tr-kpi.ok b { color: var(--ok); }
.tr-kpi.inactivo { border-left-color: var(--txt4); }
.tr-kpi.inactivo b { color: var(--txt3); }
.tr-kpi.alerta { border-left-color: var(--warn); }
.tr-kpi.alerta b { color: var(--warn); }

/* ── SECCION DE SENALES, ANTES DEL MAPA ── */
.tr-seccion-alertas {
  background: color-mix(in srgb,var(--warn) 7%,var(--card));
  border: 1px solid rgba(210, 153, 34, .35);
  border-radius: var(--r3);
  padding: var(--s3) var(--s4);
}
.tr-alertas-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s2);
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.tr-alertas-tit {
  font-family: var(--display);
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: var(--tr-lbl);
  color: var(--warn);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  text-transform: uppercase;
}
.tr-alertas-desc { font-size: var(--t-min); color: var(--txt3); }
.tr-alertas-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 8px;
}
.tr-alerta-card {
  background: rgba(0, 0, 0, .45);
  border: 1px solid rgba(210, 153, 34, .25);
  border-radius: var(--r2);
  padding: 8px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1);
}
.tr-alerta-card:hover {
  background: rgba(210, 153, 34, .12);
  border-color: var(--warn);
}
.tr-alerta-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tr-alerta-tipo {
  font-family: var(--display);
  font-size: var(--t-eti);
  font-weight: 700;
  letter-spacing: var(--tr-lbl);
  color: var(--warn);
  text-transform: uppercase;
}
.tr-alerta-det { font-size: var(--t-min); color: var(--txt); }
.tr-alerta-meta { text-align: right; font-size: var(--t-min); color: var(--txt3); white-space: nowrap; }

/* Mensaje neutro cuando no hay nada que listar. */
.tr-aviso { color: var(--txt3); font-size: var(--t-sm); padding: 10px 12px; }

/* ── LAYOUT: VENDEDORES + VISOR SVG ── */
.tr-layout {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: var(--s3);
  min-height: 520px;
}
.tr-panel-vendedores {
  background: var(--card);
  border: 1px solid var(--line2);
  border-radius: var(--r3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.tr-vendedores-h {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 10px var(--s3);
  background: var(--card2);
  border-bottom: 1px solid var(--line2);
  font-family: var(--display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: var(--tr-eti);
  color: var(--txt3);
  text-transform: uppercase;
}
.tr-vendedores-lista { overflow-y: auto; flex: 1; max-height: 580px; }
.tr-vend-card {
  padding: 10px var(--s3);
  border-bottom: 1px solid var(--line);
  border-left: 2px solid transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  transition: background var(--dur-1) var(--ease-1);
}
.tr-vend-card:hover { background: var(--hover); }
.tr-vend-card.on {
  background: var(--oro-t2);
  border-left-color: var(--oro);
}
.tr-vend-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tr-vend-nombre { font-weight: 600; font-size: var(--t-sm); color: var(--txt); }
.tr-vend-sub { font-size: var(--t-min); color: var(--txt3); }
.tr-tag-alerta { font-size: var(--t-micro); }
.tr-vend-stats { text-align: right; white-space: nowrap; }
.tr-vend-visitas { font-family: var(--display); font-size: var(--t-lg); font-weight: 700; color: var(--txt); }
.tr-vend-visitas.cero { color: var(--txt4); font-size: var(--t-sm); }
.tr-vend-km { color: var(--txt3); }

/* ── VISOR SVG ── */
.tr-visor-mapa {
  background: var(--bg);
  border: 1px solid var(--line2);
  border-radius: var(--r3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}
.tr-mapa-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px var(--s4);
  background: var(--card2);
  border-bottom: 1px solid var(--line2);
  flex-wrap: wrap;
}
.tr-vendedor-foco { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tr-vendedor-foco b { color: var(--oro-cl); font-size: var(--t-sm); }
.tr-vendedor-foco small { color: var(--txt3); font-size: var(--t-min); }
.tr-svg-wrap { flex: 1; position: relative; min-height: 420px; }
.tr-svg { width: 100%; height: 100%; display: block; }

.tr-trazo {
  fill: none;
  stroke: var(--oro);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .85;
}
.tr-trazo.dim { opacity: .12; }
.tr-trazo-anomalo {
  stroke: var(--bad);
  stroke-dasharray: 6 4;
  stroke-width: 3;
}
.tr-punto {
  stroke: var(--bg);
  stroke-width: 1.5;
  cursor: pointer;
  transition: r var(--dur-1) var(--ease-1);
}
.tr-punto:hover { r: 8; stroke: #fff; }
.tr-punto.dim { opacity: .15; }

/* Un color por estado de puerta. Son los SIETE que la base admite: si
   faltara alguno, ese punto se dibujaria sin relleno y desapareceria. */
.tr-c-interesado   { fill: var(--azul-cl);    background: var(--azul-cl); }
.tr-c-vendido      { fill: var(--ok);  background: var(--ok); }
.tr-c-cita         { fill: var(--oro); background: var(--oro); }
.tr-c-volver_luego { fill: var(--violeta);    background: var(--violeta); }
.tr-c-no_estaba    { fill: var(--txt3);    background: var(--txt3); }
.tr-c-no_interesa  { fill: var(--gris-d);    background: var(--gris-d); }
.tr-c-no_toco      { fill: var(--bad); background: var(--bad); }

/* ── LEYENDA ── */
.tr-leyenda {
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding: 8px var(--s4);
  background: var(--deep);
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
  font-size: var(--t-min);
  color: var(--txt2);
}
.tr-leyenda-item { display: flex; align-items: center; gap: 6px; }
.tr-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.tr-linea-anomala {
  width: 14px;
  height: 0;
  display: inline-block;
  border-top: 2px dashed var(--bad);
}

@media(max-width:860px){
  .tr-layout { grid-template-columns: 1fr; }
  .tr-panel-vendedores { max-height: 280px; }
}

/* ══ T5 · NUCLEO — MAPA DE CONOCIMIENTO ══
   Prefijo exclusivo .nx-. Cero librerias: SVG vectorial + CSS. */
.nx-vista{display:flex;flex-direction:column;height:calc(100dvh - var(--top) - var(--s5));
  min-height:580px;background:var(--bg);border:1px solid var(--line2);border-radius:var(--r3);
  overflow:hidden;box-shadow:var(--luz-1),var(--sombra-1)}

.nx-hud{background:linear-gradient(180deg,rgba(21,21,21,.98),rgba(14,14,14,.95));
  border-bottom:1px solid var(--line2);padding:12px var(--s4);display:flex;
  flex-direction:column;gap:10px;flex:none;z-index:10}
.nx-hud-top{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);flex-wrap:wrap}
.nx-titulo-box{display:flex;flex-direction:column;gap:2px}
.nx-titulo{font-family:var(--display);font-size:var(--t-xl);font-weight:700;
  letter-spacing:var(--tr-tit);color:var(--txt);display:flex;align-items:center;gap:8px;margin:0}
.nx-glifo-core{color:var(--oro)}
.nx-subtitulo{font-family:var(--display);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-eti);color:var(--txt3);text-transform:uppercase}

.nx-sonda-chip{display:inline-flex;align-items:center;gap:12px;background:var(--deep);
  border:1px solid var(--oro-t3);border-radius:var(--r3);padding:6px 14px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.nx-pulso-dot{width:9px;height:9px;border-radius:50%;background:var(--ok);flex:none;
  box-shadow:0 0 0 0 rgba(63,185,80,.7);animation:nx-pulso 2s var(--ease-1) infinite}
.nx-sonda-chip.apagada .nx-pulso-dot{background:var(--txt4);animation:none;box-shadow:none}
.nx-sonda-chip.apagada .nx-sonda-estado b{color:var(--txt3)}
@keyframes nx-pulso{
  0%{transform:scale(.95);box-shadow:0 0 0 0 rgba(63,185,80,.7)}
  70%{transform:scale(1.15);box-shadow:0 0 0 8px rgba(63,185,80,0)}
  100%{transform:scale(.95);box-shadow:0 0 0 0 rgba(63,185,80,0)}}
.nx-sonda-info{display:flex;flex-direction:column;font-size:var(--t-min);line-height:1.2;min-width:0}
.nx-sonda-estado{font-family:var(--display);font-size:var(--t-micro);font-weight:600;letter-spacing:var(--tr-lbl);
  color:var(--txt3);text-transform:uppercase}
.nx-sonda-estado b{color:var(--ok)}
.nx-sonda-proc{color:var(--txt);font-weight:500;white-space:nowrap;max-width:240px;
  overflow:hidden;text-overflow:ellipsis}
.nx-sonda-cnt{display:flex;flex-direction:column;align-items:flex-end;
  border-left:1px solid var(--line2);padding-left:10px;line-height:1}
.nx-sonda-cnt b{font-family:var(--display);font-size:var(--t-lg);color:var(--oro-cl)}
.nx-sonda-cnt small{font-family:var(--display);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-eti);color:var(--txt3)}

.nx-hud-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);flex-wrap:wrap}
.nx-filtros{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.nx-vista-modos{display:flex;align-items:center;gap:6px}
.nx-filtro-btn,.nx-vista-btn{background:var(--card2);border:1px solid var(--line2);
  border-radius:var(--r2);color:var(--txt2);font-family:var(--display);font-size:var(--t-min);
  font-weight:600;letter-spacing:var(--tr-lbl);padding:5px 11px;cursor:pointer;display:inline-flex;
  align-items:center;gap:6px;min-height:32px;
  transition:background var(--dur-2) var(--ease-1),border-color var(--dur-2) var(--ease-1),color var(--dur-2) var(--ease-1)}
.nx-filtro-btn:hover,.nx-vista-btn:hover{color:var(--txt);border-color:var(--oro-osc);background:var(--hover)}
.nx-filtro-btn.on,.nx-vista-btn.on{background:var(--oro-t2);border-color:var(--oro);color:var(--oro-cl)}
.nx-dot{width:7px;height:7px;border-radius:50%;flex:none}
.nx-dot.g-negocio{background:var(--oro)}
.nx-dot.g-producto{background:var(--azul-cl)}
.nx-dot.g-guia{background:var(--ok)}
.nx-dot.g-sistema{background:var(--plata)}

.nx-contenedor{flex:1;position:relative;overflow:hidden;background:var(--bg);min-height:0}
.nx-viewport{position:absolute;inset:0;width:100%;height:100%;cursor:grab;touch-action:none}
.nx-viewport:active{cursor:grabbing}
.nx-svg{width:100%;height:100%;display:block}

.nx-orbita{fill:none;stroke:var(--oro-t1);stroke-width:1;stroke-dasharray:2 10}
.nx-radar-core{fill:none;stroke:var(--oro-t2);stroke-width:1}
.nx-orbita-txt{font-family:var(--display);font-size:var(--t-micro);font-weight:700;
  letter-spacing:var(--tr-eti);fill:var(--oro-t2);text-anchor:middle}

.nx-link{stroke:var(--oro-t2);stroke-linecap:round;
  transition:stroke var(--dur-2) var(--ease-1),opacity var(--dur-2) var(--ease-1)}
.nx-link.on{stroke:rgba(240,215,123,.85);opacity:1}
.nx-link.dim{opacity:.05}

.nx-nodo{cursor:pointer;outline:none;transition:opacity var(--dur-2) var(--ease-1)}
.nx-nodo.oculto{display:none}
/* circulo PLANO: color solido por grupo, sin degradado ni esfera 3D */
.nx-nodo-core{stroke-width:0;transition:fill-opacity var(--dur-2) var(--ease-1)}
.nx-nodo[data-grupo="negocio"] .nx-nodo-core{fill:var(--oro);stroke:var(--oro)}
.nx-nodo[data-grupo="producto"] .nx-nodo-core{fill:var(--azul-cl);stroke:var(--azul-cl)}
.nx-nodo[data-grupo="guia"] .nx-nodo-core{fill:var(--ok);stroke:var(--ok)}
.nx-nodo[data-grupo="sistema"] .nx-nodo-core{fill:var(--plata);stroke:var(--plata)}
/* filo punteado: el bloque existe pero todavia no se cita al responder */
.nx-nodo.fuera .nx-nodo-core{fill-opacity:.26;stroke-width:1.4;stroke-dasharray:3 3}

/* etiqueta SUELTA bajo el nodo: sin caja, sin trazo de fondo. El trazo de 3px
   que llevaba antes se comia los glifos cuando el navegador no honra
   paint-order y dejaba una barra sin texto. */
.nx-nodo-txt{font-family:var(--display);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-lbl);fill:var(--txt2);text-anchor:middle;pointer-events:none;
  transition:fill var(--dur-2) var(--ease-1),opacity var(--dur-2) var(--ease-1)}
/* con muchos nodos, los pequenos callan hasta que te acercas o los tocas */
.nx-nodo.chico .nx-nodo-txt{opacity:0}
.nx-svg.cerca .nx-nodo.chico .nx-nodo-txt{opacity:1}

.nx-nodo-halo{fill:none;stroke:none;stroke-width:1}
.nx-nodo:hover .nx-nodo-halo,.nx-nodo:focus-visible .nx-nodo-halo{stroke:rgba(255,255,255,.28)}
.nx-nodo:hover .nx-nodo-txt,.nx-nodo:focus-visible .nx-nodo-txt{fill:var(--txt);opacity:1}
.nx-nodo.on .nx-nodo-halo{stroke:#fff;stroke-width:1.5}
.nx-nodo.on .nx-nodo-core{filter:drop-shadow(0 0 7px rgba(255,255,255,.45))}
.nx-nodo.on .nx-nodo-txt,.nx-nodo.vecino .nx-nodo-txt{fill:var(--txt);opacity:1}
.nx-nodo.vecino .nx-nodo-halo{stroke:rgba(240,215,123,.55)}
/* al seleccionar, el resto del mapa se APAGA */
.nx-nodo.dim{opacity:.13}
.nx-nodo.sonda-on .nx-nodo-halo{stroke:var(--ok);stroke-width:1.2;stroke-dasharray:3 4;
  animation:nx-halo-spin 6s linear infinite}
@keyframes nx-halo-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}

.nx-panel{position:absolute;top:0;right:0;bottom:0;width:320px;max-width:100%;
  background:rgba(14,14,14,.96);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-left:1px solid var(--line2);box-shadow:var(--sombra-2);display:flex;
  flex-direction:column;transform:translateX(101%);
  transition:transform var(--dur-3) var(--ease-1);z-index:20}
.nx-panel.on{transform:translateX(0)}
.nx-panel-h{display:flex;align-items:center;justify-content:space-between;
  padding:14px var(--s4);border-bottom:1px solid var(--line2)}
.nx-panel-x{background:transparent;border:0;color:var(--txt3);font-size:var(--t-xl);line-height:1;
  cursor:pointer;padding:4px 8px;border-radius:var(--r1)}
.nx-panel-x:hover{color:var(--bad)}
.nx-panel-b{padding:var(--s4);overflow-y:auto;display:flex;flex-direction:column;gap:var(--s4)}
.nx-panel-titulo{font-family:var(--display);font-size:var(--t-lg);font-weight:700;
  color:var(--txt);margin:0;line-height:1.25}
.nx-panel-meta{display:grid;gap:10px;background:var(--deep);border:1px solid var(--line);
  border-radius:var(--r2);padding:12px}
.nx-panel-meta small{display:block;font-family:var(--display);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-eti);color:var(--txt3);text-transform:uppercase;margin-bottom:2px}
.nx-code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:var(--t-min);color:var(--oro-cl)}
.nx-panel-sub{font-family:var(--display);font-size:var(--t-eti);font-weight:600;
  letter-spacing:var(--tr-eti);color:var(--txt3);text-transform:uppercase;margin:0 0 8px}
.nx-panel-vecinos{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
.nx-vecino-item{display:flex;align-items:center;justify-content:space-between;gap:8px;
  background:var(--card2);border:1px solid var(--line2);border-radius:var(--r2);padding:8px 10px;
  font-size:var(--t-sm);cursor:pointer;
  transition:background var(--dur-2) var(--ease-1),border-color var(--dur-2) var(--ease-1)}
.nx-vecino-item:hover{background:var(--hover);border-color:var(--oro-osc);color:var(--oro-cl)}

.nx-lista-vista{position:absolute;inset:0;width:100%;height:100%;overflow-y:auto;padding:var(--s4)}
.nx-lista-grid{display:grid;gap:var(--s3);grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.nx-lista-item{background:var(--card);border:1px solid var(--line2);border-radius:var(--r3);
  padding:14px;cursor:pointer;
  transition:border-color var(--dur-2) var(--ease-1),transform var(--dur-1) var(--ease-1)}
.nx-lista-item:hover{border-color:var(--oro);transform:translateY(-1px)}
.nx-lista-item-h{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}
.nx-lista-item-t{font-family:var(--display);font-size:var(--t-md);font-weight:700;
  color:var(--txt);margin:0 0 6px}
.nx-lista-item-m{color:var(--txt3);font-size:var(--t-min)}
.nx-vacio{color:var(--txt3)}
.nx-nota{flex:none;margin:0;padding:8px var(--s4);background:var(--deep);
  border-top:1px solid var(--line);color:var(--txt3);font-size:var(--t-min)}

@media(max-width:720px){
  .nx-vista{height:auto;min-height:520px}
  .nx-hud-top{flex-direction:column;align-items:flex-start}
  .nx-sonda-chip{width:100%;justify-content:space-between}
  .nx-sonda-proc{max-width:44vw}
  .nx-panel{width:100%}
  .nx-contenedor{min-height:420px}}
@media(pointer:coarse){
  .nx-filtro-btn,.nx-vista-btn{min-height:44px;padding:8px 14px}}

/* ══ ORGANIGRAMA ══ (estructura corporativa, solo admin) */
.og-intro{color:var(--txt3);font-size:var(--t-sm);max-width:74ch;margin:0 0 var(--s4)}
.og-num-vac{color:var(--warn)}
.og-svg-wrap{background:var(--card);border:1px solid var(--line);border-radius:var(--r3);
  padding:var(--s4);margin-bottom:var(--s4);overflow-x:auto}
.og-svg{display:block;width:100%;min-width:760px;height:auto}
.og-l{stroke:var(--line2);stroke-width:1.4;fill:none}
.og-n rect.og-n-bg{fill:#111215;stroke:var(--node-c, var(--oro));stroke-width:1.5;transition:stroke-opacity .2s, filter .2s}
.og-n:hover rect.og-n-bg{stroke-opacity:1;filter:drop-shadow(0 0 10px rgba(var(--node-rgb, 212,175,55),.45))}
.og-n rect.og-n-tab{opacity:.95}
.og-n .og-t{fill:var(--plata);font-family:var(--display);font-size:var(--t-min);font-weight:600;text-anchor:middle}
.og-n .og-o{fill:var(--node-c, var(--oro));font-size:var(--t-micro);letter-spacing:var(--tr-eti);font-weight:700;text-transform:uppercase;text-anchor:middle}
.og-n .og-q{fill:var(--txt);font-size:var(--t-micro);font-weight:700;text-anchor:middle}
.og-n.og-jefe rect.og-n-bg{fill:#141310;stroke:var(--oro);stroke-width:2}
.og-n.og-persona rect.og-n-bg{stroke:var(--ok)}
.og-n.og-persona .og-o{fill:var(--ok)}
.og-n.og-vacante rect.og-n-bg{fill:none;stroke:var(--warn);stroke-dasharray:5 4}
.og-n.og-vacante .og-o{fill:var(--warn)}

.og-grid{grid-template-columns:repeat(auto-fit,minmax(340px,1fr));align-items:start;gap:20px}
.og-card{
  margin-bottom:0;
  background:radial-gradient(ellipse at 50% 0%, rgba(var(--dep-rgb, 212,175,55),.1) 0%, #121316 65%, #0d0e11 100%);
  border:1px solid rgba(255,255,255,.07);
  border-top:3px solid var(--dep-c, var(--oro));
  border-radius:var(--r4);
  box-shadow:0 8px 30px rgba(0,0,0,.6), 0 0 25px rgba(var(--dep-rgb, 212,175,55),.05);
  position:relative;
  transition:border-color .25s, box-shadow .25s, transform .25s;
}
.og-card:hover{
  border-color:rgba(var(--dep-rgb, 212,175,55),.3);
  box-shadow:0 12px 40px rgba(0,0,0,.75), 0 0 35px rgba(var(--dep-rgb, 212,175,55),.12);
}
.og-card-h{align-items:flex-start;justify-content:space-between;gap:12px;padding:16px var(--s4) 14px;border-bottom:1px solid rgba(255,255,255,.05)}
.og-card-h-main{min-width:0}
.og-dep-badge{display:inline-flex;align-items:center;gap:8px}
.og-dep-ico{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:6px;background:rgba(var(--dep-rgb, 212,175,55),.14);color:var(--dep-c, var(--oro));border:1px solid rgba(var(--dep-rgb, 212,175,55),.3)}
.og-dep-ico svg{width:16px;height:16px}
.og-dep-nom{font-family:var(--display);font-size:var(--t-base);font-weight:700;color:var(--dep-c, var(--oro));letter-spacing:.02em;text-transform:uppercase}
.og-prop{color:var(--txt3);font-size:var(--t-sm);margin-top:6px;max-width:42ch;line-height:1.45}
.og-tag-cubierto{font-family:var(--display);font-size:var(--t-micro);font-weight:700;letter-spacing:var(--tr-eti);text-transform:uppercase;padding:3px 10px;border-radius:999px;border:1px solid rgba(var(--dep-rgb, 212,175,55),.35);color:var(--dep-c, var(--oro));background:rgba(var(--dep-rgb, 212,175,55),.1);white-space:nowrap}
.og-tag-cubierto.og-tag-vac{border-color:rgba(239,68,68,.3);color:#f87171;background:rgba(239,68,68,.08)}
.og-card-b{padding:0}

/* Indicador del departamento: la cifra real manda, lo no medible se apaga. */
.og-med{padding:12px var(--s4);border-top:1px solid rgba(255,255,255,.05);border-bottom:1px solid rgba(255,255,255,.05);background:rgba(var(--dep-rgb, 212,175,55),.03)}
.og-med-meta{font-size:var(--t-eti);color:var(--txt3);margin-bottom:8px;line-height:1.4}
.og-med-meta b{color:var(--txt2);font-weight:600}
.og-med-fila{display:flex;flex-wrap:wrap;gap:8px}
.og-med-cif{flex:1 1 140px;padding:8px 12px;border-radius:var(--r2);border:1px solid rgba(var(--dep-rgb, 212,175,55),.22);background:rgba(0,0,0,.45)}
.og-med-cif b{display:block;font-size:var(--t-base);color:var(--dep-c, var(--oro));letter-spacing:-.01em;font-weight:700}
.og-med-cif small{display:block;margin-top:2px;font-size:var(--t-micro);color:var(--txt3)}
.og-med-no{margin-top:6px;font-size:var(--t-eti);color:var(--txt3);font-style:italic}
.og-med-off .og-med-no{margin-top:0}

/* Casillas de puestos */
.og-fila{padding:13px var(--s4);border-bottom:1px solid rgba(255,255,255,.04);border-left:3px solid var(--dep-c, var(--oro));background:rgba(255,255,255,.01);transition:background .2s}
.og-fila:hover{background:rgba(255,255,255,.025)}
.og-fila:last-child{border-bottom:0}
.og-fila.og-persona{border-left-color:var(--ok)}
.og-fila.og-vacante{border-left-color:var(--warn);background:rgba(239,68,68,.02)}
.og-fila-h{display:flex;align-items:center;gap:9px}
.og-dot{width:7px;height:7px;border-radius:50%;background:var(--dep-c, var(--oro));box-shadow:0 0 8px var(--dep-c, var(--oro));flex:none}
.og-persona .og-dot{background:var(--ok);box-shadow:0 0 8px var(--ok)}
.og-vacante .og-dot{background:transparent;border:1.5px dashed var(--warn);box-shadow:none}
.og-tit{flex:1;font-family:var(--display);font-weight:600;font-size:14.5px;color:var(--plata);letter-spacing:.01em}
.og-est{font-size:10px;font-weight:700;letter-spacing:var(--tr-eti);text-transform:uppercase;padding:2px 7px;border-radius:4px;background:rgba(var(--dep-rgb, 212,175,55),.12);color:var(--dep-c, var(--oro));border:1px solid rgba(var(--dep-rgb, 212,175,55),.25);white-space:nowrap}
.og-persona .og-est{background:rgba(16,185,129,.12);color:var(--ok);border-color:rgba(16,185,129,.3)}
.og-vacante .og-est{background:rgba(239,68,68,.1);color:var(--warn);border-color:rgba(239,68,68,.3)}
.og-ocu{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;margin:6px 0 0 16px;font-size:var(--t-sm);color:var(--txt);font-weight:600}
.og-ag{display:inline-flex;align-items:center;gap:7px}
.og-ag svg,.og-ag .ico{width:15px;height:15px;flex:none;color:var(--dep-c, var(--oro))}
.og-ag small{color:var(--txt3);font-weight:400;font-size:var(--t-min);background:rgba(255,255,255,.05);padding:1px 6px;border-radius:4px}
.og-vac{color:var(--warn)}

/* Facultades: PUEDE / NO PUEDE */
.og-lim-bloque{margin:8px 0 0 16px;display:flex;flex-direction:column;gap:5px}
.og-lim{display:flex;align-items:flex-start;gap:8px;font-size:var(--t-min);line-height:1.5}
.og-lim-tag{flex:none;font-size:9.5px;font-weight:700;letter-spacing:var(--tr-lbl);text-transform:uppercase;padding:1px 6px;border-radius:3px}
.og-lim-tag.si{background:rgba(16,185,129,.12);color:#34d399;border:1px solid rgba(16,185,129,.3)}
.og-lim-tag.no{background:rgba(239,68,68,.1);color:#f87171;border:1px solid rgba(239,68,68,.3)}
.og-lim-items{display:flex;flex-wrap:wrap;gap:4px;color:var(--txt3)}
.og-lim-chip{padding:1px 6px;border-radius:3px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.05);font-size:11.5px}

/* Mesa operativa del agente */
.og-mesa{margin:8px 0 0 16px;padding:9px 12px;border-radius:var(--r2);border:1px solid rgba(255,255,255,.07);background:rgba(0,0,0,.35)}
.og-mesa.og-on{border-color:rgba(var(--dep-rgb, 212,175,55),.35);background:rgba(var(--dep-rgb, 212,175,55),.05);box-shadow:0 0 15px rgba(var(--dep-rgb, 212,175,55),.08)}
.og-mesa-h{display:flex;align-items:center;gap:8px;margin-bottom:6px;flex-wrap:wrap}
.og-pill{font-size:10px;font-weight:700;letter-spacing:var(--tr-eti);text-transform:uppercase;padding:2px 8px;border-radius:999px;border:1px solid rgba(255,255,255,.1);color:var(--txt3);background:rgba(255,255,255,.04)}
.og-on .og-pill{background:var(--dep-c, var(--oro));border-color:var(--dep-c, var(--oro));color:#0b0c0e;font-weight:700;box-shadow:0 0 10px rgba(var(--dep-rgb, 212,175,55),.3)}
.og-niv{font-size:10px;color:var(--txt3);letter-spacing:var(--tr-eti);text-transform:uppercase;font-weight:600;padding:1px 6px;border-radius:3px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.06)}
.og-esp{font-size:12.5px;color:var(--txt);line-height:1.5;font-weight:500}
.og-fte{margin-top:5px;font-size:11.5px;color:var(--txt3);line-height:1.45}
.og-fte b{color:var(--txt2);font-weight:600}
.og-mot{margin-top:5px;font-size:11.5px;color:var(--txt4);line-height:1.45;font-style:italic}
.og-off .og-mot{color:#fbbf24}

@media(max-width:480px){.og-mesa,.og-lim-bloque,.og-ocu{margin-left:0}}

/* ── LA SOCIEDAD: tres socios, no uno ─────────────────────────────── */
.og-socios{margin-bottom:var(--s4);background:radial-gradient(ellipse at 50% 0%, rgba(212,175,55,.08) 0%, #121316 65%, #0d0e11 100%);border-radius:var(--r4);border:1px solid rgba(255,255,255,.07);border-top:3px solid var(--oro)}
.og-soc-fila{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:10px;padding:12px var(--s4)}
.og-soc{display:flex;align-items:center;gap:10px;padding:10px 12px;
  border-radius:var(--r3);background:rgba(0,0,0,.4);border:1px solid rgba(212,175,55,.2);box-shadow:0 4px 14px rgba(0,0,0,.4)}
.og-soc-ini{flex:none;width:36px;height:36px;border-radius:50%;display:grid;place-items:center;
  background:linear-gradient(135deg, #D4AF37 0%, #997A15 100%);color:#0b0c0e;font-family:var(--display);font-weight:800;
  font-size:var(--t-min);letter-spacing:.02em;box-shadow:0 0 10px rgba(212,175,55,.3)}
.og-soc-txt{min-width:0;display:block}
.og-soc-txt b{display:block;font-family:var(--display);font-weight:600;font-size:var(--t-base);
  color:var(--txt);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.og-soc-txt small{display:block;margin-top:1px;font-size:var(--t-micro);color:var(--txt3)}
.og-soc-pend{padding:9px var(--s4) 12px;border-top:1px solid rgba(255,255,255,.05);
  font-size:var(--t-min);color:var(--warn);line-height:1.5}

/* ── LA OFICINA ────────────────────────────────────────────────────── */
.of-intro{color:var(--txt3);font-size:var(--t-sm);margin:0 0 var(--s4);max-width:78ch}
.of-sello{display:inline-block;margin-left:8px;padding:1px 7px;border-radius:var(--r1);
  border:1px solid var(--line2);color:var(--txt4);font-size:var(--t-micro);
  font-variant-numeric:tabular-nums}
.of-num-vac{color:var(--warn)}
.of-grid{grid-template-columns:repeat(auto-fit,minmax(330px,1fr));align-items:start}
.of-esp{margin-bottom:0}
.of-esp-h{align-items:flex-start}
.of-prop{color:var(--txt3);font-size:var(--t-min);margin-top:2px;max-width:44ch}
.of-esp-b{padding:var(--s3) var(--s4) var(--s4);display:flex;flex-direction:column;gap:10px}
.of-esp-vacio{border-style:dashed;background:transparent}
.of-esp-vacio .of-cargo,.of-esp-vacio .of-nadie{color:var(--txt4)}
.of-desierto{color:var(--txt4);font-size:var(--t-min);line-height:1.5;
  border-left:2px solid var(--line2);padding-left:10px}
.of-cargo{font-family:var(--display);font-size:var(--t-micro);font-weight:600;
  letter-spacing:var(--tr-eti);text-transform:uppercase;color:var(--txt4);margin-bottom:4px}
.of-casilla + .of-casilla{border-top:1px solid var(--line);padding-top:10px}
.of-vac .of-nadie{display:flex;align-items:center;gap:8px;color:var(--txt4);
  font-size:var(--t-min)}
.of-ag{border:1px solid var(--line);border-radius:var(--r2);background:var(--card2);
  padding:9px 11px}
.of-ag-h{display:flex;align-items:center;gap:8px}
.of-ico{display:inline-flex;color:var(--txt3);flex:none}
.of-ico svg{width:15px;height:15px}
.of-nom{font-weight:600;font-size:var(--t-sm);color:var(--txt)}
.of-est{margin-left:auto;font-family:var(--display);font-size:var(--t-micro);
  font-weight:600;letter-spacing:var(--tr-lbl);text-transform:uppercase;color:var(--txt3);flex:none}
.of-linea{color:var(--txt2);font-size:var(--t-min);line-height:1.5;margin-top:5px}
.of-hace{color:var(--txt4);font-size:var(--t-micro);margin-top:3px;
  font-variant-numeric:tabular-nums}
.of-trabajando{border-color:rgba(63,185,80,.45)}
.of-trabajando .of-est{color:var(--ok)}
.of-detenido{border-color:rgba(248,81,73,.35)}
.of-detenido .of-est{color:var(--bad)}
.of-persona .of-est{color:var(--oro)}
/* Latido: solo opacidad, sin bucle en JS y sin mover nada de sitio. */
.of-punto{width:7px;height:7px;border-radius:50%;flex:none;background:var(--txt4)}
.of-p-trabajando{background:var(--ok);box-shadow:0 0 0 3px rgba(63,185,80,.14);
  animation:of-late 1.8s ease-in-out infinite}
.of-p-espera{background:var(--oro-osc);animation:of-late 5s ease-in-out infinite}
.of-p-detenido{background:var(--bad)}
.of-p-frenado{background:var(--bad);box-shadow:0 0 0 3px rgba(248,81,73,.14)}
.of-p-pausado{background:var(--line2)}
.of-p-persona{background:var(--oro)}
.of-p-vacante{background:transparent;border:1px dashed var(--line2)}
@keyframes of-late{0%,100%{opacity:1}50%{opacity:.28}}
@media(prefers-reduced-motion:reduce){.of-punto{animation:none}}
@media(max-width:720px){.of-grid{grid-template-columns:1fr}}

/* ── Contabilidad ─────────────────────────────────────────────────────
   Sin librerias: la unica barra es un div con width:var(--barra). El CSP
   bloquea Chart.js y cualquier script que no salga de /public. */
.cb-est{display:flex;flex-direction:column}
.cb-fila{display:flex;align-items:center;gap:10px;padding:10px 0;
  border-bottom:1px solid var(--line)}
.cb-fila:last-child{border-bottom:0}
.cb-lbl{font-family:var(--display);font-size:var(--t-eti);font-weight:600;
  letter-spacing:var(--tr-lbl);text-transform:uppercase;color:var(--txt3);
  min-width:168px;flex:none}
.cb-val{color:var(--txt);font-size:var(--t-sm)}
.cb-dot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--txt4)}
.cb-dot.ok{background:var(--ok);box-shadow:0 0 0 3px rgba(63,185,80,.14)}
.cb-dot.warn{background:var(--warn);box-shadow:0 0 0 3px rgba(210,153,34,.14)}
.cb-dot.bad{background:var(--bad);box-shadow:0 0 0 3px rgba(248,81,73,.14)}
.cb-bar{height:8px;border-radius:var(--r-pill);background:var(--card2);
  border:1px solid var(--line);overflow:hidden;margin-top:16px}
.cb-bar i{display:block;height:100%;width:var(--barra);
  background:linear-gradient(90deg,var(--oro-osc),var(--oro))}
.cb-nota{color:var(--txt3);font-size:var(--t-min);line-height:1.6;margin-top:7px;
  font-family:var(--display);letter-spacing:var(--tr-lbl);text-transform:uppercase}
.cb-aviso{border-left:2px solid var(--warn);background:rgba(210,153,34,.06);
  padding:12px var(--s4);border-radius:0 var(--r2) var(--r2) 0;color:var(--txt2);
  font-size:var(--t-sm);line-height:1.65;max-width:68ch}
@media(max-width:720px){.cb-fila{flex-wrap:wrap}.cb-lbl{min-width:100%}}

/* ── AVISOS EN TARJETA: el bloque "Atencion" se leia a UNA LETRA por linea ──
   Linea 505 declara .aviso{display:flex} para el banderin en linea (icono +
   texto). dashboard.js:186 pone esa MISMA clase sobre una TARJETA entera
   (section.card.aviso.bad), asi que .card-h y .card-b quedaban de lado a
   lado. Medido a 390px: la tarjeta 366px, .card-b se quedaba con 173,1px y
   el texto del aviso con 38,7px -> una letra por renglon, y un solo aviso
   media 2.595px de alto. Una tarjeta NUNCA es una fila: cabecera arriba,
   cuerpo debajo. Se arregla en la casa, no en la vista, porque la regla mal
   aplicada es de la casa y vale para cualquier tarjeta que lleve 'aviso'. */
.card.aviso{display:block}

/* ── .col DENTRO DE UNA FILA: sin min-width:0 no se encoge ──────────────
   .col (linea 276) es la columna del TABLERO y trae min-width:232px. Se
   reusa como "columna de texto" dentro de un .row (panel, preparados). Un
   hijo de flex con min-width:auto no baja de su contenido minimo y aplasta
   a sus hermanos: es exactamente lo que pasaba aqui. El tablero no se toca:
   alli .col cuelga de .board, nunca de .row.                              */
.row > .col{min-width:0;overflow-wrap:break-word}

/* ── FILA DE LISTA CON ACCION AL FINAL, EN MOVIL ────────────────────────
   El texto ocupa el ancho completo y el boton baja a su propia linea,
   pegado a la derecha. 44px de alto: se pulsa con el pulgar, de pie y al
   sol (Apple HIG 44; WCAG 2.5.8 pide 24 como minimo). En pantalla ancha
   sigue todo en una sola linea.                                          */
@media(max-width:720px){
  li.row > form.row{flex:1 0 100%;flex-direction:row;flex-wrap:nowrap;
    justify-content:flex-end;align-items:center;margin-top:var(--s2)}
  li.row > form.row > button,li.row > form.row > .btn{width:auto;min-width:0;
    height:auto;min-height:44px}
}

/* ══════════════════════════════════════════════════════════════════
   EQUIPO E · ACABADO PREMIUM — auditoria del 4-sep sobre la entrega
   de Antigravity. Solo dos arreglos, los dos MEDIDOS con el navegador
   y sesion forjada a 390 / 1024 / 1440 px. Nada de rediseno.
   ══════════════════════════════════════════════════════════════════ */

/* ── E1 · EL TEXTO TENUE NO LLEGABA A AA ──────────────────────────
   --ink3 entro en la entrega con #6E7583. Medido contra las tres
   superficies reales del modo oscuro:
        4,25:1 sobre --bg (#0B0B0C)
        3,98:1 sobre --card (#131416)
        3,68:1 sobre --card2 (#1A1C20)
   WCAG 2.1 AA pide 4,5:1 en texto normal. Y ese token NO es
   decoracion: lo llevan "Todavia no hay actividad registrada" (Panel),
   el correo del vendedor en /pagos, "0,0 mi" en /terreno, el aviso
   "El mapa no cargo" y las descripciones de alertas del Director.
   #8A919F sube a 6,21 / 5,82 / 5,39 y mantiene el escalon de
   jerarquia: sigue por debajo de --ink2 (#A1A7B4), que ya cumplia.
   🔴 Va en los TRES sitios a proposito: los bloques de tema fijan
   --txt3 con el valor a pelo, asi que tocar solo :root deja el modo
   oscuro — el que Hector mira a diario — con el valor viejo.        */
:root{--ink3:#8A919F;--txt3:#8A919F}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){--ink3:#8A919F;--txt3:#8A919F}}
:root[data-theme="dark"]{--ink3:#8A919F;--txt3:#8A919F}

/* ── E2 · LA CASILLA DE CONSENTIMIENTO TCPA ERA INVISIBLE ─────────
   En /nuevo la casilla "El cliente autoriza que le contactemos por
   SMS, WhatsApp..." existia en el HTML pero NO se veia: medida
   1x1 px, position:absolute y clip-path:inset(50%), encima de la
   fila de botones. Un vendedor no podia marcarla ni leerla.
   La causa es la regla de :553, que oculta la PRIMERA etiqueta de un
   formulario "porque el titulo de la tarjeta ya lo dice". En /nuevo
   esa primera etiqueta suelta es justo la del consentimiento: las
   demas viven dentro de <div class="grid">.
   Ya existia una excepcion — :has(~ label), :870 — escrita cuando la
   misma regla se comio Nombre, Contrasena actual y el selector de
   fotos. No cubre este caso porque detras del consentimiento no hay
   ninguna otra etiqueta.
   Se corta la familia entera en vez de anadir un cuarto parche a
   mano: una etiqueta que ENVUELVE un control nunca es un titulo
   repetido; ocultarla borra el control. Especificidad 0,3,3 contra
   los 0,3,2 de la regla original: gana por orden y por peso, sin
   !important y sin tocar lo que ya funciona.
   NO es una regresion de la entrega premium: la regla de :553 esta
   IGUAL, byte a byte, en styles.js.bak_20260904_1625.               */
.card-h + .card-b form > label:first-of-type:has(input,select,textarea){
  position:static;width:auto;height:auto;overflow:visible;
  clip-path:none;white-space:normal;margin:10px 0 4px}


/* ── E3 · EL AVISO DE "EL MAPA NO CARGO" IBA GRIS SOBRE GRIS ──────
   Efecto colateral de E1, y lo aviso porque lo empeore yo: ese
   parrafo NO se pinta sobre las superficies oscuras del CRM, sino
   DENTRO de div.leaflet-container, cuyo fondo propio es #DDDDDD
   (el gris que Leaflet enseña cuando no llegan las teselas).
        antes de E1: #6E7583 sobre #DDD -> 3,41:1  (ya suspendia)
        despues E1 : #8A919F sobre #DDD -> 2,33:1  (peor)
   Es justo el mensaje que hay que poder leer cuando el mapa falla,
   asi que se le da una tinta oscura, propia de ese fondo claro:
   #3F444C sobre #DDDDDD = 7,22:1. Alcance minimo a proposito — solo
   dentro del contenedor de Leaflet: los demas .empty del CRM viven
   sobre --card y siguen con var(--txt3), que ya cumple.             */
.leaflet-container .empty{color:#3F444C}

/* ── E4 — CONTRASTE AA DEL CUARTO NIVEL DE TEXTO (--txt4) ───────────
   Medido en /organigrama a 390/1024/1440 con composicion alfa real:
     .og-pill "Sin operar"  #808080 sobre rgb(26,28,32)  = 4,32:1
     .og-fte b "Fuente:"    #808080 sobre rgb(26,28,32)  = 4,32:1
     .og-fte b "Fuente:"    #808080 sobre rgb(31,29,24)  = 4,26:1  (peor)
     .og-mot                #808080 sobre rgb(31,29,24)  = 4,26:1
   WCAG AA pide 4,5:1 y ninguno de esos textos es decoracion: dicen si
   una mesa opera, de donde sale el dato y por que un agente esta
   dormido. --txt4 se define UNA sola vez para oscuro (:root) y otra
   para claro (:root[data-theme="light"], especificidad 0,2,0), asi
   que este :root de aqui abajo solo pisa el oscuro y deja el modo
   claro exactamente como estaba.
   #828A97 -> 4,90:1 sobre rgb(26,28,32) y 4,84:1 sobre rgb(31,29,24),
   y sigue un peldano por debajo de --txt3 (#8A919F, 5,39:1), asi que
   la jerarquia de los cuatro niveles de tinta se conserva.          */
:root{ --txt4: #828A97 }


/* -- E5 - TACTIL: EL ZOOM DE iOS Y LAS DIANAS DE 44px ----------------
   Medido el 4-sep con PUNTERO GRUESO emulado (hasTouch/isMobile, que
   activa pointer:coarse) sobre las 21 pantallas a 390px. Sin esa
   emulacion el navegador sin ventana declara pointer:fine y la guarda
   de mas arriba NI SIQUIERA SE ACTIVA: por eso una pasada normal
   devuelve una decena de falsos positivos.

   1) ZOOM. La guarda "input,select,textarea{font-size:16px}" tiene
      especificidad 0,0,1, asi que CUALQUIER regla de clase escrita
      despues la pisa. Censo de campos visibles con el dedo: 9 clases
      distintas, tres por debajo de 16px
        input.tr-input-dia 13px  (/terreno, la pantalla del que va a pie)
        select.tr-select   13px  (/terreno)
        input.mn-input     15px  (/mentor)
      y NINGUNA por encima de 16px. Se repite la guarda con dos :not()
      inertes por selector: sube a 0,2,1 y ya gana a una clase suelta.
      Como no hay ni un campo por encima de 16px, esto solo LEVANTA, no
      encoge nada. El escritorio no se toca: sigue todo dentro de
      (pointer:coarse) y la densidad 9/10 se queda como estaba.

   2) DIANAS. A 390px con el dedo, .nav-i mide 37px de alto (min-height
      36 + borde) y .btn.sm 32px. El dedo pide 44x44 (Apple HIG y WCAG
      2.5.5). Se levantan SOLO la navegacion principal, los botones y el
      disparador del chat: son exactamente las 25 dianas cortas que se
      midieron en /leads. Quedan fuera A PROPOSITO los enlaces sueltos
      dentro de un parrafo (estirarlos rompe el interlineado del texto)
      y los pines de Leaflet, que se colocan por coordenada.
      .btn.sm se nombra aparte porque su min-height:32px es 0,2,0 y una
      regla ".btn" a secas no lo alcanza.                              */
@media(pointer:coarse){
  input:not([hidden]):not([aria-hidden="true"]),
  select:not([hidden]):not([aria-hidden="true"]),
  textarea:not([hidden]):not([aria-hidden="true"]){font-size:16px}
  .nav-i{min-height:44px}
  .btn,.btn.sm{min-height:44px}
  .chat-abrir{min-height:44px;min-width:44px}
}

