/* ============================================================
   PREGO — Likefish Trading ERP
   Hoja de estilos global / Global stylesheet
   ============================================================ */

:root{
  /* Marca Likefish */
  --navy:#0D2E52;
  --navy-800:#123c69;
  --blue:#3B8FD4;

  /* Color interactivo de la casa. Antes esto era --blue, el mismo azul
     que usa "información" — y al pintar Likemeat de granate el elemento
     activo del menú seguía saliendo azul. Son dos cosas distintas:
     --accent cambia con la empresa, --info nunca, porque azul tiene que
     seguir significando "aviso" en las tres.
     The house interactive colour. This used to be --blue, the same blue
     "information" uses — so painting Likemeat maroon left the active menu
     item blue. They are two different things: --accent follows the
     company, --info never does, because blue has to keep meaning
     "notice" in all three houses. */
  --accent:#3B8FD4;
  --accent-tint:#EAF2F9;
  --accent-soft:rgba(59,143,212,.13);
  --accent-ring:rgba(59,143,212,.22);
  --blue-tint:#EAF2F9;
  --teal:#2DD4DF;
  --teal-deep:#0e8f99;
  --gold:#c8a96a;
  --gold-deep:#9a7830;
  --foam:#f3f1e9;
  --bone:#e9e5d8;
  --ink:#06151f;
  --mute:#5d7585;

  /* Estados */
  --ok:#1a9d6b;
  --ok-bg:#e4f5ee;
  --warn:#c9862a;
  --warn-bg:#fbf1e1;
  --danger:#c0392b;
  --danger-bg:#fbe9e7;
  --info:#3B8FD4;
  --info-bg:#EAF2F9;
  --neutral:#5d7585;
  --neutral-bg:#eef1f3;

  /* Superficies */
  --bg:#f6f8fa;
  --surface:#ffffff;
  --line:#e2e8ee;
  --line-soft:#eef2f6;

  --radius:10px;
  --radius-sm:6px;
  --shadow:0 1px 2px rgba(13,46,82,.06), 0 4px 16px rgba(13,46,82,.05);
  --shadow-lg:0 8px 40px rgba(13,46,82,.14);

  --sidebar-w:232px;
  --header-h:58px;
}

*{box-sizing:border-box;margin:0;padding:0}

body{
  font-family:'Archivo',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  background:var(--bg);
  color:var(--ink);
  font-size:14px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
}

/* ---------- Estructura / Layout ---------- */

.app{display:flex;min-height:100vh}

.sidebar{
  width:var(--sidebar-w);
  background:var(--navy);
  color:#fff;
  position:fixed;
  top:0;left:0;bottom:0;
  display:flex;flex-direction:column;
  z-index:40;
}

.brand{
  padding:18px 20px 16px;
  border-bottom:1px solid rgba(255,255,255,.1);
}
.brand-mark{
  font-family:'Fraunces',Georgia,serif;
  font-size:23px;font-weight:600;letter-spacing:.02em;
  display:flex;align-items:center;gap:8px;
}
.brand-mark .dot{width:7px;height:7px;border-radius:50%;background:var(--teal);display:inline-block}
/* El icono se alinea a la altura de las mayúsculas, no al centro de
   la línea: pegado al centro flotaba por encima de la palabra.
   The icon aligns to cap height, not to the line box: centred, it
   floated above the word. */
.brand-mark svg{margin-top:-1px}
/* ---------- Selector de empresa / Company picker ----------
   El logotipo de la empresa activa, bajo la línea de la marca, es
   el control para cambiar de empresa. El <select> va encima,
   transparente y a tamaño completo: se ve el logo, se comporta
   como un menú nativo.
   The active company's logotype, under the brand rule, is the
   control for switching company. The <select> sits on top,
   transparent and full-size: it looks like the logo and behaves
   like a native menu. */
.co-picker{
  position:relative;
  padding:14px 20px 15px;
  border-bottom:1px solid rgba(255,255,255,.1);
  display:flex;align-items:center;gap:8px;
}
/* Se blanquea el logotipo de color con el mismo filtro que usa el pie
   del sitio web, para no mantener un segundo archivo por empresa.
   The colour logotype is whitened with the same filter the website
   footer uses, so there is no second file per company to maintain. */
.co-picker img{height:26px;width:auto;display:block;filter:brightness(0) invert(1);opacity:.9;transition:opacity .15s}
.co-chev{margin-left:auto;color:rgba(255,255,255,.5);font-size:15px;line-height:1;transition:color .15s}
.co-picker select{
  position:absolute;inset:0;width:100%;height:100%;
  opacity:0;cursor:pointer;border:0;appearance:none;
}
.co-picker:hover img{opacity:1}
.co-picker:hover .co-chev{color:#fff}
/* El foco por teclado tiene que verse: el <select> es invisible. */
.co-picker:focus-within{background:rgba(255,255,255,.06)}
.co-picker.fixed{cursor:default}
.co-picker.fixed img{opacity:.9}

/* ---------- Bloques plegables / collapsible blocks ----------
   La cabecera entera es el tirador. El chevrón gira; nada salta de
   sitio al plegar. / The whole header is the handle. The chevron
   turns; nothing jumps when it folds. */
/* SE TIENE QUE VER QUE SE PUEDE ABRIR.
   La cabecera plegada se veía igual que una cabecera cualquiera: el
   único indicio era un chevrón gris pálido a la derecha, y con la
   sección cerrada no había nada debajo que sugiriera que faltaba
   algo. Se pedía «¿dónde están los productos?» estando el bloque
   ahí mismo, cerrado. Ahora la cabecera plegable va sombreada y el
   chevrón se ve; abierta se aclara, porque entonces ya no hace
   falta insistir.
   IT HAS TO LOOK OPENABLE. A folded header looked like any other
   header: the only cue was a pale grey chevron on the right, and
   with the section closed there was nothing below to suggest
   anything was missing. */
.blk>summary{
  list-style:none;cursor:pointer;user-select:none;
  background:var(--bg);transition:background .12s;
}
.blk[open]>summary{background:var(--surface)}
.blk>summary::-webkit-details-marker{display:none}
.blk>summary:hover{background:var(--accent-tint)}
.blk>summary:hover h3{color:var(--accent)}
.blk>summary:hover .blk-chev{color:var(--accent)}
.blk:not([open])>summary .blk-chev{color:var(--accent);opacity:.9}
.blk-chev{
  color:var(--mute);font-size:15px;line-height:1;flex:none;
  transition:transform .15s, color .15s;transform:rotate(-90deg);
}
.blk[open]>summary .blk-chev{transform:rotate(0)}
/* Plegado: la cabecera deja de llevar línea inferior, si no queda
   flotando un borde suelto. / Folded: the header drops its bottom
   rule, otherwise a stray border is left hanging. */
.blk:not([open])>summary{border-bottom:0}
.blk.internal>summary{display:flex;align-items:center;gap:9px}

/* ---------- Menú «⋯» / overflow menu ----------
   <details> nativo: sin estado en JavaScript que restaurar en cada
   repintado. / Native <details>: no JavaScript state to restore on
   every repaint. */
.more{position:relative;display:inline-block}
.more>summary{
  list-style:none;cursor:pointer;user-select:none;
  border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--surface);color:var(--mute);
  padding:4px 11px;font-size:15px;line-height:1.1;letter-spacing:.06em;
}
.more>summary::-webkit-details-marker{display:none}
.more>summary:hover{border-color:var(--accent);color:var(--accent)}
.more[open]>summary{border-color:var(--accent);color:var(--accent)}
.more-menu{
  position:absolute;right:0;top:calc(100% + 5px);z-index:50;
  min-width:220px;padding:5px;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow-lg);
}
.more-menu button{
  display:block;width:100%;text-align:left;
  background:0;border:0;cursor:pointer;font:inherit;font-size:12.5px;
  padding:7px 10px;border-radius:var(--radius-sm);color:var(--ink);
}
.more-menu button:hover{background:var(--accent-tint);color:var(--accent)}
.more-menu button:disabled{color:var(--mute);opacity:.5;cursor:default}
.more-menu button:disabled:hover{background:0}

/* ---------- Explicación plegada / folded explanation ---------- */
.why{margin:10px 0 0}
.why>summary{
  list-style:none;cursor:pointer;font-size:11.5px;color:var(--mute);
  display:inline-flex;align-items:center;gap:5px;
}
.why>summary::-webkit-details-marker{display:none}
.why>summary::before{content:'?';display:inline-grid;place-items:center;
  width:14px;height:14px;border-radius:50%;border:1px solid var(--line);
  font-size:9px;font-weight:600}
.why>summary:hover{color:var(--accent)}
.why[open]>summary{color:var(--accent)}
.why>div{
  font-size:12px;color:var(--mute);line-height:1.6;
  padding:9px 12px;margin-top:7px;
  background:var(--bg);border-radius:var(--radius-sm);
  border-left:2px solid var(--line);
}

.nav{flex:1;padding:12px 10px;overflow-y:auto}
.nav-group{margin-bottom:16px}
.nav-label{
  font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;
  color:rgba(255,255,255,.4);padding:0 10px;margin-bottom:5px;
}
.nav a{
  display:flex;align-items:center;gap:9px;
  padding:7px 10px;border-radius:var(--radius-sm);
  color:rgba(255,255,255,.78);text-decoration:none;
  font-size:13px;margin-bottom:1px;transition:.13s;
}
.nav a:hover{background:rgba(255,255,255,.08);color:#fff}
.nav a.active{background:var(--accent);color:#fff;font-weight:500}
.nav a .ico{width:16px;text-align:center;opacity:.9;font-size:14px}
.nav a .badge{
  margin-left:auto;background:rgba(255,255,255,.16);
  font-size:10px;padding:1px 6px;border-radius:9px;font-weight:600;
}
.nav a.active .badge{background:rgba(255,255,255,.26)}

.sidebar-foot{
  padding:12px 14px;border-top:1px solid rgba(255,255,255,.1);
  font-size:11px;color:rgba(255,255,255,.45);
}
.user-chip{display:flex;align-items:center;gap:9px;margin-bottom:8px;position:relative}
/* Mismo recurso que el selector de empresa: el <select> nativo,
   invisible, encima de la ficha. / Same device as the company
   picker: the native <select>, invisible, over the chip. */
.user-pick{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;border:0;appearance:none}
.user-chip:hover{background:rgba(255,255,255,.06);border-radius:6px}
.avatar{
  width:29px;height:29px;border-radius:50%;
  background:var(--accent);display:grid;place-items:center;
  font-size:11.5px;font-weight:600;color:#fff;flex-shrink:0;
}
.user-chip .who{line-height:1.25;min-width:0}
.user-chip .who b{color:#fff;font-size:12.5px;font-weight:600;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.user-chip .who span{font-size:10.5px;color:rgba(255,255,255,.5)}

.main{flex:1;margin-left:var(--sidebar-w);display:flex;flex-direction:column;min-width:0}

.topbar{
  height:var(--header-h);background:var(--surface);
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:14px;
  padding:0 26px;position:sticky;top:0;z-index:30;
}
/* EL TÍTULO DE LA PANTALLA, EN MAYÚSCULA.
   Ya lo estaban las cabeceras de sección (h3), así que el título de
   arriba —que manda sobre todas ellas— quedaba escrito en minúscula
   y con menos peso que lo que tenía debajo: la jerarquía al revés.
   Mayúscula, negrita y algo de espaciado en los tres niveles, y el
   tamaño es lo único que los separa.
   THE SCREEN TITLE, IN CAPS. Section headings already were, so the
   title above them — which governs all of them — was set in lower
   case and lighter than what sat beneath it: the hierarchy upside
   down. Caps, bold and a little tracking at all three levels, with
   size as the only thing separating them. */
.topbar h1{
  font-size:17px;font-weight:700;
  text-transform:uppercase;letter-spacing:.045em;
}
.topbar .crumb{font-size:12px;color:var(--mute)}
.topbar .spacer{flex:1}

.search{
  display:flex;align-items:center;gap:7px;
  background:var(--bg);border:1px solid var(--line);
  border-radius:var(--radius-sm);padding:5px 10px;width:230px;
}
.search input{border:0;background:0;outline:0;font:inherit;font-size:12.5px;width:100%;color:var(--ink)}
.search .ico{color:var(--mute);font-size:12px}

/* ---------- Selector de empresa / Company switcher ---------- */

.co-switch{
  display:flex;align-items:center;gap:7px;
  border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:3px 9px 3px 10px;background:var(--surface);
  border-left:3px solid var(--co);
}
.co-switch .co-dot{
  width:7px;height:7px;border-radius:50%;background:var(--co);flex-shrink:0;
}
.co-switch select{
  border:0;background:0;outline:0;font:inherit;font-size:12.5px;
  font-weight:600;color:var(--co);cursor:pointer;padding:2px 0;
  max-width:210px;
}
.co-chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:5px 11px;border-radius:var(--radius-sm);
  background:color-mix(in srgb, var(--co) 10%, white);
  color:var(--co);font-size:12.5px;font-weight:600;
  border:1px solid color-mix(in srgb, var(--co) 25%, white);
}

/* ---------- Bloque interno confidencial / Internal-only ---------- */

.internal{
  border:1px solid #e0d4b8;
  border-left:3px solid var(--gold-deep);
  border-radius:var(--radius);
  background:repeating-linear-gradient(
    -45deg, #fdfaf3, #fdfaf3 9px, #faf5e9 9px, #faf5e9 18px);
  overflow:hidden;
}
.internal-head{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:9px 14px;background:rgba(255,255,255,.72);
  border-bottom:1px solid #ece0c9;
  font-size:12.5px;font-weight:600;color:var(--gold-deep);
}
.internal-lock{font-size:13px;opacity:.75}
.internal-flag{
  margin-left:auto;font-size:9.5px;letter-spacing:.07em;text-transform:uppercase;
  font-weight:700;color:#a08341;background:#f4ead4;
  padding:2px 7px;border-radius:3px;white-space:nowrap;
}
.internal-body{padding:14px}
.internal table thead th{background:rgba(255,255,255,.5)}
.internal table tbody td{border-bottom-color:#ece0c9}

.lang-toggle{display:flex;border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden}
.lang-toggle button{
  border:0;background:var(--surface);padding:5px 11px;
  font:inherit;font-size:11.5px;font-weight:600;cursor:pointer;color:var(--mute);
}
.lang-toggle button.on{background:var(--navy);color:#fff}

.view{padding:24px 26px 60px;max-width:1400px;width:100%}

/* ---------- Tipografía / Typography ---------- */

h2{
  font-size:15.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.05em;
}
/* El número de contrato o de cotización NO se toca: «LKF-C-0001» ya
   es mayúscula, y forzarla sobre un monoespaciado sólo le quita el
   espaciado que lo hace legible.
   Reference numbers are left alone: they are already caps, and
   forcing it on a monospaced number only costs it the tracking that
   makes it readable. */
h2.mono{ text-transform:none;letter-spacing:0 }

/* LAS CABECERAS DE SECCIÓN, EN MAYÚSCULA.
   «Ventas» en 13,5 px con peso 600 pesaba casi lo mismo que el texto
   de la tabla que tenía debajo, y en una pantalla con cuatro o cinco
   tarjetas no se veía dónde empezaba cada una: había que leer el
   contenido para saber qué se estaba mirando. En mayúscula, con algo
   de cuerpo y de espaciado, la cabecera se distingue de un vistazo
   sin necesidad de subir el tamaño hasta que grite.
   El espaciado extra es lo que hace legible una mayúscula sostenida:
   sin él las letras se apelmazan.
   SECTION HEADINGS, IN CAPS. "Ventas" at 13.5px/600 weighed about the
   same as the table text beneath it, and on a screen with four or
   five cards you could not see where each one began — you had to read
   the content to know what you were looking at. Caps with a little
   more body and tracking separate the heading at a glance without
   pushing the size up until it shouts. The extra tracking is what
   makes sustained caps readable; without it the letters clot. */
h3{
  font-size:14px;font-weight:700;
  text-transform:uppercase;letter-spacing:.055em;
}
.section-head{display:flex;align-items:center;gap:12px;margin-bottom:13px}
.section-head .spacer{flex:1}
.muted{color:var(--mute)}
.tiny{font-size:11.5px}
.eyebrow{
  font-size:10px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--mute);font-weight:600;
}
.num{font-variant-numeric:tabular-nums}

/* ---------- Tarjetas / Cards ---------- */

.card{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow);
}
.card-head{
  padding:13px 16px;border-bottom:1px solid var(--line-soft);
  display:flex;align-items:center;gap:10px;
}
.card-head .spacer{flex:1}
.card-body{padding:16px}
.card-body.tight{padding:0}

.grid{display:grid;gap:15px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.g5{grid-template-columns:repeat(5,1fr)}
@media(max-width:1150px){.g4,.g5{grid-template-columns:repeat(2,1fr)}.g3{grid-template-columns:1fr 1fr}}
@media(max-width:820px){.g2,.g3,.g4,.g5{grid-template-columns:1fr}}

/* KPI */
.kpi{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow)}
.kpi .lbl{font-size:11px;color:var(--mute);letter-spacing:.03em;margin-bottom:5px}
.kpi .val{font-size:25px;font-weight:600;letter-spacing:-.025em;line-height:1.1;font-variant-numeric:tabular-nums}
.kpi .val small{font-size:13px;font-weight:500;color:var(--mute);margin-left:2px}
.kpi .foot{font-size:11.5px;color:var(--mute);margin-top:5px;display:flex;align-items:center;gap:5px}
.kpi.accent-teal{border-top:3px solid var(--teal)}
.kpi.accent-blue{border-top:3px solid var(--accent)}
.kpi.accent-gold{border-top:3px solid var(--gold)}
.kpi.accent-navy{border-top:3px solid var(--navy)}
.delta-up{color:var(--ok);font-weight:600}
.delta-dn{color:var(--danger);font-weight:600}

/* Tira de estados del Panel: una fila por lado, una casilla por etapa.
   Panel status strip: one row per side, one box per stage. */
.etapas{padding:6px 14px}
.et-row{display:flex;align-items:center;gap:12px;padding:8px 0}
.et-row+.et-row{border-top:1px solid var(--line-soft)}
.et-side{width:78px;flex:none;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--mute)}
.et-cells{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px;flex:1;min-width:0}
.et-c{display:flex;flex-direction:column;gap:1px;padding:7px 9px;border:1px solid var(--line);border-radius:var(--radius-sm);min-width:0}
.et-c.click{cursor:pointer}
.et-c.click:hover{border-color:var(--accent)}
.et-n{font-size:19px;font-weight:600;line-height:1.1;font-variant-numeric:tabular-nums}
.et-l{font-size:11px;color:var(--mute);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.et-v{font-size:11px;color:var(--mute);font-variant-numeric:tabular-nums}
.et-c.zero .et-n{color:var(--mute);font-weight:400}
.et-c.due{border-color:var(--danger);background:var(--danger-bg)}
.et-c.due .et-n,.et-c.due .et-l{color:var(--danger)}
@media(max-width:820px){
  .et-row{flex-direction:column;align-items:stretch;gap:6px}
  .et-cells{grid-template-columns:repeat(auto-fill,minmax(96px,1fr))}
}

/* ---------- Tablas / Tables ---------- */

table{width:100%;border-collapse:collapse}
thead th{
  text-align:left;font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--mute);font-weight:600;padding:9px 14px;
  border-bottom:1px solid var(--line);background:#fbfcfd;white-space:nowrap;
}
tbody td{padding:10px 14px;border-bottom:1px solid var(--line-soft);font-size:13px;vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr.clickable{cursor:pointer;transition:background .1s}
tbody tr.clickable:hover{background:var(--accent-tint)}
td.r,th.r{text-align:right;font-variant-numeric:tabular-nums}
td.c,th.c{text-align:center}
.tbl-wrap{overflow-x:auto}
.cell-strong{font-weight:600}
.cell-sub{font-size:11.5px;color:var(--mute);display:block;margin-top:1px}
.mono{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12px;letter-spacing:-.02em}

/* ---------- Píldoras / Pills & badges ---------- */

.pill{
  display:inline-flex;align-items:center;gap:5px;
  padding:2.5px 9px;border-radius:20px;
  font-size:11px;font-weight:600;letter-spacing:.01em;white-space:nowrap;
}
.pill::before{content:'';width:5px;height:5px;border-radius:50%;background:currentColor;flex-shrink:0}
.pill.no-dot::before{display:none}
.p-draft{background:var(--neutral-bg);color:var(--neutral)}
.p-sent{background:var(--info-bg);color:#1c6ca8}
.p-nego{background:var(--warn-bg);color:var(--warn)}
.p-accept{background:var(--ok-bg);color:var(--ok)}
.p-contract{background:#ece5f7;color:#6b46a8}
.p-shipped{background:#e0f5f7;color:var(--teal-deep)}
.p-closed{background:var(--neutral-bg);color:var(--neutral)}
.p-reject{background:var(--danger-bg);color:var(--danger)}
.p-expired{background:var(--danger-bg);color:var(--danger)}

.tag{
  display:inline-block;padding:2px 7px;border-radius:4px;
  font-size:10.5px;font-weight:600;background:var(--bone);color:var(--gold-deep);
  letter-spacing:.02em;
}
.tag.blue{background:var(--blue-tint);color:#1c6ca8}
.tag.teal{background:#e0f5f7;color:var(--teal-deep)}
.tag.grey{background:var(--neutral-bg);color:var(--mute)}

/* ---------- Botones / Buttons ---------- */

/* LOS BOTONES, MÁS GRANDES. Con 7px de alto útil y peso 500 se leían
   como enlaces: la acción principal de una pantalla —«+ Nueva
   cotización», «Aprobar»— pesaba lo mismo que el texto de al lado. Un
   botón tiene que verse pulsable desde el otro extremo de una sala,
   que es donde suele estar quien mira una demo.
   `.btn-sm` no cambia: las acciones de fila —×, «Quitar»— deben
   seguir siendo discretas o compiten con lo que hay en la fila.
   BIGGER BUTTONS. At 7px of padding and weight 500 they read as
   links: a screen's main action carried the same weight as the text
   beside it. A button has to look pressable from across a room, which
   is where the person watching a demo usually is. `.btn-sm` is
   unchanged: row actions must stay quiet or they compete with the row. */
.btn{
  display:inline-flex;align-items:center;gap:7px;
  padding:9px 18px;border-radius:var(--radius-sm);
  border:1px solid var(--line);background:var(--surface);color:var(--ink);
  font:inherit;font-size:13.5px;font-weight:600;cursor:pointer;
  text-decoration:none;transition:.13s;white-space:nowrap;
}
.btn:hover{background:var(--bg);border-color:#cfd9e2}
/* La principal es la que se busca: un pelo más de cuerpo y una
   sombra que la despega del fondo.
   The primary is the one being looked for: a touch more body and a
   shadow that lifts it off the page. */
.btn-primary,.btn-accent{ padding:9px 20px;font-weight:700;box-shadow:0 1px 2px rgba(13,46,82,.12) }
.btn-primary{background:var(--navy);border-color:var(--navy);color:#fff}
.btn-primary:hover{background:var(--navy-800);border-color:var(--navy-800)}
.btn-accent{background:var(--accent);border-color:var(--accent);color:#fff}
.btn-accent:hover{background:#2f7cbd;border-color:#2f7cbd}
.btn-ghost{background:0;border-color:transparent;color:var(--accent)}
.btn-ghost:hover{background:var(--accent-tint)}
.btn-sm{padding:4px 9px;font-size:11.5px;font-weight:500}
.btn-sm.btn-primary,.btn-sm.btn-accent{ padding:4px 11px;font-weight:600;box-shadow:none }
.btn-danger{color:var(--danger);border-color:#f0cfcb}
.btn-danger:hover{background:var(--danger-bg)}
.btn:disabled{opacity:.45;cursor:not-allowed}

.btn-row{display:flex;gap:8px;flex-wrap:wrap}

/* ---------- Formularios / Forms ---------- */

.field{margin-bottom:13px}
.field label{display:block;font-size:11.5px;font-weight:600;color:var(--mute);margin-bottom:4px;letter-spacing:.02em}
.field input,.field select,.field textarea{
  width:100%;padding:7px 10px;border:1px solid var(--line);
  border-radius:var(--radius-sm);font:inherit;font-size:13px;
  background:var(--surface);color:var(--ink);outline:0;transition:.13s;
}
/* Una casilla y un desplegable del mismo formulario miden lo mismo.
   Con el mismo relleno, Chrome dibujaba el desplegable 4 px más bajo
   y las filas quedaban escalonadas. / An input and a select in the
   same form are the same height; Chrome drew the select 4px shorter. */
.field input:not([type=checkbox]):not([type=radio]),.field select{height:36px}
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);
}
.field textarea{resize:vertical;min-height:64px}

/* UN CAMPO DENTRO DE UNA TABLA SIGUE SIENDO UN CAMPO.
   El estilo de los inputs colgaba de `.field`, así que una casilla
   puesta directamente en una celda —las presentaciones del alta de
   producto, por ejemplo— salía con el borde gris del navegador y
   media anchura, como si fuera de otra aplicación.
   A FIELD INSIDE A TABLE IS STILL A FIELD. Input styling hung off
   `.field`, so a box placed straight into a cell came out with the
   browser's own grey border at half width, as if it belonged to a
   different application. */
td>input,td>select,td>textarea{
  width:100%;padding:6px 9px;border:1px solid var(--line);
  border-radius:var(--radius-sm);font:inherit;font-size:12.5px;
  background:var(--surface);color:var(--ink);outline:0;transition:.13s;
}
td>input:focus,td>select:focus,td>textarea:focus{
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);
}
.field .hint{font-size:11px;color:var(--mute);margin-top:3px}
.field-row{display:grid;gap:13px}
.fr2{grid-template-columns:1fr 1fr}
.fr3{grid-template-columns:repeat(3,1fr)}
.fr4{grid-template-columns:repeat(4,1fr)}
@media(max-width:820px){.fr2,.fr3,.fr4{grid-template-columns:1fr}}

/* ---------- Línea de tiempo / Timeline ---------- */

.timeline{position:relative;padding-left:22px}
.timeline::before{content:'';position:absolute;left:6px;top:5px;bottom:5px;width:2px;background:var(--line)}
.tl-item{position:relative;padding-bottom:16px}
.tl-item:last-child{padding-bottom:0}
.tl-item::before{
  content:'';position:absolute;left:-19px;top:4px;
  width:9px;height:9px;border-radius:50%;
  background:var(--surface);border:2px solid var(--line);
}
.tl-item.done::before{background:var(--ok);border-color:var(--ok)}
.tl-item.current::before{background:var(--accent);border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)}
.tl-item .tl-t{font-size:13px;font-weight:600}
.tl-item .tl-m{font-size:11.5px;color:var(--mute);margin-top:1px}

/* ---------- Pipeline ---------- */

.pipeline{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px}
.pipe-col{
  flex:1;min-width:135px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius);padding:11px 12px;
}
.pipe-col .pc-lbl{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--mute);font-weight:600}
.pipe-col .pc-val{font-size:19px;font-weight:600;margin-top:5px;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.pipe-col .pc-cnt{font-size:11.5px;color:var(--mute);margin-top:1px}
.pipe-col .pc-bar{height:3px;border-radius:2px;margin-top:9px;background:var(--line-soft);overflow:hidden}
.pipe-col .pc-bar i{display:block;height:100%;border-radius:2px}

/* ---------- Barra de progreso / Progress ---------- */

.prog{height:6px;background:var(--line-soft);border-radius:4px;overflow:hidden}
.prog i{display:block;height:100%;background:var(--accent);border-radius:4px;transition:width .3s}
.prog.ok i{background:var(--ok)}
.prog.warn i{background:var(--warn)}

/* ---------- Lista de verificación / Checklist ---------- */

.check-list{display:flex;flex-direction:column}
.check-item{
  display:flex;align-items:center;gap:10px;
  padding:9px 0;border-bottom:1px solid var(--line-soft);
}
.check-item:last-child{border-bottom:0}
.check-box{
  width:17px;height:17px;border-radius:4px;flex-shrink:0;
  border:1.5px solid var(--line);display:grid;place-items:center;
  font-size:10px;color:#fff;
}
.check-box.on{background:var(--ok);border-color:var(--ok)}
.check-box.req{border-color:var(--warn);border-style:dashed}
.check-item .ci-name{flex:1;font-size:12.5px}
.check-item .ci-name b{font-weight:500}
.check-item.pending .ci-name{color:var(--mute)}

/* ---------- Calendario / Calendar ---------- */

.cal{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.cal .dow{background:#fbfcfd;padding:7px 8px;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--mute);font-weight:600;text-align:center}
.cal .day{background:var(--surface);min-height:82px;padding:6px 7px;position:relative}
.cal .day.out{background:#fafbfc}
.cal .day .dnum{font-size:11.5px;color:var(--mute);font-variant-numeric:tabular-nums}
.cal .day.today .dnum{background:var(--navy);color:#fff;border-radius:50%;width:19px;height:19px;display:grid;place-items:center;font-weight:600}
.cal-ev{
  font-size:10.5px;padding:2px 5px;border-radius:3px;margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;
  border-left:2.5px solid;
}
.ev-out{background:var(--danger-bg);color:#96311f;border-color:var(--danger)}
.ev-out.prov{background:var(--ok-bg);color:#0f7a51;border-color:var(--ok)}
.ev-in{background:var(--info-bg);color:#1c6ca8;border-color:var(--blue)}
.ev-ship{background:#e0f5f7;color:var(--teal-deep);border-color:var(--teal)}
.ev-doc{background:var(--warn-bg);color:var(--warn);border-color:var(--gold)}

/* ---------- Pestañas / Tabs ---------- */

.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:16px}
.tabs button{
  border:0;background:0;font:inherit;font-size:12px;font-weight:600;
  text-transform:uppercase;letter-spacing:.05em;
  padding:8px 13px;cursor:pointer;color:var(--mute);
  border-bottom:2px solid transparent;margin-bottom:-1px;transition:.13s;
}
.tabs button:hover{color:var(--ink)}
.tabs button.on{color:var(--navy);border-bottom-color:var(--navy);font-weight:700}

/* ---------- Filtros / Filters ---------- */

.filters{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:14px}
.filters select,.filters input{
  padding:6px 10px;border:1px solid var(--line);border-radius:var(--radius-sm);
  font:inherit;font-size:12.5px;background:var(--surface);outline:0;color:var(--ink);
}
.chip{
  padding:4px 11px;border-radius:20px;border:1px solid var(--line);
  background:var(--surface);font-size:12px;cursor:pointer;transition:.13s;
  font-weight:500;color:var(--mute);
}
.chip:hover{border-color:var(--accent);color:var(--accent)}
.chip.on{background:var(--navy);border-color:var(--navy);color:#fff}

/* ---------- Detalle / Detail lists ---------- */

.dl{display:grid;grid-template-columns:auto 1fr;gap:7px 16px;font-size:12.5px;align-items:baseline}
.dl dt{color:var(--mute);font-size:11.5px;white-space:nowrap}
.dl dd{font-weight:500}

.split{display:grid;grid-template-columns:1fr 320px;gap:16px;align-items:start}
@media(max-width:1050px){.split{grid-template-columns:1fr}}
.split-wide{display:grid;grid-template-columns:1fr 380px;gap:16px;align-items:start}
@media(max-width:1150px){.split-wide{grid-template-columns:1fr}}

/* ---------- Avisos / Notices ---------- */

.notice{
  display:flex;gap:10px;padding:11px 13px;border-radius:var(--radius-sm);
  font-size:12.5px;border-left:3px solid;align-items:flex-start;
}
.notice .ni{font-size:14px;line-height:1.2}
.n-info{background:var(--info-bg);border-color:var(--blue);color:#14567f}
.n-warn{background:var(--warn-bg);border-color:var(--warn);color:#8a5c14}
.n-ok{background:var(--ok-bg);border-color:var(--ok);color:#0f6e4a}
.n-danger{background:var(--danger-bg);border-color:var(--danger);color:#96311f}
/* ESPERANDO A OTRO. No es un aviso ni un problema: es un hecho, y
   el que mira no puede hacer nada con él. En ámbar competía con los
   plazos de verdad y en azul se confundía con la información. Gris,
   como la etiqueta `t-wait` que dice lo mismo en las listas — un
   estado se pinta igual se cuente donde se cuente.
   WAITING ON SOMEBODY ELSE. Not a warning and not a problem: a fact
   the viewer can do nothing about. In amber it competed with real
   deadlines; in blue it read as information. Grey, matching the
   `t-wait` tag that says the same thing in lists — one state, one
   colour, wherever it is told. */
.n-wait{background:var(--neutral-bg);border-color:var(--neutral);color:var(--neutral)}

/* ---------- Margen (dato sensible) / Margin (role-gated) ---------- */

.margin-cell{position:relative}
.locked{
  filter:blur(4px);user-select:none;opacity:.65;
}
.margin-flag{font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--gold-deep);font-weight:700}

/* ---------- Modal ---------- */

.modal-bg{
  position:fixed;inset:0;background:rgba(6,21,31,.5);
  display:grid;place-items:center;z-index:100;padding:24px;
  backdrop-filter:blur(2px);
}
.modal{
  background:var(--surface);border-radius:12px;box-shadow:var(--shadow-lg);
  width:100%;max-width:560px;max-height:88vh;overflow-y:auto;
}
.modal-head{padding:16px 20px;border-bottom:1px solid var(--line);display:flex;align-items:center}
.modal-head .spacer{flex:1}
.modal-body{padding:20px}
.modal-foot{padding:14px 20px;border-top:1px solid var(--line);display:flex;gap:8px;justify-content:flex-end}
.x-btn{border:0;background:0;font-size:19px;cursor:pointer;color:var(--mute);line-height:1;padding:0 2px}
.x-btn:hover{color:var(--ink)}

/* ---------- Estado vacío / Empty state ---------- */

.empty{text-align:center;padding:44px 20px;color:var(--mute)}
.empty .e-ico{font-size:30px;opacity:.35;margin-bottom:10px}
.empty .e-t{font-size:14px;font-weight:600;color:var(--ink);margin-bottom:4px}

/* ---------- Banda de prototipo ---------- */

.proto-note{
  background:var(--foam);border:1px dashed var(--bone);
  border-radius:var(--radius-sm);padding:9px 13px;
  font-size:11.5px;color:var(--gold-deep);margin-bottom:16px;
  display:flex;gap:8px;align-items:center;
}

/* Utilidades */
.flex{display:flex;align-items:center;gap:9px}
.flex-col{display:flex;flex-direction:column;gap:9px}
.spacer{flex:1}
.mb0{margin-bottom:0}.mb8{margin-bottom:8px}.mb16{margin-bottom:16px}.mb24{margin-bottom:24px}
.mt8{margin-top:8px}.mt16{margin-top:16px}.mt24{margin-top:24px}
.nowrap{white-space:nowrap}
.w100{width:100%}

/* ---------- KPI navegable / clickable KPI ---------- */

.kpi.click{
  cursor:pointer;position:relative;
  transition:transform .15s, box-shadow .15s, border-color .15s;
}
.kpi.click:hover{
  transform:translateY(-2px);
  box-shadow:0 6px 22px rgba(13,46,82,.11);
  border-color:#cfd9e2;
}
.kpi.click::after{
  content:'→';position:absolute;top:11px;right:14px;
  font-size:13px;color:var(--mute);opacity:.3;transition:.15s;
}
.kpi.click:hover::after{opacity:.85;transform:translateX(2px)}
.kpi .go{
  font-size:11px;color:var(--accent);font-weight:600;
  margin-top:6px;display:block;
}

/* ---------- Aviso breve / Toast ---------- */

.toast{
  position:fixed;bottom:26px;left:50%;transform:translateX(-50%);
  background:var(--navy);color:#fff;
  padding:10px 18px;border-radius:22px;
  font-size:12.5px;font-weight:500;
  box-shadow:0 6px 26px rgba(13,46,82,.28);
  z-index:200;animation:toastIn .2s ease-out;
  max-width:min(520px,90vw);text-align:center;
}
@keyframes toastIn{from{opacity:0;transform:translate(-50%,8px)}to{opacity:1;transform:translate(-50%,0)}}

/* ---------- Estado vacío con siguiente paso / empty with next step ---------- */

.start{
  border:1px dashed var(--line);border-radius:var(--radius);
  background:var(--surface);padding:26px;text-align:center;
}
.start .s-ico{font-size:26px;opacity:.3;margin-bottom:10px}
.start .s-t{font-size:15px;font-weight:600;margin-bottom:5px}
.start .s-d{font-size:12.5px;color:var(--mute);max-width:440px;margin:0 auto 16px}
.start-steps{
  display:flex;gap:8px;justify-content:center;flex-wrap:wrap;
  margin-top:18px;padding-top:16px;border-top:1px solid var(--line-soft);
}
.start-step{
  display:flex;align-items:center;gap:7px;
  font-size:11.5px;color:var(--mute);
}
.start-step b{
  width:19px;height:19px;border-radius:50%;
  background:var(--bg);border:1px solid var(--line);
  display:grid;place-items:center;font-size:10px;color:var(--mute);
}
.start-step.on b{background:var(--navy);border-color:var(--navy);color:#fff}
.start-step.on{color:var(--navy);font-weight:600}

/* ---------- Aún no construido / Not built yet ----------
   Un botón que no hace nada es peor que uno que dice que no
   está listo. A button that does nothing is worse than one that
   says it is not ready. */
.btn.todo{
  opacity:.45;cursor:not-allowed;position:relative;
}
.btn.todo:hover{background:var(--surface);border-color:var(--line)}
.btn.todo::after{
  content:'·';margin-left:5px;color:var(--gold-deep);font-weight:700;
}

/* ---------- Tablero de posiciones / positions board ----------
   Dos columnas enfrentadas: lo que tenemos y lo que debemos. En
   pantalla estrecha se apilan — largo primero, que es lo que hay
   que colocar. / Two facing columns: what we hold and what we owe.
   On a narrow screen they stack, long first — that is what needs
   placing. */
.pos-board{display:grid;grid-template-columns:1fr 1fr;gap:22px;align-items:start}
@media (max-width:1100px){ .pos-board{grid-template-columns:1fr} }

/* Cada lado es un panel cerrado, no una lista suelta. Con las dos
   listas abiertas sobre el mismo fondo, a media pantalla ya no se
   sabía en cuál se estaba: las tarjetas son iguales y el título había
   quedado arriba, fuera de vista.

   LA CABECERA NO ES PEGAJOSA, Y HAY MOTIVO.
   Lo fue durante un rato y rompió la pantalla: `position:sticky`
   dentro de un padre con `overflow:hidden` no se queda quieta —el
   navegador la baja hasta su `top`— así que la cabecera se despegaba,
   dejaba un hueco blanco encima y tapaba el primer bloque de la
   lista. Parecía que Mariscos no cargaba; estaba debajo. Se quitó lo
   pegajoso, que era un lujo, y no lo que hace legible el panel, que
   es el marco.

   Each side is a closed panel, not a loose list. With both lists on
   the same ground, halfway down you no longer knew which one you were
   in.

   THE HEADER IS NOT STICKY, AND THERE IS A REASON. It was for a
   while and it broke the screen: `position:sticky` inside a parent
   with `overflow:hidden` does not hold still — the browser drops it
   to its `top` — so the header detached, left a white gap above it
   and covered the list's first block. It looked as though Seafood was
   not loading; it was underneath. The stickiness went, being a
   luxury, rather than the frame, which is what makes the panel
   readable. */
.pos-col{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--radius);
  overflow:hidden;
}
/* La franja de arriba dice el lado antes que cualquier palabra: oro lo
   que tenemos, turquesa lo que debemos — los mismos colores del borde
   de cada tarjeta y de los KPI.
   The band on top says which side before any word does: gold for what
   we hold, teal for what we owe — the same colours as each card's edge
   and the KPIs. */
.pos-col::before{ content:'';display:block;height:3px }
.pos-col.long::before { background:var(--gold) }
.pos-col.short::before{ background:var(--teal) }

.pos-col-head{
  display:flex;align-items:baseline;gap:8px;
  padding:10px 14px 9px;
  border-bottom:1px solid var(--line);
}
.pos-col-head h2{ font-size:13px;margin:0;letter-spacing:-.01em;font-weight:600 }
.pos-col-n{
  font-size:11px;font-weight:600;padding:0 6px;border-radius:9px;
  background:var(--neutral-bg);color:var(--neutral);
}
.pos-col.long  .pos-col-n{ background:rgba(200,169,106,.2);color:var(--gold-deep) }
.pos-col.short .pos-col-n{ background:rgba(45,212,223,.2);color:var(--teal-deep) }
.pos-col-mt{ font-size:12px;font-weight:600;color:var(--mute);white-space:nowrap }

/* El cuerpo va sobre el tono de página: así las tarjetas, que son
   blancas, se despegan del panel en vez de fundirse con él.
   The body sits on the page tint so the cards, which are white, lift
   off the panel instead of merging into it. */
.pos-col-body{ padding:10px;background:var(--bg) }
.pos-col-body>.btn{ margin-top:4px }

.pos{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);margin-bottom:10px;overflow:hidden;
  border-left:3px solid var(--line);
}
.pos.long{border-left-color:var(--gold)}
.pos.short{border-left-color:var(--teal)}
.pos-head{
  display:flex;align-items:center;gap:8px;cursor:pointer;
  padding:9px 13px;border-bottom:1px solid var(--line-soft);
}
.pos-head:hover{background:var(--bg)}
.pos-head .spacer{flex:1}
.pos-body{padding:10px 13px}
.pos-match{border-top:1px solid var(--line-soft);background:var(--bg)}
.pos-match>summary{
  list-style:none;cursor:pointer;padding:7px 13px;
  font-size:11.5px;color:var(--accent);font-weight:500;
}
.pos-match>summary::-webkit-details-marker{display:none}
.pos-match>summary:hover{background:var(--accent-tint)}
.pos-match>div{padding:0 13px 8px}
.pos-match.empty-match{padding:7px 13px;font-size:11.5px;color:var(--mute)}

/* Cuánto de la posición está ya cubierto. La barra es lo que hace que
   «50 de 200» se lea sin hacer la cuenta.
   How much of the position is already covered. The bar is what makes
   "50 of 200" legible without doing the arithmetic. */
.cover-bar{ height:4px;border-radius:2px;background:var(--line);overflow:hidden }
.cover-bar>span{ display:block;height:100%;background:var(--accent) }
.pos.long  .cover-bar>span{ background:var(--gold) }
.pos.short .cover-bar>span{ background:var(--teal) }

/* Una contraparte candidata. La que encaja va limpia; la que comparte
   producto pero no ficha se marca con un filo y enseña en qué difiere
   — enterrarlo en un tooltip sería esconder justamente lo que hay que
   leer antes de decidir.
   A candidate counterpart. The one that fits is plain; the one sharing
   a product but not a sheet gets an edge and shows what differs —
   burying it in a tooltip would hide precisely what has to be read
   before deciding. */
.cand{ padding:6px 0;border-bottom:1px solid var(--line-soft) }
.cand:last-child{ border-bottom:0 }
.cand.differs{
  border-left:2px solid var(--warn);
  padding-left:8px;margin-left:-10px;background:var(--warn-bg);
}
.cand-diff{
  font-size:11px;line-height:1.5;color:var(--ink);
  margin-top:4px;padding-left:1px;
}
.cand-diff>b{ display:block;color:var(--warn);font-size:10.5px;
  letter-spacing:.03em;text-transform:uppercase;margin-bottom:2px }

/* ============================================================
   TONOS / TONES
   ------------------------------------------------------------
   UNA SOLA REGLA: EL ROJO Y EL AMARILLO SON DEL RELOJ.
   Nada más los usa. Si algo sale en rojo es porque una fecha ya
   pasó; si sale en amarillo, porque está a punto de pasar. Punto.

   Estaban en todas partes: el lado de compra iba en amarillo para
   distinguirlo del de venta, «broker» en amarillo, «editada» en
   amarillo, el margen flojo en rojo, las salidas de caja en rojo.
   Todo eso son estados y categorías, no urgencias. Cuando el rojo
   señala veinte cosas distintas deja de señalar ninguna, y la
   factura vencida de verdad se pierde entre ellas.

   Los tonos, y lo que significa cada uno:

     t-due    rojo      una fecha ya venció
     t-soon   ámbar     una fecha vence pronto
     t-mine   acento    te toca a ti — sin prisa de calendario
     t-wait   gris      está en manos de otro
     t-done   verde     terminado
     t-flat   gris      una etiqueta de estado, sin juicio

   ONE RULE: RED AND AMBER BELONG TO THE CLOCK. Nothing else uses
   them. If something is red it is because a date has passed; amber,
   because one is about to. That is all.

   They were everywhere: the buy side in amber to tell it from the
   sell side, "broker" in amber, "edited" in amber, thin margin in
   red, cash outflows in red. Those are states and categories, not
   urgencies. When red flags twenty different things it flags none,
   and the genuinely overdue invoice is lost among them.
   ============================================================ */
.t-due  { background:var(--danger-bg);  color:var(--danger) }
.t-soon { background:var(--warn-bg);    color:var(--warn) }
.t-mine { background:var(--accent-soft);color:var(--accent) }
.t-wait { background:var(--neutral-bg); color:var(--mute) }
.t-done { background:var(--ok-bg);      color:var(--ok) }
.t-flat { background:var(--neutral-bg); color:var(--neutral) }

/* En texto suelto, sin fondo. */
.tx-due  { color:var(--danger); font-weight:600 }
.tx-soon { color:var(--warn);   font-weight:600 }
.tx-wait { color:var(--mute) }

/* Casilla de importe con su símbolo pegado. El $ va dentro del marco,
   no al lado: así se lee como parte del campo y no como una etiqueta
   suelta que podría referirse a la columna entera.
   An amount box with its symbol attached. The $ sits inside the frame,
   not beside it: it then reads as part of the field rather than a
   loose label that might belong to the whole column. */
.money-in{
  display:inline-flex;align-items:center;gap:2px;
  border:1px solid var(--line);border-radius:4px;
  padding:0 6px;background:var(--surface);
}
.money-in{ cursor:text }
.money-in:focus-within{ border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-ring) }
.money-in>span{ color:var(--mute);font-size:12px }
.money-in>input{
  width:78px;text-align:right;padding:3px 0;
  border:0;outline:0;background:transparent;font:inherit;font-size:12px;
}
/* Quita las flechitas del number: en una casilla de importe estorban
   más que ayudan. / Strips the number spinners: on an amount box they
   get in the way more than they help. */
.money-in>input::-webkit-outer-spin-button,
.money-in>input::-webkit-inner-spin-button{ -webkit-appearance:none;margin:0 }
.money-in>input[type=number]{ -moz-appearance:textfield }

/* En una fila de líneas ocupa la celda entera, para que las tres
   casillas queden a la misma altura y al mismo ancho de columna.
   In a line row it fills the cell, so the three boxes end up at the
   same height and column width. */
td>.money-in{ display:flex;width:100%;padding:4px 8px }
td>.money-in>input{ width:100%;font-size:12.5px }

/* La unidad va al final, no delante: «24 MT» se lee en ese orden.
   The unit goes last, not first: "24 MT" reads in that order. */
.money-in.unit-in>span{ order:2;margin-left:2px }
.money-in.unit-in>input{ order:1 }

/* El costo es interno, y el campo lo dice con el mismo fondo hueso
   que el resto de lo que no sale al cliente.
   Cost is internal, and the field says so with the same bone tint
   used everywhere for what never reaches the client. */
.money-in.internal{ background:var(--foam) }

/* Rótulos «mín. / máx.» sobre la horquilla de cantidad. Están
   siempre, aunque la línea sea de cantidad fija: si sólo saliesen al
   escribir el máximo, la fila daría un salto justo mientras se teclea.
   "min / max" labels above the quantity range. Always present, even on
   fixed-quantity lines: showing them only once a maximum is typed makes
   the row jump under the cursor. */
.qty-lab{ font-size:10px;color:var(--mute);letter-spacing:.02em;margin-bottom:3px;line-height:1 }


/* ------------------------------------------------------------
   COLAPSABLE ANIDADO — el detalle dentro de su tarjeta
   ------------------------------------------------------------
   Los parámetros de calidad eran una tarjeta por producto, al lado
   de la tarjeta que ya listaba esos productos. Dos tarjetas del
   mismo peso visual para una sola cosa se leen como dos listas
   distintas. Dentro necesitan otro peso: una línea, no un marco.
   NESTED COLLAPSIBLE. Quality parameters were a card per product
   beside the card already listing those products — two blocks of
   equal visual weight for one thing. Inside, they need a lighter
   register: a rule, not a frame.
   ------------------------------------------------------------ */
.sub-blk{ border:1px solid var(--line-soft);border-radius:var(--radius-sm);
          margin-bottom:6px;background:var(--surface) }
.sub-blk[open]{ background:#fff;border-color:var(--line) }
.sub-head{ display:flex;align-items:center;gap:8px;padding:7px 10px;cursor:pointer;
           list-style:none;font-size:12px }
.sub-head::-webkit-details-marker{ display:none }
.sub-head:hover{ background:var(--blue-tint) }
.sub-t{ font-weight:600;font-size:12.5px;letter-spacing:-.01em }
.sub-blk .blk-chev{ transition:transform .12s;color:var(--mute);font-size:12px }
.sub-blk[open] .blk-chev{ transform:rotate(180deg) }
.sub-blk .card-body{ padding:0 10px 8px }

/* Variante estrecha, para los precios por destino apilados. */
.money-in.sm{ padding:1px 5px }
.money-in.sm>input{ width:58px;font-size:11.5px }

/* Lista para elegir un registro dentro de un diálogo — qué contrato
   embarcar, por ejemplo. La fila entera es el objetivo del clic, no
   sólo el redondel: acertarle a un radio de 13 px es trabajo de
   puntería que nadie pidió.
   A list for picking a record inside a dialog — which contract to
   ship, for instance. The whole row is the click target, not just the
   radio: hitting a 13px circle is marksmanship nobody asked for. */
.pick-list{ border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden }
.pick-row{
  display:flex;align-items:center;gap:10px;cursor:pointer;
  padding:9px 12px;border-bottom:1px solid var(--line-soft);
}
.pick-row:last-child{ border-bottom:0 }
.pick-row:hover{ background:var(--bg) }
.pick-row:has(input:checked){ background:var(--accent-tint) }

/* ---------- Pestañas de pantalla / screen tabs ----------
   Cuando varias pantallas comparten una entrada del menú, esta barra
   dice cuáles son y en cuál estás. Va arriba del todo, antes de los
   KPI, porque es navegación y no contenido: si estuviera mezclada
   entre las tarjetas parecería un filtro, y no lo es — cambia de
   pantalla, no de vista.
   When several screens share one menu entry, this bar says which
   they are and where you stand. It sits at the very top, before the
   KPIs, because it is navigation and not content: mixed in among the
   cards it would read as a filter, which it is not — it changes
   screen, not view. */
.shell-tabs{
  display:flex;gap:2px;margin:-4px 0 20px;
  border-bottom:1px solid var(--line);
}
/* VENTAS · COMPRAS. Son el segundo nivel de navegación y se leían
   como texto corriente al lado de un título en mayúscula.
   They are the second level of navigation and read as running text
   beside a capitalised title. */
.shell-tabs a{
  display:flex;align-items:center;gap:7px;
  padding:8px 14px;font-size:12.5px;font-weight:600;
  text-transform:uppercase;letter-spacing:.05em;
  color:var(--mute);text-decoration:none;
  border-bottom:2px solid transparent;margin-bottom:-1px;
}
.shell-tabs a:hover{color:var(--ink);background:var(--bg)}
.shell-tabs a.on{color:var(--accent);border-bottom-color:var(--accent);font-weight:700}
.shell-n{
  font-size:11px;font-weight:600;padding:1px 6px;border-radius:9px;
  background:var(--neutral-bg);color:var(--neutral);
}
.shell-tabs a.on .shell-n{background:var(--accent-soft);color:var(--accent)}

/* Los bloques por tipo de producto dentro de cada columna. Las
   tarjetas ya traen su propio borde, así que el bloque que las
   contiene se aligera: sin sombra y con el fondo de la página. Si no,
   se ven cajas dentro de cajas y el tablero pesa el doble.
   Un bloque en cero se apaga — sigue ahí, se lee que no hay nada, y
   no compite por la atención con los que sí tienen posición.
   The per-type blocks inside each column. The cards carry their own
   border, so the containing block is lightened: no shadow, page
   background. Otherwise it reads as boxes inside boxes and the board
   feels twice as heavy. A block at zero is dimmed — still there, still
   legible as empty, but not competing for attention with the ones
   that hold position. */
/* Los bloques por tipo, dentro del panel: cada uno es una tarjeta
   blanca sobre el fondo del cuerpo. Compacta —una fila de 30 px— para
   que seis categorías quepan sin que la columna se estire.
   The per-type blocks inside the panel: each a white card on the
   body's tint. Compact — a 30px row — so six categories fit without
   the column stretching. */
.pos-board .blk{
  box-shadow:none;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  margin-bottom:6px;
}
.pos-board .blk>.card-head{padding:6px 10px;min-height:0}
.pos-board .blk>.card-head h3{font-size:12px;font-weight:600}
.pos-board .blk>.card-head:hover{background:var(--bg)}
.pos-board .blk>.card-body{padding:2px 8px 8px;background:var(--bg)}
.pos-board .blk .pos{margin-bottom:6px}
.pos-board .blk .pos:last-child{margin-bottom:0}
.pos-board .blk:not([open])>.card-head{border-bottom:none}
/* Una categoría en cero se apaga: sigue ahí, se lee que no hay nada, y
   no compite con las que sí tienen posición. */
.pos-board .blk.zero{background:transparent;border-style:dashed}
.pos-board .blk.zero>.card-head h3{color:var(--mute);font-weight:500}

/* ---------- Tabla compacta / compact table ----------
   Sin cabecera y con una franja de urgencia a la izquierda: el color
   dice si corre prisa antes de leer nada. / No header row, and an
   urgency stripe on the left: the colour says whether it is urgent
   before you read anything. */
table.compact td{padding:9px 12px;vertical-align:middle}
table.compact tr{border-left:3px solid transparent}
table.compact tr.u-now{border-left-color:var(--warn)}
table.compact tr.u-soon{border-left-color:var(--accent)}
table.compact tr.u-wait{border-left-color:var(--line)}
table.compact tr.u-done{border-left-color:transparent}
table.compact tr.u-done td{opacity:.62}
table.compact tr:hover td{background:var(--bg)}

/* ---------- Símbolo de la acción / action glyph ----------
   La forma se reconoce antes que la palabra: con nueve filas iguales,
   ver dos «↻» y tres «→» ahorra leerlas todas.
   Shape is recognised before language: with nine identical rows,
   seeing two "↻" and three "→" saves reading all of them. */
.act-ico{
  display:inline-grid;place-items:center;
  width:19px;height:19px;border-radius:5px;flex:none;
  font-size:11px;line-height:1;font-weight:600;
  margin-right:7px;vertical-align:-4px;
  background:var(--neutral-bg);color:var(--neutral);
}
.act-ico.u-now{background:var(--warn-bg);color:var(--warn)}
.act-ico.u-soon{background:var(--accent-tint);color:var(--accent)}
.act-ico.u-wait{background:var(--neutral-bg);color:var(--neutral)}
.act-ico.u-done{background:var(--ok-bg);color:var(--ok)}

/* ---------- Quién la hizo / who raised it ---------- */
.who-chip{
  display:inline-grid;place-items:center;
  width:24px;height:24px;border-radius:50%;
  font-size:9.5px;font-weight:600;letter-spacing:.02em;
  background:var(--neutral-bg);color:var(--mute);
}
.who-chip.me{background:var(--accent-tint);color:var(--accent)}

/* ---------- Interruptor de lado / side switch ----------
   Vender o comprar, en el mismo constructor. Se ve de qué lado estás
   antes de escribir nada. / Sell or buy, in the same builder. Which
   side you are on is visible before typing anything. */
.side-switch{display:inline-flex;border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden}
.side-switch a{
  padding:6px 14px;font-size:12.5px;text-decoration:none;
  color:var(--mute);background:var(--surface);transition:.13s;
}
.side-switch a+a{border-left:1px solid var(--line)}
.side-switch a:hover{background:var(--bg);color:var(--ink)}
.side-switch a.on{background:var(--navy);color:#fff;font-weight:500}


/* ============================================================
   LA HOJA / THE SHEET
   ------------------------------------------------------------
   Los documentos que salen al cliente —cotización y contrato— se
   dibujan sobre una hoja A4 de verdad: 210 mm de ancho con 18 mm de
   margen. Antes tomaban el ancho del diálogo, así que en un monitor
   ancho una cotización salía de 900 px y al imprimirla se partía por
   donde caía.

   Y hay reglas de corte: una tabla no se parte por la mitad, un
   título no se queda solo al pie de página, y el bloque de firmas no
   acaba en una hoja aparte con nada encima. Son las tres cosas que
   estropean un documento impreso.

   AL IMPRIMIR SE IMPRIME LA HOJA, NADA MÁS. Se apaga el menú, la
   barra superior, el fondo del diálogo y los botones. Lo que queda
   es el papel.

   THE SHEET. Client-facing documents are drawn on a real A4 sheet:
   210mm wide with 18mm margins. And there are break rules: a table is
   not cut in half, a heading does not sit alone at the foot of a
   page, and the signature block does not land on a page of its own.
   Those are the three things that ruin a printed document.
   WHEN PRINTING, THE SHEET PRINTS AND NOTHING ELSE.
   ============================================================ */
.doc-sheet{
  width:210mm;max-width:100%;
  min-height:auto;
  margin:0 auto;
  padding:18mm;
  background:#fff;color:#000;
  border:1px solid var(--line);
  box-shadow:0 2px 14px rgba(13,46,82,.10);
  font-size:10.5px;line-height:1.45;
}
/* El diálogo se ensancha para que quepa la hoja entera. Verla
   recortada obliga a imprimirla para saber cómo queda, que es
   justo lo que la vista previa debería evitar. */
.modal.wide{ max-width:calc(210mm + 48px) }

/* Dónde SÍ puede cortarse la página, y dónde no. */
.doc-sheet table{ page-break-inside:avoid; break-inside:avoid }
.doc-sheet h1,.doc-sheet h2,.doc-sheet h3{ page-break-after:avoid; break-after:avoid }
.doc-sheet .no-break{ page-break-inside:avoid; break-inside:avoid }

@media print{
  /* EL MARGEN ES DE CADA PÁGINA, NO DE LA HOJA (29-sep-2026). Con el
     margen puesto como relleno de la hoja, sólo lo tenían la primera
     página arriba y la última abajo: la segunda empezaba pegada al
     borde, y cuando el texto llenaba la página justa, el relleno de
     abajo se iba solo a una página en blanco.
     THE MARGIN BELONGS TO EACH PAGE, NOT TO THE SHEET. */
  @page{ size:A4; margin:14mm 0 }
  body{ background:#fff }
  /* Fuera todo lo que no es el papel. */
  .sidebar,.topbar,.modal-head,.modal-foot,.notice,.btn,.x-btn,.no-print{ display:none !important }
  /* Con un diálogo abierto, la página de debajo no se imprime. Sin
     esto, imprimir una ficha desde el catálogo sacaba el catálogo.
     With a dialog open the page underneath does not print. Without
     this, printing a sheet from the catalogue printed the catalogue. */
  body.modal-open>.app,
  body.modal-open>.wrap{ display:none !important }
  .modal-bg{ position:static;padding:0;background:0;backdrop-filter:none;display:block }
  .modal{ max-width:none;width:auto;box-shadow:none;border-radius:0;max-height:none;overflow:visible }
  .modal-body{ padding:0 }
  .doc-sheet{
    width:auto;border:0;box-shadow:none;margin:0;
    padding:0 16mm;
  }
  /* La franja de borrador va de borde a borde, arriba del todo. */
  .doc-sheet .franja{ margin:0 -16mm !important }
}


/* Sub-banda dentro de una ficha: separa dos clases de campo que
   parecían lo mismo. La de arriba dice qué son y la de la derecha
   advierte de su alcance — que es lo que faltaba: unos campos se
   negocian en cada pedido y otros no, y el formulario los presentaba
   idénticos.
   A sub-band inside a form: separates two kinds of field that looked
   alike. Some are negotiated on every order and some are not, and the
   form presented them identically. */
.sub-band{
  display:flex;align-items:baseline;gap:10px;
  margin:4px 0 12px;padding-bottom:5px;
  border-bottom:1px solid var(--line);
}
.sub-band>span:first-child{
  font-size:11px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink);
}
.sub-band>.tiny{ color:var(--mute);margin-left:auto;font-style:italic }


/* El selector de modo dice, debajo del nombre, lo único que de verdad
   los separa: si lo que haces sobrevive a recargar. Sin eso, «Demo»
   se lee como «datos de ejemplo» y no como «esto se borra».
   The mode picker says, under the name, the only thing that really
   separates them: whether what you do survives a reload. */
.mode-toggle{ display:flex;gap:2px;background:var(--bg);border:1px solid var(--line);
              border-radius:var(--radius-sm);padding:2px }
.mode-toggle>button{
  border:0;background:0;cursor:pointer;font:inherit;
  padding:3px 10px 4px;border-radius:4px;color:var(--mute);
  display:flex;flex-direction:column;align-items:center;line-height:1.15;
  font-size:12px;font-weight:600;
}
.mode-toggle>button>span{ font-size:9px;font-weight:500;letter-spacing:.03em;opacity:.8 }
.mode-toggle>button:hover{ color:var(--ink) }
.mode-toggle>button.on{ background:var(--surface);color:var(--accent);box-shadow:var(--shadow) }


/* La × de un aviso. Discreta hasta que pasas por encima: cerrar es
   una salida, no una acción que haya que ofrecer con insistencia.
   A notice's ×. Discreet until hovered: dismissing is an exit, not an
   action to press on anyone. */
.notice{ position:relative }
.notice-x{
  position:absolute;top:5px;right:7px;
  border:0;background:0;cursor:pointer;line-height:1;
  font-size:16px;color:currentColor;opacity:.35;padding:1px 3px;border-radius:4px;
}
.notice-x:hover{ opacity:1;background:rgba(0,0,0,.06) }

/* ---------------------------------------------------------------
   ZONA DE ARCHIVOS / FILE DROP
   Borde discontinuo: dice «esto no es un campo, aquí se suelta»
   sin necesidad de leer nada. Al arrastrar encima se tiñe, que es
   la única confirmación de que el navegador va a aceptarlo.
   A dashed border says "not a field — drop here" without reading.
   It tints on hover-drag, the only confirmation the browser will
   take the file.
   --------------------------------------------------------------- */
.drop{
  display:flex;align-items:center;gap:9px;cursor:pointer;
  padding:14px 12px;margin-top:4px;
  border:1.5px dashed var(--line);border-radius:var(--radius-sm);
  background:var(--bg);color:var(--mute);font-size:12px;
  transition:background .12s,border-color .12s;
}
.drop:hover{ border-color:var(--accent);background:var(--surface) }
.drop.over{ border-color:var(--accent);background:var(--accent-tint);color:var(--accent) }
.drop .di{ font-size:15px;line-height:1 }
.drop-list{ margin-top:7px;display:flex;flex-direction:column;gap:5px }
.drop-file{
  display:flex;align-items:center;gap:9px;
  padding:6px 9px;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--surface);font-size:11.5px;
}
.drop-file .df-n{ flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap }

/* La mezcla de tallas: títulos centrados sobre su casilla y todas las
   casillas en la misma línea y a la misma altura. El empaque lleva
   debajo su peso, y con la alineación al centro vertical eso subía
   su casilla por encima de las demás.
   The size mix: headings centred over their box, every box on one line
   at one height. The pack's weight note underneath used to lift its
   box above the rest. */
.mezcla th,.mezcla th.r{text-align:center}
.mezcla td{vertical-align:top;text-align:center}
.mezcla td select,.mezcla td>.money-in,.mezcla td .btn{height:32px!important;box-sizing:border-box}
.mezcla td>.money-in{align-items:center}
.mezcla td.num{line-height:32px}
.mezcla td .cell-sub{text-align:center}
