:root{
  --bg:#F1F3EE; --surface:#FCFCFB; --surface-2:#F6F8F3; --surface-3:#EDF0E8;
  --line:#E2E6DC; --line-2:#CBD1C3; --line-3:#B3BBA9;
  --ink:#171A15; --ink-2:#454B3F; --muted:#6E7568; --muted-2:#8B9283;
  --accent:#0B6552; --accent-ink:#FFFFFF; --accent-soft:#E2EFE9; --accent-line:#9CC6B7;
  --pos:#1F7A4D; --neg:#BE3B2B; --warn:#9C6B0C;
  --r1:#05846A; --r2:#C2701A; --r3:#2166A8; --r4:#BE2F4E; --r5:#7E9411; --r6:#7A4FC0;
  --r1-s:#E0F0EB; --r2-s:#F7EBDD; --r3-s:#E2ECF6; --r4-s:#F8E4E8; --r5-s:#EEF2DC; --r6-s:#EDE6F8;
  --grid-line:#E6E9E1;
  --shadow:0 1px 2px rgba(20,26,18,.06), 0 8px 24px -12px rgba(20,26,18,.18);
  --shadow-lg:0 2px 6px rgba(20,26,18,.08), 0 24px 60px -20px rgba(20,26,18,.32);
  --edit-bg:#FFF8E6; --edit-line:#C9A43C;
  /* Banda superior: es oscura en los dos temas, asi que no deriva de --surface.
     El logo corporativo es blanco y solo se lee sobre este azul. */
  --top-bg:#0E2A4E; --top-soft:#1B3C63; --top-ink:#F4F8FD; --top-muted:#A9BFD8;
  --top-line:#2A4C74; --top-accent:#7FE0C0;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#0E100D; --surface:#1A1A19; --surface-2:#212320; --surface-3:#282B26;
    --line:#2E312C; --line-2:#3D413A; --line-3:#4E534A;
    --ink:#EAECE5; --ink-2:#B6BBAF; --muted:#8B9283; --muted-2:#6E7568;
    --accent:#4FD0A8; --accent-ink:#0E100D; --accent-soft:#16302A; --accent-line:#2C5F51;
    --pos:#54C88B; --neg:#F0776A; --warn:#DFA53B;
    --r1:#1FA680; --r2:#C67D2C; --r3:#4A87CC; --r4:#E24E77; --r5:#7F9A22; --r6:#9A79DE;
    --r1-s:#122A24; --r2-s:#2C2317; --r3-s:#17222E; --r4-s:#2E1A21; --r5-s:#20260F; --r6-s:#221C33;
    --grid-line:#292C26;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.7);
    --shadow-lg:0 2px 6px rgba(0,0,0,.5), 0 24px 60px -20px rgba(0,0,0,.85);
    --edit-bg:#2B2513; --edit-line:#9A7C22;
    --top-bg:#1A3F6B; --top-soft:#25517F; --top-ink:#EAF1F9; --top-muted:#9FB8D6;
    --top-line:#33608F; --top-accent:#7FE0C0;
  }
}
:root[data-theme="dark"]{
  --bg:#0E100D; --surface:#1A1A19; --surface-2:#212320; --surface-3:#282B26;
  --line:#2E312C; --line-2:#3D413A; --line-3:#4E534A;
  --ink:#EAECE5; --ink-2:#B6BBAF; --muted:#8B9283; --muted-2:#6E7568;
  --accent:#4FD0A8; --accent-ink:#0E100D; --accent-soft:#16302A; --accent-line:#2C5F51;
  --pos:#54C88B; --neg:#F0776A; --warn:#DFA53B;
  --r1:#1FA680; --r2:#C67D2C; --r3:#4A87CC; --r4:#E24E77; --r5:#7F9A22; --r6:#9A79DE;
  --r1-s:#122A24; --r2-s:#2C2317; --r3-s:#17222E; --r4-s:#2E1A21; --r5-s:#20260F; --r6-s:#221C33;
  --grid-line:#292C26;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.7);
  --shadow-lg:0 2px 6px rgba(0,0,0,.5), 0 24px 60px -20px rgba(0,0,0,.85);
  --edit-bg:#2B2513; --edit-line:#9A7C22;
  --top-bg:#1A3F6B; --top-soft:#25517F; --top-ink:#EAF1F9; --top-muted:#9FB8D6;
  --top-line:#33608F; --top-accent:#7FE0C0;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:13px; line-height:1.45; -webkit-font-smoothing:antialiased;
}
.num{font-family:"IBM Plex Mono",ui-monospace,Consolas,monospace; font-variant-numeric:tabular-nums}
h1,h2,h3,h4{font-family:Archivo,"IBM Plex Sans",system-ui,sans-serif; margin:0; text-wrap:balance; letter-spacing:-.01em}
button{font:inherit; color:inherit; background:none; border:none; cursor:pointer}
:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:3px}

/* ---------- shell ---------- */
.app{height:100dvh; display:grid; grid-template-rows:auto 1fr; overflow:hidden}
.topbar{display:flex; align-items:center; gap:18px; padding:0 16px; height:54px;
  background:var(--top-bg); color:var(--top-ink); border-bottom:1px solid var(--top-line);
  position:relative; z-index:60}
.brand{display:flex; align-items:center; gap:11px; padding-right:16px; border-right:1px solid var(--top-line); height:100%}
/* Logo corporativo: es blanco con transparencia, asi que solo se lee sobre la banda
   azul o sobre la placa del login. Escala por alto y el ancho lo deduce el navegador
   de la proporcion nativa (~3.4:1): nunca se fijan los dos lados, no se deforma. */
.brandmark{display:block; height:26px; max-height:34px; width:auto; object-fit:contain; flex:none}
.brand b{font-family:Archivo; font-weight:700; font-size:15px; letter-spacing:-.025em; display:block; line-height:1.15}
.brand span{display:block; font-size:9.5px; color:var(--top-muted); letter-spacing:.09em; text-transform:uppercase; font-weight:600}
.ciclo{display:flex; align-items:center; gap:9px}
.ciclo .yr{font-family:Archivo; font-weight:700; font-size:19px; letter-spacing:-.03em}
.ciclo .cap{font-size:9.5px; letter-spacing:.09em; text-transform:uppercase; color:var(--top-muted); font-weight:600}
.pill{display:inline-flex; align-items:center; gap:5px; font-size:10.5px; font-weight:600; letter-spacing:.04em;
  text-transform:uppercase; padding:3px 8px; border-radius:999px; border:1px solid var(--line-2); color:var(--muted)}
.pill.on{background:var(--accent-soft); border-color:var(--accent-line); color:var(--accent)}
.pill .dot{width:6px; height:6px; border-radius:50%; background:currentColor}
.topbar .spacer{flex:1}
.deadline{text-align:right; font-size:10.5px; color:var(--muted); line-height:1.35}
.deadline b{display:block; font-size:12px; color:var(--ink-2); font-weight:600}
.user{display:flex; align-items:center; gap:9px; padding-left:14px; border-left:1px solid var(--top-line); height:100%}
.avatar{width:29px; height:29px; border-radius:50%; background:var(--surface-3); border:1px solid var(--line-2);
  display:grid; place-items:center; font-size:10.5px; font-weight:700; color:var(--ink-2); font-family:Archivo}
.user .who{font-size:11.5px; font-weight:600; line-height:1.25}
.user .who span{display:block; font-size:10px; color:var(--muted); font-weight:400}
.icon-btn{width:30px; height:30px; border-radius:8px; border:1px solid var(--line); display:grid; place-items:center;
  color:var(--muted-2); font-size:14px}
.icon-btn:hover{background:var(--surface-2); color:var(--ink-2)}

/* ---------- contenido de la banda superior ----------
   Los tokens generales (--muted, --ink-2, --line, --surface) estan calibrados contra
   el fondo claro de la pagina; sobre el azul de la banda no contrastan. Todo lo que
   vive dentro de la topbar se repinta con los tokens --top-*. */
.topbar .pill{border-color:var(--top-line); color:var(--top-muted)}
.topbar .pill.on{background:var(--top-soft); border-color:var(--top-accent); color:var(--top-accent)}
.topbar .deadline{color:var(--top-muted)}
.topbar .deadline b{color:var(--top-ink)}
.topbar .ver{color:var(--top-muted)}
.topbar .seg{background:var(--top-soft)}
.topbar .seg button{color:var(--top-muted)}
.topbar .seg button:hover{color:var(--top-ink)}
/* El activo del mockup se resuelve con --surface, que sobre el azul desaparece:
   aca se invierte, chip claro con el texto del color de la banda. */
.topbar .seg button[aria-pressed="true"]{background:var(--top-ink); color:var(--top-bg); box-shadow:none}
.topbar .avatar{background:var(--top-soft); border-color:var(--top-line); color:var(--top-ink)}
.topbar .user .who span{color:var(--top-muted)}
.topbar .icon-btn{border-color:var(--top-line); color:var(--top-muted)}
.topbar .icon-btn:hover{background:var(--top-soft); color:var(--top-ink)}
/* El foco de teclado hereda --accent, que es verde oscuro en tema claro y sobre el
   azul casi no se ve. Dentro de la banda usa el acento claro. */
.topbar :focus-visible{outline-color:var(--top-accent)}

.body{display:grid; grid-template-columns:314px minmax(0,1fr); min-height:0}

/* ---------- portafolio ---------- */
.rail{background:var(--surface); border-right:1px solid var(--line); display:flex; flex-direction:column; min-height:0}
.rail-head{padding:13px 14px 10px; border-bottom:1px solid var(--line); display:flex; flex-direction:column; gap:9px}
.rail-head .t{display:flex; align-items:baseline; justify-content:space-between}
.rail-head h2{font-size:13.5px; font-weight:600}
.rail-head .t em{font-style:normal; font-size:11px; color:var(--muted)}
.search{display:flex; align-items:center; gap:7px; background:var(--surface-2); border:1px solid var(--line);
  border-radius:8px; padding:0 9px; height:31px}
.search input{border:none; background:none; outline:none; font:inherit; font-size:12px; color:var(--ink); width:100%}
.search input::placeholder{color:var(--muted-2)}
.chips{display:flex; gap:5px; flex-wrap:wrap}
.chip{font-size:11px; padding:3px 9px; border-radius:999px; border:1px solid var(--line); color:var(--muted); background:var(--surface-2)}
.chip:hover{color:var(--ink-2); border-color:var(--line-2)}
.chip[aria-pressed="true"]{background:var(--ink); border-color:var(--ink); color:var(--surface)}
.rail-list{overflow-y:auto; flex:1; padding:6px; display:flex; flex-direction:column; gap:2px}
.cli{width:100%; text-align:left; display:grid; gap:6px; padding:9px 10px; border-radius:9px; border:1px solid transparent}
.cli:hover{background:var(--surface-2)}
.cli[aria-current="true"]{background:var(--accent-soft); border-color:var(--accent-line)}
.cli .l1{display:flex; align-items:center; gap:7px}
.cli .st{width:7px; height:7px; border-radius:50%; flex:none}
.st.pend{background:var(--line-3)} .st.proc{background:var(--warn)} .st.list{background:var(--pos)}
.cli .nm{font-size:12.5px; font-weight:600; letter-spacing:-.005em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.cli .l2{display:flex; align-items:center; gap:6px; font-size:10.5px; color:var(--muted)}
.cli .l2 code{font-family:"IBM Plex Mono",monospace; font-size:10px; color:var(--muted-2)}
.cli .l3{display:flex; align-items:center; gap:8px}
.bar{flex:1; height:4px; border-radius:2px; background:var(--surface-3); overflow:hidden}
.bar i{display:block; height:100%; background:var(--accent); border-radius:2px; transition:width .25s ease}
/* Cuenta sin meta asignada: la barra no mide nada, asi que se muestra vacia y
   apenas insinuada. Pintarla en 0 con el mismo contraste que una barra real
   diria que la cuenta va atrasada contra una meta que no existe. */
.bar.nometa{background:transparent; border:1px dashed var(--line); height:6px; cursor:help}
.bar.nometa i{display:none}
.cli .amt{font-size:10.5px; color:var(--ink-2); font-weight:500}
.rail-foot{border-top:1px solid var(--line); padding:11px 14px; display:grid; gap:8px; background:var(--surface-2)}
.rf-row{display:flex; align-items:baseline; justify-content:space-between; font-size:11.5px; color:var(--muted)}
.rf-row b{font-size:14px; color:var(--ink); font-weight:600}
.meter{height:6px; border-radius:3px; background:var(--surface-3); overflow:hidden; display:flex; gap:1px}
.meter i{display:block; height:100%}

/* ---------- cabecera cliente ---------- */
.main{min-width:0; display:flex; flex-direction:column; min-height:0; background:var(--bg)}
.cli-head{padding:12px 20px 0; background:var(--surface); border-bottom:1px solid var(--line)}
.ch-top{display:flex; align-items:flex-start; gap:16px; flex-wrap:wrap}
.ch-top h1{font-size:21px; font-weight:700; letter-spacing:-.028em}
.ch-meta{display:flex; align-items:center; gap:6px; margin-top:6px; flex-wrap:wrap}
.tag{font-size:10.5px; padding:2px 7px; border-radius:5px; background:var(--surface-3); color:var(--ink-2); font-weight:500}
.tag.code{font-family:"IBM Plex Mono",monospace; letter-spacing:.02em; color:var(--muted)}
.ch-actions{margin-left:auto; display:flex; gap:8px; align-items:center}
.btn{display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 13px; border-radius:8px;
  border:1px solid var(--line-2); font-size:12px; font-weight:500; background:var(--surface); white-space:nowrap}
.btn:hover{background:var(--surface-2); border-color:var(--line-3)}
.btn.primary{background:var(--accent); border-color:var(--accent); color:var(--accent-ink); font-weight:600}
.btn.primary:hover{filter:brightness(1.08); background:var(--accent)}
.btn.ghost{border-color:transparent; background:transparent; color:var(--muted)}
.btn.ghost:hover{background:var(--surface-2); color:var(--ink-2)}
.btn:disabled{opacity:.42; cursor:not-allowed}
.btn .badge{font-size:10px; font-weight:600; background:var(--surface-3); border-radius:999px; padding:1px 6px; color:var(--ink-2)}

.kpis{display:grid; grid-template-columns:repeat(4,minmax(120px,1fr)) minmax(240px,1.25fr); margin-top:11px;
  border-top:1px solid var(--line)}
.kpi{padding:9px 18px 10px; border-right:1px solid var(--line)}
.kpi:first-child{padding-left:0}
.kpi .lbl{font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600}
.kpi .val{font-family:Archivo; font-weight:700; font-size:20px; letter-spacing:-.035em; margin-top:2px;
  display:flex; align-items:baseline; gap:5px; font-variant-numeric:tabular-nums}
.kpi .val small{font-family:"IBM Plex Sans"; font-size:11px; font-weight:500; color:var(--muted); letter-spacing:0}
.kpi .sub{font-size:11px; color:var(--muted); margin-top:3px; display:flex; align-items:center; gap:5px}
.delta{font-weight:600; font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums}
.delta.up{color:var(--pos)} .delta.dn{color:var(--neg)} .delta.eq{color:var(--muted)}
.mixwrap{padding:9px 0 10px 18px; display:flex; flex-direction:column; gap:6px; justify-content:center; min-width:0}
.mixbar{display:flex; gap:2px; height:9px}
.mixbar i{display:block; border-radius:2px; min-width:2px}
.mixlegend{display:flex; flex-wrap:wrap; gap:3px 10px; font-size:10.5px; color:var(--muted)}
.mixlegend span{display:inline-flex; align-items:center; gap:4px; white-space:nowrap}
.mixlegend s{width:7px; height:7px; border-radius:2px; text-decoration:none; flex:none}
.mixlegend b{color:var(--ink-2); font-weight:600; font-family:"IBM Plex Mono",monospace}

.toolbar{display:flex; align-items:center; gap:10px; padding:8px 20px; border-bottom:1px solid var(--line);
  background:var(--surface-2); flex-wrap:wrap}
.seg{display:flex; background:var(--surface-3); border-radius:8px; padding:2px; gap:2px}
.seg button{font-size:11.5px; padding:4px 11px; border-radius:6px; color:var(--muted); font-weight:500}
.seg button[aria-pressed="true"]{background:var(--surface); color:var(--ink); box-shadow:var(--shadow); font-weight:600}
.toolbar .sep{width:1px; height:20px; background:var(--line)}
.toolbar .spacer{flex:1}
.hint{font-size:11px; color:var(--muted); display:flex; align-items:center; gap:6px}
.kbd{font-family:"IBM Plex Mono",monospace; font-size:10px; border:1px solid var(--line-2); border-bottom-width:2px;
  border-radius:4px; padding:0 4px; color:var(--muted-2); background:var(--surface)}

.scroll{flex:1; min-height:0; padding:14px 20px 16px; display:flex; flex-direction:column; gap:13px; overflow:hidden}

/* ---------- panel gráfico ---------- */
.card{background:var(--surface); border:1px solid var(--line); border-radius:12px; box-shadow:var(--shadow)}
.chartcard{padding:11px 15px 6px; flex:none}
.chartcard[hidden]{display:none}
.cc-head{display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:6px}
.cc-head h3{font-size:12.5px; font-weight:600}
.cc-head p{margin:0; font-size:11px; color:var(--muted)}
.legend{margin-left:auto; display:flex; gap:14px; font-size:10.5px; color:var(--muted); align-items:center}
.legend span{display:inline-flex; align-items:center; gap:5px}
.legend s{text-decoration:none; display:inline-block}
.legend s.fill{width:9px; height:9px; border-radius:2px; background:var(--accent)}
.legend s.tend{width:12px; height:2px; background:var(--ink-2)}
.legend s.tras{width:9px; height:9px; border-radius:2px; border:1.5px dashed var(--r6)}
#chart{width:100%; height:98px; display:block; overflow:visible}
.chart-x{display:grid; grid-template-columns:repeat(12,1fr); font-size:10px; color:var(--muted); text-align:center; margin-top:2px}
.chart-x b{font-weight:600; color:var(--ink-2)}

/* ---------- grilla ---------- */
.gridwrap{flex:1; min-height:0; overflow:auto; border:1px solid var(--line); border-radius:12px;
  background:var(--surface); box-shadow:var(--shadow)}
table.g{border-collapse:separate; border-spacing:0; width:100%; min-width:1288px}
table.g th, table.g td{padding:0; font-weight:400; text-align:right; white-space:nowrap}
table.g thead th{position:sticky; top:0; z-index:30; background:var(--surface-2); border-bottom:1px solid var(--line-2);
  font-size:10px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); font-weight:600;
  padding:9px 8px; height:34px}
table.g thead th.c0{text-align:left; z-index:40; left:0; padding-left:14px; min-width:330px; width:330px}
table.g thead th.mes{width:66px; min-width:66px}
table.g thead th.q3{border-left:1px dotted var(--line-2)}
table.g thead th.tot{width:86px; min-width:86px; border-left:1px solid var(--line-2); color:var(--ink-2)}
table.g thead th.dif{width:80px; min-width:80px}
table.g td.c0, table.g th.c0{position:sticky; left:0; z-index:20; text-align:left; background:var(--surface)}
table.g tr.rubro td{background:var(--surface-3)}
table.g tr.fam td{background:var(--surface-2)}
table.g tr.ref td{background:var(--surface-2)}
table.g tr.foot td{background:var(--surface-3)}
table.g tr.foot2 td{background:var(--surface-2)}
table.g tr.empty td{background:var(--surface)}
table.g td{border-bottom:1px solid var(--grid-line); height:32px; padding:0 8px}
table.g td.q3{border-left:1px dotted var(--grid-line)}
table.g td.tot{border-left:1px solid var(--line); font-weight:600; color:var(--ink-2)}
td.c0{border-right:1px solid var(--line); padding:0 10px 0 0}

.cellwrap{display:flex; align-items:center; gap:8px; min-height:32px}
.twist{width:18px; height:18px; border-radius:4px; display:grid; place-items:center; color:var(--muted-2); flex:none}
.twist:hover{background:var(--line); color:var(--ink)}
.twist svg{transition:transform .16s ease}
.twist[aria-expanded="true"] svg{transform:rotate(90deg)}
.stripe{width:3px; align-self:stretch; border-radius:0 2px 2px 0; flex:none}

tr.rubro .cellwrap{min-height:40px; padding-left:0}
.rubro-name{font-family:Archivo; font-weight:700; font-size:12.5px; letter-spacing:-.01em; display:flex; align-items:center; gap:8px}
.rubro-n{font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:600; width:17px; height:17px; border-radius:4px;
  display:grid; place-items:center; color:#fff}
.rubro-sub{font-size:10px; color:var(--muted); font-weight:400; font-family:"IBM Plex Sans"}
.count{font-size:10px; color:var(--muted); background:var(--surface); border:1px solid var(--line); border-radius:999px; padding:0 6px}

tr.fam .fam-name{font-size:12px; font-weight:600; color:var(--ink-2); display:flex; align-items:center; gap:7px}
.fam-ico{width:6px; height:6px; border-radius:1px; transform:rotate(45deg); flex:none}

tr.sku td.c0{padding-left:0}
.sku-name{display:flex; align-items:center; gap:8px; min-width:0}
.sku-code{font-family:"IBM Plex Mono",monospace; font-size:10px; color:var(--muted-2); flex:none}
.sku-t{font-size:12px; overflow:hidden; text-overflow:ellipsis}
.sku-t em{font-style:normal; color:var(--muted); font-size:10.5px}
tr.sku:hover td{background:var(--accent-soft)}
tr.sku:hover td.c0{background:var(--accent-soft)}

.mescell{position:relative}
.mescell input{width:100%; height:26px; border:1px solid transparent; border-radius:5px; background:transparent;
  text-align:right; font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; font-size:12px;
  color:var(--ink); padding:0 5px; outline:none; -moz-appearance:textfield}
.mescell input::-webkit-outer-spin-button, .mescell input::-webkit-inner-spin-button{-webkit-appearance:none; margin:0}
.mescell input:hover{border-color:var(--line-2); background:var(--surface)}
.mescell input:focus{border-color:var(--accent); background:var(--surface); box-shadow:0 0 0 2px var(--accent-soft)}
.mescell input.edited{background:var(--edit-bg); border-color:var(--edit-line); font-weight:500}
.mescell.moved::after{content:""; position:absolute; top:3px; right:3px; width:5px; height:5px; border-radius:50%;
  background:var(--r6)}
.mescell.zero input{color:var(--muted-2)}

.refline{font-size:11px; color:var(--muted); font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums}
tr.ref td{height:27px; border-bottom:1px dotted var(--grid-line)}
tr.ref .yr{display:flex; align-items:center; gap:8px; padding-left:56px; font-size:11px; color:var(--muted)}
tr.ref .yr b{font-family:"IBM Plex Mono",monospace; font-weight:600; color:var(--ink-2); font-size:11px}
table.g tr.ref.tend td{background:var(--accent-soft); border-bottom:1px solid var(--accent-line)}
tr.ref.tend .yr b, tr.ref.tend .refline{color:var(--accent)}
.proy{opacity:.62; font-style:italic}
.sparkbox{display:flex; align-items:flex-end; gap:2px; height:16px; margin-left:auto; padding-right:6px}
.sparkbox i{width:5px; border-radius:1px; background:var(--line-3); display:block}
.sparkbox i.ppto{background:var(--accent)}

tr.empty td{height:44px}
.emptybox{display:flex; align-items:center; gap:9px; padding-left:56px; font-size:11.5px; color:var(--muted)}
.linkbtn{color:var(--accent); font-weight:600; font-size:11.5px; text-decoration:underline; text-underline-offset:2px}

.rowact{display:flex; gap:2px; margin-left:auto; opacity:0; transition:opacity .12s}
tr.sku:hover .rowact, tr.sku:focus-within .rowact{opacity:1}
.miniact{width:22px; height:22px; border-radius:5px; display:grid; place-items:center; color:var(--muted-2); font-size:12px}
.miniact:hover{background:var(--surface-3); color:var(--ink)}

tr.foot td{height:40px; border-top:2px solid var(--line-2); border-bottom:none; font-weight:600; position:sticky; bottom:0; z-index:25}
tr.foot td.c0{z-index:35}
tr.foot .f-name{font-family:Archivo; font-weight:700; font-size:12.5px; padding-left:14px}
tr.foot2 td{height:30px; border-top:1px solid var(--line); font-weight:400; color:var(--muted);
  position:sticky; bottom:40px; z-index:24}
tr.foot2 td.c0{z-index:34}
tr.foot2 .f-name{font-family:"IBM Plex Sans"; font-weight:500; font-size:11.5px; color:var(--muted); padding-left:14px}

table.g[data-hot] td[data-hot-on], table.g[data-hot] th[data-hot-on]{
  background-image:linear-gradient(var(--hot-tint),var(--hot-tint))}
:root{--hot-tint:rgba(11,101,82,.055)}
:root[data-theme="dark"]{--hot-tint:rgba(79,208,168,.075)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--hot-tint:rgba(79,208,168,.075)}}

/* ---------- modal / drawer ---------- */
.scrim{position:fixed; inset:0; background:rgba(12,16,10,.42); backdrop-filter:blur(2px); z-index:100;
  display:grid; place-items:center; padding:24px}
.modal{background:var(--surface); border:1px solid var(--line-2); border-radius:14px; box-shadow:var(--shadow-lg);
  width:min(520px,100%); max-height:100%; overflow:auto}
.m-head{padding:15px 18px 12px; border-bottom:1px solid var(--line)}
.m-head h3{font-size:15px; font-weight:700; letter-spacing:-.02em}
.m-head p{margin:3px 0 0; font-size:11.5px; color:var(--muted)}
.m-body{padding:16px 18px; display:grid; gap:13px}
.m-foot{padding:12px 18px; border-top:1px solid var(--line); display:flex; gap:8px; justify-content:flex-end; background:var(--surface-2);
  border-radius:0 0 13px 13px}
.field{display:grid; gap:5px}
.field label{font-size:10.5px; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); font-weight:600}
.field select, .field input[type="number"], .field input[type="text"]{
  height:34px; border:1px solid var(--line-2); border-radius:8px; background:var(--surface); color:var(--ink);
  font:inherit; font-size:12.5px; padding:0 9px; outline:none}
.field select:focus, .field input:focus{border-color:var(--accent); box-shadow:0 0 0 2px var(--accent-soft)}
.row2{display:grid; grid-template-columns:1fr auto 1fr; gap:10px; align-items:end}
.arrowmid{padding-bottom:9px; color:var(--muted); font-size:15px}
.note{font-size:11.5px; color:var(--muted); background:var(--surface-2); border:1px solid var(--line);
  border-left:3px solid var(--r6); border-radius:0 8px 8px 0; padding:8px 11px; line-height:1.5}
.note b{color:var(--ink-2)}

.drawer{position:fixed; top:0; right:0; height:100dvh; width:min(420px,92vw); background:var(--surface);
  border-left:1px solid var(--line-2); box-shadow:var(--shadow-lg); z-index:110; display:flex; flex-direction:column}
.d-head{padding:15px 18px 13px; border-bottom:1px solid var(--line); display:flex; align-items:flex-start; gap:12px}
.d-head h3{font-size:15px; font-weight:700; letter-spacing:-.02em}
.d-head p{margin:3px 0 0; font-size:11.5px; color:var(--muted)}
.d-list{flex:1; overflow-y:auto; padding:10px 14px; display:flex; flex-direction:column; gap:8px}
.tras{border:1px solid var(--line); border-radius:10px; padding:10px 11px; background:var(--surface-2); display:grid; gap:6px}
.tras .t1{display:flex; align-items:center; gap:8px; font-size:12px; font-weight:600}
.tras .mv{display:inline-flex; align-items:center; gap:6px; font-family:"IBM Plex Mono",monospace; font-size:11.5px;
  color:var(--ink-2); background:var(--surface); border:1px solid var(--line); border-radius:6px; padding:2px 7px}
.tras .mv b{color:var(--r6)}
.tras .t2{font-size:11px; color:var(--muted); display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.emptydrawer{padding:34px 18px; text-align:center; color:var(--muted); font-size:12px; line-height:1.6}

.toast{position:fixed; left:50%; bottom:76px; transform:translateX(-50%) translateY(8px); opacity:0;
  background:var(--ink); color:var(--bg); font-size:12.5px; font-weight:500; padding:10px 16px; border-radius:9px;
  box-shadow:var(--shadow-lg); z-index:200; pointer-events:none; transition:opacity .2s, transform .2s; display:flex; align-items:center; gap:8px}
.toast.show{opacity:1; transform:translateX(-50%) translateY(0)}

.tip{position:fixed; z-index:150; pointer-events:none; background:var(--surface); border:1px solid var(--line-2);
  border-radius:9px; box-shadow:var(--shadow-lg); padding:9px 11px; font-size:11.5px; min-width:150px; opacity:0;
  transition:opacity .12s}
.tip.show{opacity:1}
.tip h5{margin:0 0 6px; font-family:Archivo; font-size:11.5px; font-weight:700; letter-spacing:.02em}
.tip .tr{display:flex; justify-content:space-between; gap:16px; color:var(--muted)}
.tip .tr b{color:var(--ink); font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; font-weight:600}

@media (prefers-reduced-motion: reduce){*{transition:none !important; animation:none !important}}

@media (max-width:1080px){
  .body{grid-template-columns:minmax(0,1fr); grid-template-rows:auto minmax(0,1fr)}
  .rail{border-right:none; border-bottom:1px solid var(--line); max-height:210px}
  .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
  .kpi:nth-child(2n){border-right:none}
  .mixwrap{grid-column:1/-1; padding-left:0; border-top:1px solid var(--line); padding-top:11px}
}

/* =============================================================================
   Extensiones de la plataforma
   Login, cambio de vista, bandeja de revision, consolidado, estados de carga.
   Usan las mismas custom properties del mockup: no se redefine ningun token.
   ============================================================================= */

/* [hidden] tiene que ganarle a las reglas de display de las clases del shell */
[hidden]{display:none !important}

/* ---------- utilidades que reemplazan estilos inline del markup ---------- */
.search.sm{width:210px; height:29px}
.dash{color:var(--muted-2)}
.mixwrap .lbl{font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600}
.pill.prospect{border-color:var(--r5); color:var(--r5)}
tr.ref .yr.head{padding-left:70px; color:var(--muted-2); font-size:10px; letter-spacing:.09em;
  text-transform:uppercase; font-weight:600}
tr.ref .yr .note{font-size:10px}
table.g tr.ref td.tot.soft{font-weight:400; color:var(--muted)}
table.g tr.ref.tend td.tot{color:var(--accent)}
table.g tr.foot2 td.tot{font-weight:400; color:var(--muted)}
tr.sku td.mescell .ro{display:block; text-align:right; padding-right:5px; color:var(--ink)}
tr.sku td.mescell.zero .ro{color:var(--muted-2)}

/* ---------- topbar: version, selector de vista, estado de guardado ---------- */
.ver{font-family:"IBM Plex Mono",monospace; font-size:10px; color:var(--muted-2); letter-spacing:.02em}
.topbar .seg{margin-left:4px}
.savestate{display:inline-flex; align-items:center; gap:6px; font-size:11px; color:var(--muted);
  min-width:84px; justify-content:flex-end}
.savestate.busy{color:var(--warn)}
.savestate.err{color:var(--neg)}
.savestate .dot{width:6px; height:6px; border-radius:50%; background:currentColor; flex:none}

/* ---------- login ---------- */
.login{position:fixed; inset:0; z-index:300; background:var(--bg); display:grid; place-items:center; padding:24px}
.login-card{width:min(390px,100%); background:var(--surface); border:1px solid var(--line);
  border-radius:14px; box-shadow:var(--shadow-lg); overflow:hidden}
/* El fondo del login es claro y el logo es blanco: sin placa de color no se veria
   nada. La marca se apoya en una banda azul a sangre, la misma de la topbar. */
.login-head{padding:0 0 15px; display:grid; gap:14px}
.login-brand{display:flex; align-items:center; gap:11px; padding:15px 22px;
  background:var(--top-bg); color:var(--top-ink); border-bottom:1px solid var(--top-line)}
.login-brand .brandmark{height:30px; max-height:38px}
.login-copy{padding:0 22px}
.login-head h1{font-size:19px; font-weight:700; letter-spacing:-.025em}
.login-head p{margin:0; font-size:11.5px; color:var(--muted)}
.login-body{padding:0 22px 18px; display:grid; gap:13px}
.login-foot{padding:11px 22px; border-top:1px solid var(--line); background:var(--surface-2);
  display:flex; align-items:center; justify-content:space-between; font-size:10.5px; color:var(--muted)}
.formerror{font-size:11.5px; color:var(--neg); min-height:15px; line-height:1.3}
.btn.block{width:100%; justify-content:center; height:36px}

/* ---------- campos extra ---------- */
.field input[type="password"], .field input[type="search"]{
  height:34px; border:1px solid var(--line-2); border-radius:8px; background:var(--surface); color:var(--ink);
  font:inherit; font-size:12.5px; padding:0 9px; outline:none}
.field textarea{border:1px solid var(--line-2); border-radius:8px; background:var(--surface); color:var(--ink);
  font:inherit; font-size:12.5px; padding:8px 9px; outline:none; min-height:74px; resize:vertical}
.field input[type="password"]:focus, .field input[type="search"]:focus, .field textarea:focus{
  border-color:var(--accent); box-shadow:0 0 0 2px var(--accent-soft)}
.field .help{font-size:10.5px; color:var(--muted)}

/* ---------- estados de cuenta adicionales ---------- */
.st.subm{background:var(--r3)}
.st.appr{background:var(--accent)}
.st.retn{background:var(--neg)}
.pill.st-pend{border-color:var(--line-2); color:var(--muted)}
.pill.st-proc{border-color:var(--warn); color:var(--warn)}
.pill.st-list{border-color:var(--pos); color:var(--pos)}
.pill.st-subm{border-color:var(--r3); color:var(--r3)}
.pill.st-appr{border-color:var(--accent-line); color:var(--accent); background:var(--accent-soft)}
.pill.st-retn{border-color:var(--neg); color:var(--neg)}

/* ---------- paginacion server-side ---------- */
.pager{display:flex; align-items:center; gap:8px; font-size:11px; color:var(--muted)}
.pager .pg{font-family:"IBM Plex Mono",monospace; color:var(--ink-2)}
.pgbtn{width:26px; height:26px; border-radius:7px; border:1px solid var(--line-2); display:grid;
  place-items:center; color:var(--muted-2); font-size:12px; background:var(--surface)}
.pgbtn:hover:not(:disabled){background:var(--surface-2); color:var(--ink-2)}
.pgbtn:disabled{opacity:.4; cursor:not-allowed}
.rail-pager{display:flex; align-items:center; justify-content:space-between; gap:8px}

/* ---------- vistas de gerencia ---------- */
.view{min-width:0; min-height:0; display:flex; flex-direction:column; background:var(--bg)}
.view-head{padding:13px 20px; background:var(--surface); border-bottom:1px solid var(--line);
  display:flex; align-items:center; gap:14px; flex-wrap:wrap}
.view-head h1{font-size:19px; font-weight:700; letter-spacing:-.025em}
.view-head p{margin:2px 0 0; font-size:11px; color:var(--muted)}
.view-head .spacer{flex:1}
.view-scroll{flex:1; min-height:0; overflow:auto; padding:14px 20px 18px; display:flex;
  flex-direction:column; gap:12px}

/* ---------- bandeja de revision ---------- */
.rev{padding:12px 14px; display:grid; gap:10px}
.rev-top{display:flex; align-items:center; gap:9px; flex-wrap:wrap}
.rev-name{font-family:Archivo; font-weight:700; font-size:14px; letter-spacing:-.02em}
.rev-actions{margin-left:auto; display:flex; gap:8px; flex-wrap:wrap}
.rev-metrics{display:flex; gap:22px; flex-wrap:wrap}
.rev-m{display:grid; gap:1px}
.rev-m .lbl{font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600}
.rev-m .v{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; font-size:13px;
  color:var(--ink); font-weight:600}
.rev-m .v small{font-family:"IBM Plex Sans"; font-size:10.5px; font-weight:400; color:var(--muted)}

/* ---------- consolidado ---------- */
.cons-kpis{display:grid; grid-template-columns:repeat(auto-fit,minmax(165px,1fr))}
.cons-kpis .kpi{border-right:1px solid var(--line)}
.cons-kpis .kpi:first-child{padding-left:18px}
.cons-kpis .kpi:last-child{border-right:none}
.cons-cols{display:grid; grid-template-columns:repeat(auto-fit,minmax(290px,1fr)); gap:12px}
.card-pad{padding:12px 15px 14px}
.card-pad h3{font-size:12.5px; font-weight:600; margin-bottom:9px}
#consChart{width:100%; height:104px; display:block; overflow:visible}
table.simple{width:100%; border-collapse:collapse; font-size:12px}
table.simple th{text-align:left; font-size:9.5px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); font-weight:600; padding:5px 8px; border-bottom:1px solid var(--line-2); white-space:nowrap}
table.simple td{padding:7px 8px; border-bottom:1px solid var(--grid-line)}
table.simple tr:last-child td{border-bottom:none}
table.simple td.r, table.simple th.r{text-align:right}
.statuslist{display:flex; flex-wrap:wrap; gap:6px}
.statuslist .pill b{color:var(--ink-2); font-family:"IBM Plex Mono",monospace}

/* ---------- estados de carga y vacio ---------- */
.skel{background:linear-gradient(90deg,var(--surface-2) 25%,var(--surface-3) 50%,var(--surface-2) 75%);
  background-size:280% 100%; animation:skmove 1.15s linear infinite; border-radius:6px}
@keyframes skmove{0%{background-position:200% 0} 100%{background-position:-80% 0}}
.skel-cli{display:block; height:52px; margin:3px 6px}
.skel-cell{display:block; height:14px; width:100%; margin:0 auto}
.statebox{margin:auto; padding:38px 22px; max-width:440px; text-align:center; color:var(--muted);
  font-size:12.5px; line-height:1.6; display:grid; gap:11px; justify-items:center}
.statebox h3{font-size:15px; font-weight:700; color:var(--ink); letter-spacing:-.02em}
.statebox .ico{font-size:24px; color:var(--muted-2)}
.railstate{padding:26px 16px; text-align:center; color:var(--muted); font-size:11.5px; line-height:1.55}
.spin{width:14px; height:14px; border-radius:50%; border:2px solid var(--line-2);
  border-top-color:var(--accent); animation:spinr .7s linear infinite; flex:none}
@keyframes spinr{to{transform:rotate(360deg)}}

/* ---------- selector de SKU del catalogo ---------- */
.cat-list{max-height:246px; overflow:auto; border:1px solid var(--line); border-radius:9px;
  display:flex; flex-direction:column; background:var(--surface-2)}
.cat-it{display:flex; align-items:center; gap:10px; padding:8px 10px; width:100%; text-align:left;
  border-bottom:1px solid var(--line)}
.cat-it:last-child{border-bottom:none}
.cat-it:hover{background:var(--surface-3)}
.cat-it[aria-pressed="true"]{background:var(--accent-soft)}
.cat-it .nm{font-size:12px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.cat-it .mt{font-size:10.5px; color:var(--muted)}
.cat-it .pr{margin-left:auto; font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--ink-2); flex:none}
.cat-empty{padding:22px 12px; text-align:center; font-size:11.5px; color:var(--muted)}

@media (max-width:1080px){
  .topbar{flex-wrap:wrap; height:auto; padding:8px 12px; gap:10px}
  .brand{border-right:none}
  .brandmark{height:23px}
  /* La banda pasa a dos lineas: con height:100% los bloques de marca y usuario se
     miden contra la altura de una sola linea y el usuario se dibuja fuera del azul,
     con texto claro sobre el fondo claro de la pagina. */
  .brand, .user{height:auto}
  .deadline{display:none}
  .view-head{padding:11px 14px}
  .view-scroll{padding:12px 14px 16px}
  .rev-actions{margin-left:0; width:100%}
}

/* ---------- administracion de ciclos ---------- */
.selfilter{height:29px; border:1px solid var(--line); border-radius:8px; background:var(--surface-2);
  color:var(--ink); font:inherit; font-size:12px; padding:0 8px; outline:none}
.selfilter:focus{border-color:var(--accent); box-shadow:0 0 0 2px var(--accent-soft)}
.btn.danger{border-color:var(--neg); color:var(--neg)}
.btn.danger:hover{background:var(--neg); border-color:var(--neg); color:var(--surface)}
.btn.primary.danger{background:var(--neg); border-color:var(--neg); color:var(--surface)}
.btn.primary.danger:hover{background:var(--neg); filter:brightness(1.08)}
.note.danger{border-color:var(--neg); color:var(--neg); background:transparent}
.note.danger b{color:var(--neg)}
.field input[type="date"]{height:34px; border:1px solid var(--line-2); border-radius:8px; background:var(--surface);
  color:var(--ink); font:inherit; font-size:12.5px; padding:0 9px; outline:none}
.field input[type="date"]:focus{border-color:var(--accent); box-shadow:0 0 0 2px var(--accent-soft)}
.formgrid{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px}
.formgrid .wide{grid-column:1/-1}
.cyc{padding:12px 14px; display:grid; gap:10px}
.cyc-top{display:flex; align-items:center; gap:9px; flex-wrap:wrap}
.cyc-year{font-family:Archivo; font-weight:700; font-size:21px; letter-spacing:-.03em; color:var(--ink)}
.cyc-name{font-size:13.5px; font-weight:600; letter-spacing:-.01em; color:var(--ink-2)}
.cyc-actions{margin-left:auto; display:flex; gap:8px; flex-wrap:wrap}
.cyc-meta{display:flex; gap:22px; flex-wrap:wrap}
.cyc-m{display:grid; gap:1px}
.cyc-m .lbl{font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600}
.cyc-m .v{font-size:12px; color:var(--ink-2); font-weight:500}
.cyc-m .v.late{color:var(--neg); font-weight:600}
.cyc-notes{margin:0; font-size:11.5px; color:var(--muted); line-height:1.5;
  border-top:1px solid var(--line); padding-top:8px}
.pill.cyc-draft{border-color:var(--line-2); color:var(--muted)}
.pill.cyc-closed{border-color:var(--line-2); color:var(--ink-2); background:var(--surface-3)}
.tag.late{background:transparent; border:1px solid var(--neg); color:var(--neg); font-weight:600}
.statebox .btn{margin-top:2px}

@media (max-width:1080px){
  .cyc-actions{margin-left:0; width:100%}
  .formgrid{grid-template-columns:minmax(0,1fr)}
}

/* ---------- ajustes finales: sangrias de la grilla y detalles ---------- */
.cellwrap.fam-wrap{padding-left:24px}
.cellwrap.sku-wrap{padding-left:44px}
.login-brand b{font-family:Archivo; font-weight:700; font-size:15px; letter-spacing:-.025em}
.rev-top .st{width:8px; height:8px; border-radius:50%; flex:none}
.statebox .spin{margin:0 auto}
.statuslist .pill{gap:6px}

/* ---------- rubro de referencia: presupuesto del anio anterior (solo lectura) ---------- */
/* Misma jerarquia que los rubros presupuestables, con un tratamiento apagado:
   es contexto para comparar, no la captura del ciclo. */
table.g tr.rubro.refcat td{background:var(--surface-2)}
table.g tr.fam.refcat td, table.g tr.sku.refcat td{background:var(--surface)}
tr.rubro.refcat .rubro-name, tr.rubro.refcat .rubro-sub{opacity:.72}
tr.rubro.refcat .rubro-n{color:var(--ink)}
tr.fam.refcat .fam-name, tr.sku.refcat .sku-name{opacity:.68}
table.g tr.refcat td.tot{font-weight:400; color:var(--muted)}
/* Sin resalte de hover: la fila no se edita, no hay nada que invitar a tocar. */
table.g tr.sku.refcat:hover td, table.g tr.sku.refcat:hover td.c0{background:var(--surface)}
/* Placeholder del chevron ausente, para que el nombre no se corra a la izquierda. */
.twist-off{width:18px; height:18px; flex:none}
.tag.ref{background:transparent; border:1px solid var(--line-3); color:var(--muted); font-weight:600;
  font-size:9.5px; letter-spacing:.06em; text-transform:uppercase; padding:1px 6px}

/* ---------- analisis de la cuenta (debajo de los KPIs) ---------- */
/* Contexto para decidir, no captura: mismo lenguaje visual que los KPIs pero un
   escalon mas abajo en peso tipografico, para no competir con el presupuesto del
   ciclo. Sangra a los bordes de la cabecera con margenes negativos. */
.acct-an{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.6fr) minmax(0,1fr);
  margin:11px -20px 0; padding:11px 20px 12px; background:var(--surface-2); border-top:1px solid var(--line)}
.an-card{padding:0 18px; min-width:0}
.an-card:first-child{padding-left:0}
.an-card:last-child{padding-right:0}
.an-card + .an-card{border-left:1px solid var(--line)}
.an-lbl{font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600}
.an-val{font-family:Archivo; font-weight:700; font-size:15px; letter-spacing:-.03em; margin-top:3px;
  display:flex; align-items:baseline; gap:6px; flex-wrap:wrap; font-variant-numeric:tabular-nums}
.an-val small{font-family:"IBM Plex Sans"; font-size:10.5px; font-weight:500; color:var(--muted); letter-spacing:0}
.an-sub{font-size:10.5px; color:var(--muted); margin-top:3px; line-height:1.45}
.an-sub b{color:var(--ink-2); font-weight:600}
.an-note{font-size:10.5px; color:var(--muted-2); margin-top:3px; line-height:1.4}
.an-empty{grid-column:1/-1; margin:0; font-size:11px; color:var(--muted-2)}

.an-rows{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:4px 18px; margin-top:3px}
.an-row{min-width:0}
.an-row-h{display:flex; align-items:baseline; justify-content:space-between; gap:8px}
.an-row-h > span{font-size:10.5px; color:var(--muted); font-weight:500}
.an-pct{font-size:14px; letter-spacing:-.02em}

/* Los tres conjuntos de SKUs en una sola lectura: acertado / presupuestado sin venta /
   vendido fuera del plan. El ancho de cada tramo es proporcion, viene por flex. */
.an-meter{display:flex; gap:2px; height:7px; margin-top:5px}
.an-meter i{display:block; border-radius:2px; min-width:2px}
.an-meter i.ok{background:var(--pos)}
.an-meter i.miss{background:var(--neg)}
.an-meter i.extra{background:var(--warn)}
.an-legend{display:flex; flex-wrap:wrap; gap:2px 10px; font-size:10px; color:var(--muted); margin-top:5px}
.an-legend span{display:inline-flex; align-items:center; gap:4px; white-space:nowrap}
.an-legend s{width:7px; height:7px; border-radius:2px; text-decoration:none; flex:none}
.an-legend s.ok{background:var(--pos)}
.an-legend s.miss{background:var(--neg)}
.an-legend s.extra{background:var(--warn)}
.an-legend b{color:var(--ink-2); font-weight:600}

.an-trend{font-family:Archivo; font-weight:700; font-size:15px; letter-spacing:-.03em}
.an-trend.up{color:var(--pos)}
.an-trend.dn{color:var(--neg)}
.an-trend.eq{color:var(--muted)}
/* Mini serie de venta anual: el mismo .sparkbox de la grilla, en tamano de cabecera. */
.sparkbox.tall{height:34px; gap:3px; margin-left:0; padding-right:0; margin-top:6px}
.sparkbox.tall i{width:9px; border-radius:2px 2px 1px 1px; background:var(--accent-line)}
/* Anio que el backend dejo fuera de la regresion: no puede leerse igual que uno
   que peso en el diagnostico. Se apaga a color neutro y el title dice el motivo.
   Un anio en cero conserva su barra minima: el hueco tambien es informacion. */
.sparkbox.tall i.off{background:var(--line-3); opacity:.6}

@media (max-width:1080px){
  .acct-an{grid-template-columns:minmax(0,1fr); gap:10px}
  .an-card{padding:0}
  .an-card + .an-card{border-left:none; border-top:1px solid var(--line); padding-top:10px}
}
@media (max-width:560px){
  .an-rows{grid-template-columns:minmax(0,1fr); gap:10px}
}

/* ---------- agregar SKU desde la fila del rubro ----------
   Las acciones de fila del mockup se revelan al pasar el mouse, pero "agregar
   SKU" es una accion primaria: escondida detras del hover no la encuentra nadie.
   Se muestra siempre, atenuada, y toma color al acercarse. */
tr.rubro .rowact{opacity:.55; margin-left:10px}
tr.rubro:hover .rowact,
tr.rubro:focus-within .rowact{opacity:1}
tr.rubro .rowact .miniact{font-size:15px; line-height:1; font-weight:600;
  border:1px solid var(--line-2); background:var(--surface)}
tr.rubro .rowact .miniact:hover{background:var(--accent-soft); border-color:var(--accent-line);
  color:var(--accent)}


/* ---------- conmutador de moneda (USD / moneda local) ----------
   Segundo control segmentado de la toolbar, con el mismo lenguaje que Cantidades/Valor
   pero un escalon mas discreto: la unidad es la decision principal, la moneda es como
   se lee esa unidad. En Cantidades queda deshabilitado, nunca activo en falso. */
.seg.cur button{font-family:"IBM Plex Mono",monospace; font-size:11px; letter-spacing:.02em;
  min-width:44px; text-align:center}
.seg button:disabled{cursor:not-allowed}
.seg.off{opacity:.45}
.seg.off button{box-shadow:none}
.seg[hidden]{display:none}

/* ---------- orden del portafolio ----------
   Cuarto control segmentado de la app: reusa .seg tal cual, con el mismo estado
   activo (fondo elevado + sombra) que ya usan Cantidades/Valor y USD/local, para
   que el comercial no tenga que aprender un segundo lenguaje de seleccion.
   Va full width del rail y con las etiquetas cortas: el titulo largo de cada
   opcion vive en el title del boton. Si el ancho no alcanza, el .seg baja de
   linea entero en vez de recortar una etiqueta. */
.railsort{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.railsort .lbl{flex:none; font-size:9.5px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--muted); font-weight:600}
.seg.sort{flex:1 1 190px; min-width:0}
.seg.sort button{flex:1 1 auto; padding:4px 7px; font-size:11px; text-align:center; white-space:nowrap}

/* ---------- cliente clave ----------
   La cuenta esta dentro del 80% de la venta de su cartera (Pareto por cartera que
   resuelve el backend). Es donde el comercial tiene que poner el esfuerzo, asi que
   la marca se lee recorriendo la lista sin leer los nombres.

   No depende del color en ningun momento: la senial primaria es la presencia de la
   marca —solo las cuentas clave la llevan—, la silueta de la estrella es unica en el
   rail, y el numero del puesto agrega la magnitud. El verde es el cuarto canal,
   nunca el unico.

   Anclada al borde derecho de la linea del nombre: forma una columna vertical
   constante al barrer la lista, y el nombre se elide antes que la marca se mueva.
   Alto 15px contra los 18px de la linea del nombre: no empuja la fila. */
.cli .key{flex:none; margin-left:auto; display:inline-flex; align-items:center; gap:3px;
  height:15px; padding:0 5px; border-radius:4px; line-height:1; cursor:help;
  background:var(--accent-soft); border:1px solid var(--accent-line); color:var(--accent)}
.cli .key .gl{font-size:9px}
.cli .key b{font-size:10px; font-weight:700; letter-spacing:-.01em}
/* La fila seleccionada ya pinta el fondo con --accent-soft: la marca se invertiria
   contra el si no cambiara de fondo. */
.cli[aria-current="true"] .key{background:var(--surface); border-color:var(--accent)}

@media (max-width:1080px){
  /* El rail pasa a horizontal y su cabecera tiene que dejar de apilar controles: en
     fila, el buscador y el orden comparten renglon y la cabecera no crece respecto
     de antes de agregar el selector. Los chips se quedan con su propia linea porque
     ya vienen envolviendo. */
  .rail-head{flex-flow:row wrap; align-items:center; column-gap:12px}
  .rail-head .t{flex:1 1 100%}
  .rail-head .search{flex:1 1 220px}
  .railsort{flex:0 1 auto}
  .seg.sort{flex:0 0 auto}
  .rail-head .chips{flex:1 1 100%}
  /* Con el rail acostado, 210px fijos dejaban el listado en cero apenas la cabecera
     envolvia. Se le da alto proporcional al viewport, con tope, para que siempre
     queden filas visibles bajo la cabecera. */
  .rail{max-height:min(38vh, 300px)}
}

/* Aviso de total incompleto: hay lineas que no se pueden valorizar en la moneda local
   y quedaron fuera de los subtotales. Va al lado del conmutador que lo provoca. */
.curwarn{display:flex; align-items:center; gap:5px; font-size:10.5px; line-height:1.35;
  color:var(--warn); background:var(--surface); border:1px solid var(--line);
  border-radius:7px; padding:3px 9px; max-width:420px}
.curwarn[hidden]{display:none}
.curwarn b{font-family:"IBM Plex Mono",monospace; font-weight:700; flex:none}

/* Celda que no se puede valorizar en la moneda activa. No es un cero: es un dato que
   no existe, asi que no usa el guion, que en esta grilla significa cero. */
.noprice{font-family:"IBM Plex Sans",system-ui,sans-serif; font-size:10px; font-weight:600;
  color:var(--muted-2); border-bottom:1px dotted var(--line-3); cursor:help; letter-spacing:.02em}
.tag.nolocal{background:transparent; border:1px solid var(--warn); color:var(--warn); font-weight:600;
  font-size:9.5px; letter-spacing:.04em; padding:1px 6px; flex:none; white-space:nowrap}

/* Total al que le faltan lineas: el asterisco lo dice y el title cuenta cuantas. */
table.g td.tot.parcial{color:var(--warn)}
.pmark{font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:700; color:var(--warn);
  cursor:help; margin-left:1px}

/* Los KPIs, el analisis y la mezcla los calcula el servidor y vienen siempre en USD.
   Con la grilla en moneda local hay que decirlo donde se lee el numero, no en una nota. */
.curtag{font-family:"IBM Plex Mono",monospace; font-style:normal; font-size:8.5px; font-weight:700;
  letter-spacing:.06em; color:var(--accent); background:var(--accent-soft);
  border:1px solid var(--accent-line); border-radius:4px; padding:0 4px; margin-left:5px;
  vertical-align:1px; cursor:help}

/* ---------- catalogo: primera carga ----------
   El barrido del catalogo y de la lista de precios puede tardar decenas de segundos la
   primera vez. Sin un estado explicito el modal parece colgado. */
.cat-loading{display:flex; align-items:flex-start; gap:10px; padding:22px 14px;
  font-size:11.5px; color:var(--muted); line-height:1.5}
.cat-loading .spin{margin-top:2px}
.cat-loading small{display:block; font-size:10.5px; color:var(--muted-2); margin-top:3px}

@media (max-width:900px){
  .curwarn{max-width:none; order:99; width:100%}
}

/* ---------- bandeja de revision: agrupacion de la tarjeta ----------
   La tarjeta paso de siete metricas a siete mas tres bloques de contexto. Sin agrupar
   se vuelve una lista ilegible, asi que se parte en dos secciones con encabezado: lo
   que se esta aprobando arriba, el contexto del cliente abajo, separados por una linea
   y con el contexto un escalon mas atenuado. */
.rev-block{display:grid; gap:7px; min-width:0}
.rev-b-t{font-size:9.5px; letter-spacing:.11em; text-transform:uppercase; color:var(--muted-2);
  font-weight:600; font-family:"IBM Plex Sans",system-ui,sans-serif}
.rev-block.ctx{border-top:1px solid var(--line); padding-top:9px}

/* Metrica que llega en cero por falta de dato y no por valor (hoy: Meta y Cumplimiento,
   que nunca se cargan por cuenta). Se muestra igual, pero no compite con lo que si tiene
   contenido: el motivo esta en el title. */
.rev-m.soft .lbl{color:var(--muted-2)}
.rev-m.soft .v{color:var(--muted-2); font-weight:500}
.rev-m.soft{cursor:help}

/* ---------- contexto del cliente: los tres bloques del insight ---------- */
.rev-ctx{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px 18px}
.rev-c{min-width:0; padding-left:14px; border-left:1px solid var(--line)}
.rev-c:first-child{padding-left:0; border-left:none}
.rev-c-l{font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600}
.rev-c-v{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums;
  font-size:16px; font-weight:600; letter-spacing:-.02em; color:var(--ink); margin-top:2px; line-height:1.2}
.rev-c-s{font-size:10.5px; color:var(--muted); margin-top:3px; line-height:1.45}
.rev-c-s b{color:var(--ink-2); font-weight:600}
.rev-c-n{font-size:10.5px; color:var(--muted-2); margin-top:3px; line-height:1.4}

/* Saldo pendiente de cobranza: es la plata que el cliente debe hoy, el dato mas
   accionable del bloque. Va en su propia caja para que no se lea como un detalle del
   porcentaje, y solo se pinta en rojo cuando la cobranza cae bajo el umbral malo. */
.rev-c-hi{display:flex; align-items:baseline; gap:8px; margin-top:5px; padding:3px 8px;
  border:1px solid var(--line); border-radius:7px; background:var(--surface-2)}
.rev-c-hi .l{font-size:9px; letter-spacing:.08em; text-transform:uppercase; color:var(--muted);
  font-weight:600; white-space:nowrap}
.rev-c-hi b{margin-left:auto; font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums;
  font-size:13px; font-weight:600; color:var(--ink-2)}
.rev-c-hi.dn{border-color:var(--neg); background:transparent}
.rev-c-hi.dn .l, .rev-c-hi.dn b{color:var(--neg)}

/* Termino con explicacion al pasar el mouse, dentro de una linea de detalle. */
.why{font-style:normal; border-bottom:1px dotted var(--line-3); cursor:help}

/* ---------- modal de solo lectura: detalle del presupuesto ----------
   Mas ancho que un formulario porque muestra una jerarquia de tres niveles, y con el
   cuerpo scrolleando por dentro para que el encabezado y el boton de cerrar queden
   siempre a la vista. */
.modal.wide{width:min(760px,100%); display:flex; flex-direction:column; overflow:hidden}
.modal.wide .m-body{overflow:auto; min-height:0; gap:11px}

.det-state{display:flex; align-items:flex-start; gap:11px; padding:30px 12px; justify-content:center;
  text-align:left; font-size:12px; color:var(--muted); line-height:1.5}
.det-state .ico{font-size:18px; color:var(--muted-2); line-height:1.2}
.det-state b{color:var(--ink); font-weight:600; font-size:13px}
.det-state p{margin:2px 0 0}
.det-state.err b{color:var(--neg)}

.det-sum{gap:20px; padding-bottom:11px; border-bottom:1px solid var(--line)}
.rev-m.big .v{font-size:16px}

.det-list{display:grid; gap:6px}
.det-cat{border:1px solid var(--line); border-radius:9px; background:var(--surface-2); overflow:hidden}
.det-h{display:flex; align-items:center; gap:8px; width:100%; text-align:left; padding:8px 10px}
.det-h:hover{background:var(--surface-3)}
.det-n{width:17px; height:17px; border-radius:5px; color:#fff; font-size:9.5px; font-weight:700;
  display:grid; place-items:center; flex:none; font-family:"IBM Plex Mono",monospace}
/* margin-right:auto en el nombre y no margin-left:auto en la barra: el rubro de
   referencia y un rubro en cero no dibujan barra, y los importes tienen que quedar
   alineados a la derecha igual que los demas. */
.det-name{display:flex; align-items:center; gap:6px; min-width:0; font-size:12.5px; font-weight:600;
  color:var(--ink); flex-wrap:wrap; margin-right:auto}
.det-bar{width:80px; height:5px; border-radius:3px; background:var(--line);
  overflow:hidden; flex:none}
.det-bar i{display:block; height:100%; border-radius:3px}
.det-amt{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; font-size:12.5px;
  font-weight:600; color:var(--ink); flex:none; min-width:88px; text-align:right}
.det-pct{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--muted); flex:none;
  min-width:56px; text-align:right}
.det-nosum{font-family:"IBM Plex Sans",system-ui,sans-serif; font-style:normal; font-size:9.5px;
  letter-spacing:.04em; color:var(--muted-2); cursor:help}
/* El rubro de referencia se lee, no se aprueba: mismo tratamiento apagado que en la grilla. */
.det-cat.ref{background:var(--surface)}
.det-cat.ref .det-name, .det-cat.ref .det-amt{opacity:.72; font-weight:500}
/* Rubro sin lineas: sigue estando, pero no compite con los que tienen contenido. */
.det-cat.vacio .det-name, .det-cat.vacio .det-amt, .det-cat.vacio .det-pct{color:var(--muted-2); font-weight:500}
.det-cat.vacio .det-n{opacity:.5}

.det-body{border-top:1px solid var(--line); background:var(--surface); padding:2px 10px 8px}
.det-fam{padding-top:8px}
.det-f-h{display:flex; align-items:center; gap:7px; font-size:11.5px; color:var(--ink-2); font-weight:600}
.det-f-h .fam-ico{width:6px; height:6px; border-radius:2px; flex:none; display:block}
.det-f-n{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.det-f-h b{margin-left:auto; font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums;
  font-size:11.5px; flex:none}
table.det-sku{margin-top:3px; font-size:11.5px}
table.det-sku th{padding:3px 6px}
table.det-sku td{padding:5px 6px; color:var(--ink-2)}
table.det-sku em{font-style:normal; color:var(--muted)}
.det-empty{margin:0; padding:10px 2px 6px; font-size:11.5px; color:var(--muted)}

/* Chevron decorativo de un encabezado que ya es boton: el estado lo declara el
   contenedor, asi que la rotacion no puede colgar de aria-expanded. */
.twist[data-abierto="true"] svg{transform:rotate(90deg)}

@media (max-width:1080px){
  .rev-ctx{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
  .rev-c{padding-left:0; border-left:none}
}
@media (max-width:560px){
  .rev-ctx{grid-template-columns:minmax(0,1fr)}
  .rev-c + .rev-c{border-top:1px solid var(--line); padding-top:9px}
  .det-h{flex-wrap:wrap}
  .det-bar{display:none}
  .det-amt{min-width:0}
}
