/* ===========================================================================
   SOLID ERP — tema claro "premium" (estilo Tailwind/Shadcn) + sidebar + grid
   =========================================================================== */
:root {
  --background: 50 33% 98%;
  --foreground: 240 21% 15%;
  --card: 0 0% 100%;
  --card-foreground: 240 21% 15%;
  --popover: 50 33% 98%;
  --sidebar: 0 0% 100%;
  --sidebar-border: 240 5% 90%;
  --sidebar-primary: 208 88% 22%;
  --primary: 208 88% 22%;
  --primary-foreground: 0 0% 100%;
  --muted: 240 5% 90%;
  --muted-foreground: 240 6% 50%;
  --border: 240 5% 90%;
  --input: 240 5% 90%;
  --radius: .75rem;

  /* Acento por modo del chat (se sobreescribe con data-mode) */
  --accent: 208 88% 22%;
  --danger: 0 72% 51%;
  --mono: "JetBrains Mono", ui-monospace, monospace;

  /* Fase 29 — Altura de los desplegables anclados. Uno solo para los tres (antes
     convivían 100, 100 y 200 sin motivo). Debe quedar por DEBAJO de los modales (500)
     y del sidebar móvil (1000): un desplegable nunca tapa a un diálogo. */
  --z-panel-anclado: 200;

  /* Hoja de detalle en móvil (≤640px). Entre los desplegables (200) y los modales (500):
     la hoja tapa un desplegable que hubiera quedado abierto, pero nunca a un diálogo ni
     al sidebar móvil (1000). El fondo va en este valor y la hoja en +1. */
  --z-hoja-detalle: 300;
}

/* ===========================================================================
   FASE 25 — TEMA OSCURO ("slate azulado"). Sobrescribe SOLO las variables HSL;
   como el resto del CSS usa hsl(var(--…)), todas las superficies se adaptan.
   Mayor especificidad que :root, así que gana sin !important.
   =========================================================================== */
:root[data-theme="dark"] {
  --background: 222 18% 11%;
  --foreground: 210 20% 92%;
  --card: 222 16% 15%;
  --card-foreground: 210 20% 92%;
  --popover: 222 16% 15%;
  --sidebar: 222 17% 13%;
  --sidebar-border: 222 12% 24%;
  --sidebar-primary: 208 90% 58%;
  --primary: 208 90% 58%;            /* azul aclarado: resalta sobre fondo oscuro */
  --primary-foreground: 0 0% 100%;
  --muted: 222 14% 22%;
  --muted-foreground: 215 15% 65%;
  --border: 222 12% 24%;
  --input: 222 12% 24%;
  --accent: 208 90% 58%;
  --danger: 0 75% 62%;
}
/* Superficies con color CLARO hardcodeado (no derivan de variables) que sí conviene
   oscurecer por ser muy visibles: el fondo global y los campos de texto (login/chat). */
:root[data-theme="dark"] body {
  background: linear-gradient(135deg, hsl(222 22% 8%), hsl(222 18% 12%));
}
:root[data-theme="dark"] .field input,
:root[data-theme="dark"] .field select,
:root[data-theme="dark"] :is(#input, [id^="input_"]) {
  background: hsl(var(--card));
}

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

html, body { overflow-x: hidden; }

body {
  font-family: "Montserrat", system-ui, sans-serif;
  color: hsl(var(--foreground));
  background: linear-gradient(135deg, #f8fafc, #e0e7ef);
  height: 100vh; height: 100dvh; overflow: hidden;
}

.screen { height: 100vh; height: 100dvh; }
.centered { display: grid; place-items: center; padding: 24px; }

.logo-badge {
  width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  display: grid; place-items: center; font-weight: 700; font-size: 1.1rem;
  box-shadow: 0 4px 14px hsl(var(--primary) / 0.35);
}

/* ----- Tarjetas login / empresa ------------------------------------------ */
.card {
  width: 100%; max-width: 390px;
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: 18px; padding: 34px 30px;
  box-shadow: 0 20px 50px rgba(30, 41, 59, 0.12);
  animation: rise .3s ease;
}
.brand-block { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.brand-block h1 { font-size: 1.35rem; font-weight: 700; letter-spacing: -0.02em; }
.accent { color: hsl(var(--primary)); }
.card-sub { color: hsl(var(--muted-foreground)); font-size: .9rem; margin-bottom: 22px; }

.field { margin-bottom: 16px; }
.field label {
  display: block; font-size: .76rem; color: hsl(var(--muted-foreground));
  margin-bottom: 6px; text-transform: uppercase; letter-spacing: .05em; font-weight: 600;
}
.field input, .field select {
  width: 100%; background: #fff; border: 1px solid hsl(var(--input));
  border-radius: 10px; color: hsl(var(--foreground));
  font-family: inherit; font-size: .95rem; padding: 12px 14px; outline: none;
  transition: border-color .2s, box-shadow .2s;
}
.field input:focus, .field select:focus {
  border-color: hsl(var(--primary)); box-shadow: 0 0 0 3px hsl(var(--primary) / 0.12);
}
.field select { cursor: pointer; }

.btn-primary {
  width: 100%; margin-top: 6px; background: hsl(var(--primary));
  color: hsl(var(--primary-foreground)); border: none; font-family: inherit;
  font-weight: 600; font-size: .95rem; padding: 13px; border-radius: 10px;
  cursor: pointer; transition: transform .1s, opacity .2s, box-shadow .2s;
  box-shadow: 0 6px 18px hsl(var(--primary) / 0.25);
}
.btn-primary:hover { transform: translateY(-1px); }
.btn-primary:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.btn-link {
  width: 100%; margin-top: 12px; background: none; border: none;
  color: hsl(var(--muted-foreground)); font-size: .82rem; cursor: pointer; text-decoration: underline;
}
.btn-link:hover { color: hsl(var(--primary)); }
.form-error { color: hsl(var(--danger)); font-size: .84rem; min-height: 18px; margin-bottom: 4px; }
/* Las barras de error de acceso arrancan ocultas; app.js las muestra solo ante un error. */
#login-error, #empresa-error { display: none; }

@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; } }

/* ----- Shell: sidebar + main --------------------------------------------- */
.shell { display: flex; height: 100vh; height: 100dvh; }

.sidebar {
  width: 240px; flex-shrink: 0; background: hsl(var(--sidebar));
  border-right: 1px solid hsl(var(--sidebar-border));
  display: flex; flex-direction: column; padding: 18px 14px; gap: 8px;
  z-index: 40; box-shadow: 1px 0 8px rgba(30,41,59,.04);
  height: 100vh; height: 100dvh;   /* altura acotada explícita para el scroll interno */
  min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
}
.sidebar-brand {
  display: flex; align-items: center; gap: 10px; font-size: 1.05rem;
  padding: 6px 8px 16px; border-bottom: 1px solid hsl(var(--sidebar-border)); margin-bottom: 8px;
}
.nav-group { display: flex; flex-direction: column; gap: 2px; }
.nav-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
  color: hsl(var(--muted-foreground)); font-weight: 600; padding: 10px 10px 4px;
}
.nav-item {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  background: transparent; border: none; cursor: pointer; font-family: inherit;
  font-size: .92rem; color: hsl(var(--foreground)); padding: 10px 12px;
  border-radius: 10px; transition: background .15s, color .15s;
  min-height: 44px;
}
.nav-item span { font-size: 1.05rem; }
.nav-item:hover { background: hsl(var(--muted) / 0.6); }
.nav-item.is-active { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); font-weight: 600; }
.nav-ai { border: 1px dashed hsl(var(--sidebar-border)); }
.nav-ai.is-active { border-color: transparent; }

/* Carpetas desplegables (acordeón) */
.nav-folder { display: flex; flex-direction: column; }
.nav-folder-toggle .chev {
  margin-left: auto; font-size: .8rem; color: hsl(var(--muted-foreground));
  transition: transform .2s;
}
.nav-folder.open .nav-folder-toggle .chev { transform: rotate(90deg); }
.nav-sub { display: none; flex-direction: column; gap: 2px; margin: 2px 0 4px; }
.nav-folder.open .nav-sub { display: flex; }
.nav-subitem { padding-left: 40px; font-size: .88rem; color: hsl(var(--muted-foreground)); }
.nav-subitem:hover { color: hsl(var(--foreground)); }
.nav-subitem.is-active { color: hsl(var(--primary-foreground)); }
.sidebar-foot { margin-top: auto; display: flex; flex-direction: column; gap: 2px;
  padding-top: 12px; border-top: 1px solid hsl(var(--sidebar-border)); }
.link-btn {
  background: none; border: none; text-align: left; cursor: pointer; font-family: inherit;
  font-size: .82rem; color: hsl(var(--muted-foreground)); padding: 8px 12px; border-radius: 8px;
  transition: color .15s, background .15s;
  min-height: 44px; display: flex; align-items: center;
}
.link-btn:hover { color: hsl(var(--primary)); background: hsl(var(--muted) / 0.5); }
.sidebar-backdrop { display: none; }

.main-area { flex: 1; display: flex; flex-direction: column; min-width: 0; }

/* ----- Topbar ------------------------------------------------------------ */
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 22px; border-bottom: 1px solid hsl(var(--border)); background: hsl(var(--card));
  position: relative; z-index: 50; flex-shrink: 0;
  box-shadow: 0 1px 8px rgba(30,41,59,.08);
}
.topbar-title { flex: 1; min-width: 0; }
.topbar-title h2, .topbar-title .sub {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-title h2 { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }
.sub { color: hsl(var(--muted-foreground)); font-size: .78rem; }
/* Fase 22 — indicador discreto de la sesión nativa ("Sesión: <n> - <fecha>"). */
.session-badge {
  display: block; font-family: var(--mono); font-size: .68rem;
  color: hsl(var(--muted-foreground)); opacity: .6; letter-spacing: .02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.session-badge:empty { display: none; }   /* no ocupa espacio si aún no hay sesión */
.status {
  font-family: var(--mono); font-size: .72rem; color: hsl(var(--primary));
  border: 1px solid hsl(var(--border)); padding: 5px 12px; border-radius: 999px;
  background: hsl(var(--background)); white-space: nowrap;
}
.hamburger {
  display: none; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: hsl(var(--muted) / 0.5); border: 1px solid hsl(var(--border));
  border-radius: 8px; cursor: pointer; padding: 11px 10px; flex-shrink: 0;
  min-width: 44px; min-height: 44px;
}
.hamburger span { width: 20px; height: 2px; background: hsl(var(--foreground)); border-radius: 2px; }

/* ===========================================================================
   FASE 25 — Botón de tema + menú de usuario de la topbar
   =========================================================================== */
.icon-btn {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; font-size: 1.05rem; line-height: 1; cursor: pointer;
  background: hsl(var(--muted) / 0.5); border: 1px solid hsl(var(--border));
  border-radius: 10px; color: hsl(var(--foreground)); transition: background .15s, border-color .15s;
}
.icon-btn:hover { background: hsl(var(--muted)); border-color: hsl(var(--primary) / 0.4); }

.user-menu { flex-shrink: 0; }
.user-menu-toggle {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  background: hsl(var(--muted) / 0.5); border: 1px solid hsl(var(--border));
  border-radius: 999px; padding: 4px 12px 4px 4px; color: hsl(var(--foreground));
  font-family: inherit; font-size: .85rem; transition: background .15s, border-color .15s;
}
.user-menu-toggle:hover { background: hsl(var(--muted)); border-color: hsl(var(--primary) / 0.4); }
.user-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  font-size: .74rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
}
.user-name {
  max-width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600;
}
.user-caret { font-size: .7rem; color: hsl(var(--muted-foreground)); }

/* La posición la pone anclaje.js (.panel-anclado): aquí solo el aspecto. */
.user-dropdown-menu {
  min-width: 210px; padding: 6px; display: flex; flex-direction: column; gap: 2px;
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: 12px; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22);
}
.user-dropdown-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 10px 12px; border: none; border-radius: 8px; cursor: pointer;
  background: transparent; color: hsl(var(--foreground)); font-family: inherit; font-size: .9rem;
}
.user-dropdown-item:hover { background: hsl(var(--muted) / 0.7); }

/* Vista de perfil (Fase 25) */
.perfil-wrap { padding: 28px 32px; overflow-y: auto; }
.perfil-wrap h2 { font-size: 1.3rem; font-weight: 700; margin-bottom: 6px; color: hsl(var(--foreground)); }
.perfil-intro { color: hsl(var(--muted-foreground)); margin-bottom: 20px; }
.perfil-datos {
  display: grid; grid-template-columns: max-content 1fr; gap: 10px 24px;
  max-width: 640px; background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: var(--radius); padding: 20px 24px;
}
.perfil-datos dt { font-weight: 600; color: hsl(var(--muted-foreground)); }
.perfil-datos dd { color: hsl(var(--foreground)); font-family: var(--mono); font-size: .88rem; }

.view { flex: 1; display: flex; flex-direction: column; min-height: 0; min-width: 0; }

/* ----- Dashboard de Dirección --------------------------------------------- */
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  padding: 22px;
  overflow-y: auto;
}

.dashboard-card {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  box-shadow: 0 2px 12px rgba(30, 41, 59, 0.06);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  min-height: 280px;
}

.dashboard-card h3 {
  margin: 0 0 12px;
  font-size: .95rem;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.dashboard-card canvas {
  flex: 1;
  min-height: 0;
}

@media (max-width: 1100px) {
  .dashboard-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .dashboard-grid { grid-template-columns: 1fr; padding: 14px; }
}

/* ----- Modo dual --------------------------------------------------------- */
#app-root[data-mode="asesor"]      { --accent: 208 88% 22%; }
#app-root[data-mode="operaciones"] { --accent: 160 70% 32%; }

.modebar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 10px 22px; border-bottom: 1px solid hsl(var(--border)); background: hsl(var(--card));
}
.mode-switch { display: inline-flex; background: hsl(var(--muted) / 0.5);
  border: 1px solid hsl(var(--border)); border-radius: 999px; padding: 3px; }
.mode-tab {
  background: transparent; border: none; color: hsl(var(--muted-foreground));
  font-family: inherit; font-size: .84rem; font-weight: 500; padding: 9px 16px;
  border-radius: 999px; cursor: pointer; transition: all .18s;
}
.mode-tab:hover { color: hsl(var(--foreground)); }
.mode-tab.is-active { background: hsl(var(--accent)); color: #fff; font-weight: 600; }
.mode-hint { color: hsl(var(--muted-foreground)); font-size: .8rem; }

/* ----- Chat -------------------------------------------------------------- */
.chat { flex: 1; overflow-y: auto; padding: 24px 22px; display: flex; flex-direction: column; gap: 18px; }
.welcome { margin: auto; text-align: center; max-width: 540px; }
.welcome h2 { font-size: 1.7rem; margin-bottom: 10px; letter-spacing: -0.02em; }
.welcome p { color: hsl(var(--muted-foreground)); margin-bottom: 22px; }
.chips { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.chip {
  background: hsl(var(--card)); border: 1px solid hsl(var(--border)); color: hsl(var(--foreground));
  padding: 9px 15px; border-radius: 999px; font-size: .85rem; cursor: pointer;
  transition: border-color .2s, transform .1s; font-family: inherit;
}
.chip:hover { border-color: hsl(var(--accent)); transform: translateY(-1px); }

.msg { display: flex; max-width: 100%; animation: rise .25s ease; }
.msg.user { justify-content: flex-end; }
.msg.user .bubble {
  background: hsl(var(--accent)); color: #fff;
  border-radius: var(--radius) var(--radius) 4px var(--radius);
  max-width: 75%; padding: 12px 16px; white-space: pre-wrap;
}
.msg.ai { justify-content: flex-start; }
.msg.ai .bubble {
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: var(--radius) var(--radius) var(--radius) 4px;
  max-width: 100%; width: 100%; padding: 16px 18px;
  box-shadow: 0 2px 10px rgba(30, 41, 59, 0.05);
}
.bubble { line-height: 1.5; word-break: break-word; overflow-wrap: anywhere; }
.answer { font-size: 1.02rem; line-height: 1.55; margin-bottom: 14px; white-space: pre-wrap;
  overflow-wrap: anywhere; }

.files-tag { font-family: var(--mono); font-size: .72rem; color: hsl(var(--muted-foreground));
  margin-bottom: 10px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.files-tag .pill { background: hsl(var(--muted) / 0.6); border: 1px solid hsl(var(--border));
  padding: 2px 8px; border-radius: 6px; color: hsl(var(--primary)); }

.sql-block { position: relative; margin: 4px 0 14px; }
.sql-block > summary { cursor: pointer; list-style: none; font-family: var(--mono);
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: hsl(var(--muted-foreground)); padding: 6px 0; }
.sql-block > summary::-webkit-details-marker { display: none; }
.sql-block > summary::before { content: "▸ "; color: hsl(var(--accent)); }
.sql-block[open] > summary::before { content: "▾ "; }
.sql-block pre {
  background: #0f172a; border-radius: 10px; padding: 14px 16px; overflow-x: auto;
  font-family: var(--mono); font-size: .82rem; color: #c7e6e2; border-left: 3px solid hsl(var(--accent));
}
.copy-btn { position: absolute; top: 30px; right: 10px; background: #1e293b; border: 1px solid #334155;
  color: #94a3b8; font-size: .7rem; padding: 4px 9px; border-radius: 6px; cursor: pointer; z-index: 2; }
.copy-btn:hover { color: #fff; }

.table-wrap { border: 1px solid hsl(var(--border)); border-radius: 10px; overflow: auto; max-height: 420px; }
table { border-collapse: collapse; width: 100%; font-size: .82rem; background: hsl(var(--card)); }
thead th { position: sticky; top: 0; background: hsl(var(--primary)); color: #fff;
  font-family: var(--mono); font-weight: 500; text-align: left; padding: 10px 14px;
  white-space: nowrap; }
tbody td { padding: 9px 14px; border-bottom: 1px solid hsl(var(--border)); white-space: nowrap; }
tbody tr:nth-child(even) { background: hsl(var(--muted) / 0.3); }
tbody tr:hover { background: hsl(var(--primary) / 0.07); }
td.null { color: hsl(var(--muted-foreground)); font-style: italic; }

.meta { font-size: .76rem; color: hsl(var(--muted-foreground)); margin-top: 10px; }
.error { border-left: 3px solid hsl(var(--danger)); background: hsl(var(--danger) / 0.08);
  padding: 12px 14px; border-radius: 8px; color: hsl(var(--danger)); font-size: .88rem; white-space: pre-wrap; }

.thinking { display: flex; align-items: center; gap: 8px; color: hsl(var(--muted-foreground)); }
.thinking .ball { width: 7px; height: 7px; border-radius: 50%; background: hsl(var(--accent)); animation: blink 1.2s infinite ease-in-out; }
.thinking .ball:nth-child(2) { animation-delay: .2s; }
.thinking .ball:nth-child(3) { animation-delay: .4s; }
@keyframes blink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }

.composer { display: flex; gap: 10px; align-items: flex-end; padding: 16px 22px 20px;
  border-top: 1px solid hsl(var(--border)); background: hsl(var(--card)); }
:is(#input, [id^="input_"]) { flex: 1; resize: none; background: #fff; border: 1px solid hsl(var(--input));
  border-radius: 12px; color: hsl(var(--foreground)); font-family: inherit; font-size: .95rem;
  padding: 13px 16px; max-height: 160px; line-height: 1.4; outline: none; transition: border-color .2s; }
:is(#input, [id^="input_"]):focus { border-color: hsl(var(--accent)); }
:is(#input, [id^="input_"]):disabled { opacity: .6; cursor: not-allowed; background: hsl(var(--muted) / 0.4); }
:is(#send, [id^="send_"]) { background: hsl(var(--accent)); color: #fff; border: none; width: 46px; height: 46px;
  border-radius: 12px; cursor: pointer; display: grid; place-items: center; flex-shrink: 0;
  transition: transform .1s, opacity .2s; }
:is(#send, [id^="send_"]):hover { transform: translateY(-1px); }
:is(#send, [id^="send_"]):disabled { opacity: .4; cursor: not-allowed; transform: none; }

/* ----- Vista de datos directos (grid) ------------------------------------ */
.data-head { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 14px 22px 10px; }
.data-head h3 { font-size: 1.15rem; font-weight: 700; }
.data-count { font-size: .8rem; color: hsl(var(--muted-foreground)); }
.data-scroll {
  flex: 1; min-height: 0; min-width: 0;
  display: flex; flex-direction: column;
  padding: 0 22px 22px;
}
.data-placeholder, .data-loading { color: hsl(var(--muted-foreground)); padding: 40px; text-align: center; }
.data-table-wrap {
  flex: 1; min-height: 0; max-width: 100%;
  overflow: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid hsl(var(--border)); border-radius: var(--radius);
  background: hsl(var(--card)); box-shadow: 0 2px 12px rgba(30, 41, 59, 0.06);
}
.data-table { border-collapse: collapse; width: 100%; font-size: .85rem; }
.data-table thead th { position: sticky; top: 0; background: hsl(var(--primary)); color: #fff;
  text-align: left; padding: 11px 16px; font-weight: 600; white-space: nowrap; }
.data-table tbody td { padding: 10px 16px; border-top: 1px solid hsl(var(--border)); white-space: nowrap; }
.data-table tbody tr:nth-child(even) { background: hsl(var(--muted) / 0.3); }
.data-table tbody tr:hover { background: hsl(var(--primary) / 0.07); }

/* ----- Maestro-Detalle: dos paneles apilados ----------------------------- */
.data-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* openTab() sufija los id al clonar la plantilla (grid-detalles_data_facturas_venta), así
   que el selector por id pelado NUNCA llegaba a aplicarse y el panel se quedaba sin su
   separador. Misma convención :is(#x, [id^="x_"]) que ya se usa más arriba en el fichero. */
:is(#grid-detalles, [id^="grid-detalles_"]) { border-top: 2px solid hsl(var(--border)); }
.data-table tbody tr.fila-doc { cursor: pointer; }
.data-table tbody tr.fila-sel,
.data-table tbody tr.fila-sel:hover {
  background: hsl(var(--primary) / 0.16);
  box-shadow: inset 3px 0 0 hsl(var(--primary));
}
.detalle-close { width: auto; margin: 0 0 0 auto; text-decoration: none; }
.detalle-close:hover { background: hsl(var(--muted) / 0.5); }
/* El ✕ y la palabra «Cerrar» son dos spans para poder dejar solo el ✕ en móvil. En
   escritorio se leen juntos, exactamente como antes. */
.detalle-close-ico { margin-right: 4px; }
/* Fondo de la hoja de detalle: inerte en escritorio, solo se activa en el bloque de
   ≤640px (espeja a .sidebar-backdrop, que sigue el mismo esquema). */
.detalle-backdrop { display: none; }

/* ----- Ficha de cabecera del documento activo ----------------------------
   Datos generales (fecha, cliente/proveedor, NIF, bases, IVA, total) del MISMO
   documento cuyas líneas se ven debajo: los dos salen de una sola respuesta de
   /api/documentos/{tipo}/{rig}/ficha. `flex: 0 0 auto` para que no le robe alto al
   scroll de las líneas, ni aquí ni en la hoja de móvil. Los campos que la vista no
   expone se omiten en JS, así que la rejilla se adapta sola a ventas y a compras. */
.doc-cabecera {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 10px 20px;
  padding: 12px 16px;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--muted) / 0.3);
}
.doc-cab-campo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Título y dirección son textos largos: ocupan toda la fila cuando hay sitio. */
.doc-cab-campo.ancho { grid-column: 1 / -1; }
.doc-cab-campo.num { text-align: right; }
.doc-cab-etq {
  font-size: 0.72rem; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: hsl(var(--muted-foreground));
}
/* Los valores SÍ se parten (a diferencia de las celdas de tabla): un nombre comercial
   o una dirección larga no deben desbordar la ficha ni forzar scroll horizontal. */
.doc-cab-val {
  font-size: 0.92rem; color: hsl(var(--foreground));
  overflow-wrap: anywhere;
}
.doc-cab-campo.num .doc-cab-val { font-variant-numeric: tabular-nums; }
.doc-cab-campo.destacado .doc-cab-val {
  font-size: 1.05rem; font-weight: 700; color: hsl(var(--primary));
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: hsl(var(--muted)); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: hsl(var(--muted-foreground) / 0.5); }

/* ----- Responsive / Mobile-first -----------------------------------------
   BREAKPOINTS CANÓNICOS del proyecto (usar solo estos, de mayor a menor):
     1100px = desktop pequeño   ·   820px = tablet
      640px = móvil grande      ·   480px = móvil
   El visor de documentos (.docs-view) usa el mismo canon (640) desde M1.
   -------------------------------------------------------------------------- */

/* Hamburger span — base para animación */
.hamburger span { transition: transform .25s ease, opacity .2s; }

@media (max-width: 820px) {
  .hamburger { display: flex; }
  .sidebar {
    position: fixed; top: 0; left: 0; height: 100vh; height: 100dvh;
    width: min(240px, 84vw);
    overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
    transform: translateX(-100%);
    transition: transform .25s ease; box-shadow: 0 0 40px rgba(0, 0, 0, 0.35);
    z-index: 1000;
  }
  .shell.sidebar-open .sidebar { transform: translateX(0); }
  .sidebar-backdrop { display: none; }
  .shell.sidebar-open .sidebar-backdrop {
    display: block; position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.45); z-index: 999;
  }

  /* Hamburger → X cuando el sidebar está abierto */
  .shell.sidebar-open .hamburger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
  .shell.sidebar-open .hamburger span:nth-child(2) { opacity: 0; transform: scaleX(0); }
  .shell.sidebar-open .hamburger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

  .msg.user .bubble { max-width: 88%; }
  .chat, .composer, .data-scroll { padding-left: 14px; padding-right: 14px; }
  .composer { padding-bottom: calc(20px + env(safe-area-inset-bottom)); }
  .topbar { padding: 12px 16px; }
  .modebar { padding: 10px 16px; }
}

@media (max-width: 640px) {
  .tab { min-width: 120px; max-width: 160px; padding: 8px 10px; font-size: 0.8rem; }
  .data-head { padding: 12px 14px 8px; gap: 8px; }
  .data-head h3 { font-size: 1rem; }
  .table-controls { width: 100%; }
  .table-search { min-width: 0; flex: 1; }
}

/* M3 — Evita el zoom automático de iOS al enfocar: los controles de formulario
   deben tener font-size >= 16px. Afecta SOLO a input/select/textarea (no toca
   botones, pestañas, etiquetas ni elementos visuales). La especificidad de estos
   selectores gana a las reglas por clase/elemento sin necesidad de !important. */
@media (max-width: 640px) {
  input:not([type="checkbox"]):not([type="radio"]),
  select:not([multiple]),
  textarea { font-size: 16px; }
  /* El input del chat usa selector por id (mayor especificidad) → override puntual. */
  :is(#input, [id^="input_"]) { font-size: 16px; }
}

/* ----- M4 — Rejillas en pantallas estrechas: la tabla pasa a TARJETAS ----------
   Una tarjeta por fila, con la etiqueta de la columna (data-col) a la izquierda y el
   valor a la derecha. El corte SUBE de 480 a 640px, el "móvil grande" del canon de
   arriba y el mismo BP_MOVIL que usa anclaje.js: entre 481 y 640px la tabla seguía
   siendo tabla con white-space:nowrap y se apelotonaba en móviles apaisados y tablets
   pequeñas. Por encima de 640px NO cambia absolutamente nada (escritorio intacto).

   Alcanza a la vez cabeceras, líneas de detalle, maestro-detalle y Extractos, porque
   todo el ERP pinta sus tablas con el mismo buildDataTable(). ------------------- */
@media (max-width: 640px) {
  .data-table thead { display: none; }
  .data-table tbody tr {
    display: block;
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius);
    margin-bottom: 10px;
    padding: 10px 12px;
    background: hsl(var(--card));
    box-shadow: 0 1px 6px rgba(30,41,59,.06);
  }
  /* El zebrado de la vista tabla no tiene sentido con tarjetas ya separadas por borde y
     sombra: sin esto, la regla de :nth-child(even) (más específica) las pintaba a dos
     tonos y parecía un fallo. */
  .data-table tbody tr:nth-child(even) { background: hsl(var(--card)); }
  .data-table tbody td {
    display: flex; justify-content: space-between; align-items: flex-start;
    padding: 6px 0; border-top: none;
    border-bottom: 1px solid hsl(var(--border) / 0.5);
    font-size: 0.875rem; white-space: normal;
    gap: 10px;
  }
  .data-table tbody td::before {
    content: attr(data-col);
    font-weight: 600; font-size: 0.75rem; color: hsl(var(--muted-foreground));
    flex-shrink: 0; max-width: 45%; line-height: 1.5;
    text-transform: uppercase; letter-spacing: .04em;
  }
  /* LA regla anti-solapamiento. El valor iba suelto como texto y era un ítem flex
     anónimo con min-width:auto → no podía encogerse por debajo de su min-content y se
     salía por encima de la etiqueta. Envuelto en .cell-val (lo hace buildDataTable) sí
     puede encoger y partir palabras largas. */
  .data-table tbody td .cell-val {
    flex: 1; min-width: 0; text-align: right;
    overflow-wrap: anywhere; word-break: break-word;
  }
  /* Textos largos (TITULO de una línea es VARCHAR(60)): etiqueta arriba y valor debajo a
     todo el ancho, en vez de disputarse el hueco en la misma línea. */
  .data-table tbody td[data-col="TITULO"],
  .data-table tbody td[data-col="TEXTO"],
  .data-table tbody td[data-col="NOMBRE_COMERCIAL"],
  .data-table tbody td[data-col="NOMBRE_R_SOCIAL"] {
    flex-direction: column; align-items: stretch; gap: 2px;
  }
  .data-table tbody td[data-col="TITULO"] .cell-val,
  .data-table tbody td[data-col="TEXTO"] .cell-val,
  .data-table tbody td[data-col="NOMBRE_COMERCIAL"] .cell-val,
  .data-table tbody td[data-col="NOMBRE_R_SOCIAL"] .cell-val { text-align: left; }
  .data-table tbody td:last-child { border-bottom: none; }
  .data-table tbody td.col-acciones {
    justify-content: flex-end; gap: 8px; padding-top: 8px;
  }
  .data-table tbody td.col-acciones::before { display: none; }
  /* Mantener sticky header en modo tabla (> 640px) */
  .data-table { min-width: unset; }
}

/* ----- M5 — El detalle, en móvil, es una HOJA SUPERPUESTA ---------------------
   En escritorio el maestro-detalle son dos paneles apilados y funciona bien. En un
   móvil los dos layouts se peleaban por la misma pantalla: textos pisados, la tabla de
   fondo asomando y dos scrolls anidados. No es un problema de ancho sino de interacción,
   así que a ≤640px el detalle deja de ser "un panel al lado" y pasa a ser "una pantalla
   encima": hoja inferior a ancho completo, fondo bloqueado y scroll propio.

   NO se crea un panel nuevo: es el MISMO #grid-detalles, con su mismo contenido y su
   misma lógica (cargarFichaDocumento / cargarDetalleMaestro), solo re-presentado. Por eso vale a
   la vez para los 7 documentos de compra/venta y para el maestro-detalle genérico
   (Terceros→Direcciones, Diario→Apuntes), sin una sola bifurcación en JS.

   Sacar la hoja del flujo con position:fixed tiene un efecto secundario deseado: como
   el reparto 50/50 lo producía `.data-panel { flex: 1 }`, el listado recupera el 100%
   del alto automáticamente, sin necesidad de ninguna regla para él.

   Reutiliza los tokens de hoja que ya existen en el proyecto: @keyframes slideUp, el asa
   ::before del modal CRUD y env(safe-area-inset-bottom).  -------------------------- */
@keyframes detalleFondoEntra { from { opacity: 0; } to { opacity: 1; } }

@media (max-width: 640px) {
  /* Fondo bloqueado: impide tocar el listado mientras la hoja está abierta. */
  .view.detalle-abierto .detalle-backdrop {
    display: block;
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.5);
    z-index: var(--z-hoja-detalle);
    animation: detalleFondoEntra .2s ease;
  }

  /* La hoja. `position: fixed` escapa del overflow:hidden de .views-container — es la
     misma técnica que .panel-anclado y depende de que ningún ancestro cree bloque
     contenedor (ver el aviso junto a .views-container). */
  :is(#grid-detalles, [id^="grid-detalles_"]) {
    position: fixed; inset: auto 0 0 0;
    z-index: calc(var(--z-hoja-detalle) + 1);
    height: 80vh; height: 80dvh;          /* dvh por la barra de direcciones, como .shell */
    background: hsl(var(--card));
    border-top: none;                      /* el separador es cosa del panel de escritorio */
    border-radius: 20px 20px 0 0;
    box-shadow: 0 -8px 30px rgba(30, 41, 59, 0.18);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    overflow: hidden;                      /* recorta el contenido a las esquinas curvas */
    animation: slideUp .28s cubic-bezier(.34, 1.56, .64, 1);
  }

  /* Cabecera fija tipo app: asa de arrastre, título que puede fluir y ✕ de 44px. */
  :is(#grid-detalles, [id^="grid-detalles_"]) .data-head {
    position: relative; flex-shrink: 0;
    padding: 24px 14px 10px;
    border-bottom: 1px solid hsl(var(--border));
  }
  :is(#grid-detalles, [id^="grid-detalles_"]) .data-head::before {
    content: ''; display: block; position: absolute;
    top: 10px; left: 50%; transform: translateX(-50%);
    width: 36px; height: 4px;
    background: hsl(var(--muted)); border-radius: 2px;
  }
  :is(#grid-detalles, [id^="grid-detalles_"]) .data-head h3 {
    flex: 1 1 auto; min-width: 0;
    white-space: normal; line-height: 1.3; font-size: 1rem;
  }
  /* El contador baja a una segunda línea (basis 100%) y deja la primera al título + ✕. */
  :is(#grid-detalles, [id^="grid-detalles_"]) .data-count { flex: 1 1 100%; order: 3; }
  :is(#grid-detalles, [id^="grid-detalles_"]) .detalle-close {
    order: 2; flex: 0 0 auto; margin: 0;
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; font-size: 1.05rem;
  }
  .detalle-close-ico { margin-right: 0; }
  .detalle-close-txt { display: none; }

  /* La ficha de cabecera no se estira ni scrollea: en 80dvh el alto es para las líneas.
     Dos columnas fijas (en un móvil `auto-fit` con minmax 170px daría una sola y la
     ficha se comería media hoja); los campos anchos siguen ocupando la fila entera. */
  :is(#grid-detalles, [id^="grid-detalles_"]) .doc-cabecera {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px 12px;
    padding: 10px 14px;
  }

  /* Scroll propio. `overscroll-behavior: contain` evita que al llegar al final de las
     líneas el gesto siga arrastrando el listado que hay detrás. */
  :is(#grid-detalles, [id^="grid-detalles_"]) .data-scroll {
    padding: 12px 14px 14px;
    overscroll-behavior: contain;
  }
}
/* ----- Formularios CRUD (vista de alta) ---------------------------------- */
.form-wrap { padding: 24px; max-width: 560px; overflow-y: auto; flex: 1; min-height: 0; }
.crud-form { display: flex; flex-direction: column; gap: 16px; }
.campo { display: flex; flex-direction: column; gap: 6px; }
.campo > span { font-size: 0.9rem; font-weight: 600; color: hsl(var(--foreground)); }
.campo > span em { color: #c0392b; font-style: normal; }
.campo input[type="text"], .campo input[type="number"], .campo select {
  padding: 11px 12px; border: 1px solid hsl(var(--border)); border-radius: 10px;
  font-size: 1rem; background: hsl(var(--card)); color: hsl(var(--foreground));
}
.campo input:focus, .campo select:focus {
  outline: none; border-color: hsl(var(--primary)); box-shadow: 0 0 0 3px hsl(var(--primary) / 0.15);
}
.campo small { color: hsl(var(--muted-foreground)); font-size: 0.8rem; }
.campo-check { flex-direction: row; align-items: center; gap: 10px; }
.campo-check input { width: 18px; height: 18px; }
.campo-check span { font-weight: 600; font-size: 0.9rem; }
.form-actions { margin-top: 4px; }
.form-msg { padding: 12px 14px; border-radius: 10px; font-size: 0.92rem; margin: 0; }
.form-ok { background: hsl(140 50% 95%); color: hsl(140 60% 25%); border: 1px solid hsl(140 40% 75%); }
.form-error { background: hsl(0 70% 96%); color: hsl(0 60% 38%); border: 1px solid hsl(0 60% 82%); }


/* ----- Buscador y paginación de tablas ----------------------------------- */
.table-search {
  margin-left: auto; min-width: 200px; max-width: 320px;
  padding: 8px 12px; border: 1px solid hsl(var(--border)); border-radius: 10px;
  font-size: 0.9rem; background: hsl(var(--card)); color: hsl(var(--foreground));
}
.table-search:focus { outline: none; border-color: hsl(var(--primary));
  box-shadow: 0 0 0 3px hsl(var(--primary) / 0.15); }
.page-size-select {
  padding: 8px 10px; border: 1px solid hsl(var(--border)); border-radius: 10px;
  font-size: 0.85rem; background: hsl(var(--card)); color: hsl(var(--foreground));
  cursor: pointer; min-height: 36px;
}
.page-size-select:focus { outline: none; border-color: hsl(var(--primary));
  box-shadow: 0 0 0 3px hsl(var(--primary) / 0.15); }

/* Fase 23: desplegables de la barra de herramientas (Ordenar por…, filtro de serie). */
.form-select {
  padding: 8px 10px; border: 1px solid hsl(var(--border)); border-radius: 10px;
  font-size: .85rem; background: hsl(var(--card)); color: hsl(var(--foreground));
  cursor: pointer; min-height: 36px;
}
.form-select:focus { outline: none; border-color: hsl(var(--primary));
  box-shadow: 0 0 0 3px hsl(var(--primary) / 0.15); }
.pagination {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  padding: 10px 16px; border-top: 1px solid hsl(var(--border));
}
.pagination:empty { display: none; }

/* Pie de tabla: botón "Exportar CSV" a la izquierda + paginación a la derecha.
   El borde superior y el padding van en el pie; la paginación (que va dentro)
   los cede para no duplicarlos. */
.data-footer {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
  padding: 10px 16px; border-top: 1px solid hsl(var(--border));
}
.data-footer .pagination { border-top: none; padding: 0; }
.data-footer .btn-outline { white-space: nowrap; }
.pg-btn {
  min-width: 36px; min-height: 36px; padding: 6px 10px; border: 1px solid hsl(var(--border));
  background: hsl(var(--card)); color: hsl(var(--foreground));
  border-radius: 8px; cursor: pointer; font-size: 0.88rem;
  transition: background .15s, transform .1s;
}
.pg-btn:hover:not(:disabled):not(.pg-activa) { background: hsl(var(--muted) / 0.5); transform: translateY(-1px); }
.pg-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.pg-activa { background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  border-color: hsl(var(--primary)); font-weight: 600; }
.pg-sep { padding: 0 4px; color: hsl(var(--muted-foreground)); }


  /* Todas las clases van scopeadas bajo .docs-view para no pisar el ERP.
   Hereda las variables del ERP; aquí solo se añaden las que el escáner usa y
   el ERP no tiene, en valores de tema CLARO.
   ========================================================================== */
.docs-view {
  --secondary: 240 5% 96%;
  --secondary-foreground: 240 21% 15%;
  --accent-foreground: 0 0% 100%;
  --destructive: 0 72% 51%;
  --destructive-foreground: 0 0% 100%;
  --ring: 208 88% 22%;
  --success: 142 71% 38%;
  --success-foreground: 0 0% 100%;
  --warning: 38 92% 50%;
  --warning-foreground: 0 0% 12%;
  --info: 208 88% 40%;
  --popover: 0 0% 100%;
  --popover-foreground: 240 21% 15%;
}
/* Dark mode del módulo: el dark del ERP (:root[data-theme="dark"]) solo redefine sus
   propios tokens y no toca .docs-view, así que aquí reasignamos los tokens que el módulo
   añade y aclaramos los textos hardcodeados de badges/avisos/NIF para que sean legibles
   sobre fondo oscuro. Mismo patrón que styles.css:33-50: solo tokens/colores, sin layout. */
:root[data-theme="dark"] .docs-view {
  --secondary: 222 14% 22%;   --secondary-foreground: 210 20% 92%;
  --popover: 222 16% 15%;     --popover-foreground: 210 20% 92%;
  --success: 142 60% 45%;     --warning: 38 92% 55%;
  --info: 208 90% 62%;        --destructive: 0 70% 55%;   --ring: 208 90% 58%;
}
:root[data-theme="dark"] .docs-view .nif-ok    { color: hsl(142 60% 65%); }
:root[data-theme="dark"] .docs-view .nif-error { color: hsl(0 72% 68%); }
:root[data-theme="dark"] .docs-view .tipo-albaran,
:root[data-theme="dark"] .docs-view .tipo-doc-albaran,
:root[data-theme="dark"] .docs-view .albaran-warning-text strong { color: hsl(38 92% 62%); }
.docs-view, .docs-view * , .docs-view *::before, .docs-view *::after { box-sizing: border-box; }
.docs-view .docs-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 24px; }
/* Los modales van por encima de todo */
.docs-view .modal-overlay { z-index: 2000; }

.docs-view /* ── Modal Overlay ──────────────────────────────────────────────────────── */
.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 50;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(4px);
}
.docs-view .modal-overlay.active { display: flex; }
.docs-view /* ── Card ───────────────────────────────────────────────────────────────── */
.card {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  overflow: hidden;
  animation: fadeIn 0.2s ease-out;
}
/* Tarjetas dentro de un modal (Tipo factura / SOLID / Albarán): limitar alto y
   permitir scroll interno para que no se corten en viewports bajos. */
.docs-view .modal-overlay .card {
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}
.docs-view .modal-overlay .card-content {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1;
  min-height: 0;
}
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.docs-view .card-header {
  padding: 24px 24px 0;
}
.docs-view .card-title {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: hsl(var(--foreground));
  display: flex;
  align-items: center;
  gap: 10px;
}
.docs-view .card-description {
  font-size: 0.875rem;
  color: hsl(var(--muted-foreground));
  margin-top: 4px;
}
.docs-view .card-content {
  padding: 24px;
}
.docs-view .card-footer {
  padding: 0 24px 24px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.docs-view /* ── Login Card ─────────────────────────────────────────────────────────── */
.login-card {
  width: 100%;
  max-width: 400px;
}
.docs-view .login-card .card-header {
  text-align: center;
  padding: 32px 24px 0;
}
.docs-view .login-card .card-title {
  font-size: 1.5rem;
  justify-content: center;
}
.docs-view .login-card .card-description {
  margin-top: 8px;
}
.docs-view .login-icon {
  width: 48px;
  height: 48px;
  margin: 0 auto 16px;
  background: hsl(var(--secondary));
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
}
.docs-view /* ══════════════════════════════════════════════════════════════════════════
   NUEVO: Casilla "Recuérdame"
   ══════════════════════════════════════════════════════════════════════════ */
.remember-me {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}
.docs-view .remember-me input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: hsl(var(--primary));
  cursor: pointer;
}
.docs-view .remember-me label {
  font-size: 0.8rem;
  color: hsl(var(--muted-foreground));
  cursor: pointer;
  font-weight: 400;
}
.docs-view /* ══════════════════════════════════════════════════════════════════════════
   NUEVO: Desplegable de cuentas guardadas
   ══════════════════════════════════════════════════════════════════════════
   Aparece debajo del campo "Usuario" en el login.
   Muestra una lista de cuentas que el usuario guardó con "Recuérdame".
*/

/* Wrapper del campo usuario para que el desplegable se posicione relativo a él */
.form-group-username-wrap {
  position: relative;
}
/* CÓDIGO MUERTO: no hay HTML ni JS que use .saved-accounts-dropdown (resto del login
   del antiguo Pfactura). Se conserva tal cual, pero OJO si algún día se revive: usa el
   viejo patrón de anclar con CSS, que es justo el que se salía de la pantalla en móvil
   (Fase 29). Engánchalo a Anclaje.abrir/cerrar como los otros tres desplegables en vez
   de copiar este `position:absolute`. */
.docs-view .saved-accounts-dropdown {
  display: none;
  position: absolute;
  top: 100%;           /* Justo debajo del campo de texto */
  left: 0;
  right: 0;
  z-index: 100;
  background: hsl(240 6% 8%);
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  margin-top: 4px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  overflow: hidden;
  max-height: 280px;
  overflow-y: auto;
}
.docs-view .saved-accounts-dropdown.visible {
  display: block;
  animation: dropdownFadeIn 0.15s ease-out;
}
@keyframes dropdownFadeIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.docs-view .saved-accounts-header {
  padding: 8px 12px;
  font-size: 0.7rem;
  font-weight: 600;
  color: hsl(var(--muted-foreground));
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid hsl(var(--border));
}
.docs-view .saved-account-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  cursor: pointer;
  transition: background 0.1s;
  border-bottom: 1px solid hsl(var(--border) / 0.5);
}
.docs-view .saved-account-item:last-child {
  border-bottom: none;
}
.docs-view .saved-account-item:hover {
  background: hsl(var(--secondary));
}
.docs-view /* Avatar circular con la inicial del nombre */
.saved-account-avatar {
  width: 34px;
  height: 34px;
  min-width: 34px;
  border-radius: 50%;
  background: hsl(var(--info) / 0.2);
  color: hsl(var(--info));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 600;
}
.docs-view .saved-account-info {
  flex: 1;
  min-width: 0;   /* Para que el text-overflow funcione */
}
.docs-view .saved-account-name {
  font-size: 0.85rem;
  font-weight: 500;
  color: hsl(var(--foreground));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.docs-view .saved-account-user {
  font-size: 0.72rem;
  color: hsl(var(--muted-foreground));
}
.docs-view /* Botón × para eliminar una cuenta del historial */
.saved-account-remove {
  width: 24px;
  height: 24px;
  min-width: 24px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: hsl(var(--muted-foreground));
  font-size: 1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  font-family: inherit;
}
.docs-view .saved-account-remove:hover {
  background: hsl(var(--destructive) / 0.2);
  color: hsl(0 72% 42%);
}
.docs-view /* ══════════════════════════════════════════════════════════════════════════
   NUEVO: Modal de selección de tipo (Acreedor / Proveedor)
   ══════════════════════════════════════════════════════════════════════════ */
.tipo-card {
  width: 100%;
  max-width: 520px;
}
.docs-view .tipo-info {
  font-size: 0.9rem;
  color: hsl(var(--muted-foreground));
  line-height: 1.6;
  margin-bottom: 20px;
  text-align: center;
}
.docs-view .tipo-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.docs-view .tipo-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 24px 16px;
  background: hsl(var(--secondary) / 0.5);
  border: 2px solid hsl(var(--border));
  border-radius: var(--radius);
  cursor: pointer;
  font-family: inherit;
  color: hsl(var(--foreground));
  transition: all 0.2s;
  text-align: center;
}
.docs-view .tipo-option:hover {
  border-color: hsl(var(--ring));
  background: hsl(var(--secondary));
  transform: translateY(-2px);
}
.docs-view .tipo-option-icon {
  font-size: 2rem;
  margin-bottom: 4px;
}
.docs-view .tipo-option-title {
  font-size: 1rem;
  font-weight: 600;
}
.docs-view .tipo-option-desc {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
  line-height: 1.4;
}
.docs-view /* ══════════════════════════════════════════════════════════════════════════
   NUEVO: Badge de tipo en el modal SOLID
   ══════════════════════════════════════════════════════════════════════════ */
.tipo-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  font-size: 0.7rem;
  font-weight: 600;
  border-radius: 9999px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.docs-view .tipo-proveedor {
  background: hsl(var(--info) / 0.15);
  border: 1px solid hsl(var(--info) / 0.3);
  color: hsl(217 91% 70%);
}
.docs-view .tipo-acreedor {
  background: hsl(280 60% 40% / 0.15);
  border: 1px solid hsl(280 60% 40% / 0.3);
  color: hsl(280 60% 70%);
}
.docs-view .tipo-albaran {
  background: hsl(var(--warning) / 0.15);
  border: 1px solid hsl(var(--warning) / 0.3);
  color: hsl(38 92% 32%);
}
.docs-view /* ══════════════════════════════════════════════════════════════════════════
   NUEVO: Badge de tipo de documento en el editor (Factura / Albarán)
   ══════════════════════════════════════════════════════════════════════════ */
.tipo-doc-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 12px;
  font-size: 0.7rem;
  font-weight: 700;
  border-radius: 9999px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  vertical-align: middle;
  margin-left: 10px;
}
.docs-view .tipo-doc-factura {
  background: hsl(var(--info) / 0.15);
  border: 1px solid hsl(var(--info) / 0.3);
  color: hsl(217 91% 70%);
}
.docs-view .tipo-doc-albaran {
  background: hsl(var(--warning) / 0.15);
  border: 1px solid hsl(var(--warning) / 0.3);
  color: hsl(38 92% 32%);
  animation: albaran-pulse 2s ease-in-out 3;
}
@keyframes albaran-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}
.docs-view /* ══════════════════════════════════════════════════════════════════════════
   NUEVO: Modal de confirmación de albarán
   ══════════════════════════════════════════════════════════════════════════ */
.albaran-card {
  width: 100%;
  max-width: 520px;
}
.docs-view .albaran-warning-box {
  display: flex;
  gap: 14px;
  padding: 16px;
  background: hsl(var(--warning) / 0.08);
  border: 1px solid hsl(var(--warning) / 0.25);
  border-radius: var(--radius);
  margin-bottom: 20px;
  border-left: 4px solid hsl(var(--warning));
}
.docs-view .albaran-warning-icon {
  font-size: 1.6rem;
  flex-shrink: 0;
  line-height: 1;
}
.docs-view .albaran-warning-text {
  font-size: 0.85rem;
  color: hsl(var(--foreground));
  line-height: 1.6;
}
.docs-view .albaran-warning-text strong {
  color: hsl(38 92% 32%);
}
.docs-view .albaran-note {
  font-size: 0.8rem;
  color: hsl(var(--muted-foreground));
  line-height: 1.5;
  margin: 16px 0;
  font-style: italic;
}
.docs-view .btn-albaran {
  background: hsl(var(--warning));
  color: hsl(var(--warning-foreground));
  font-weight: 600;
}
.docs-view .btn-albaran:hover {
  opacity: 0.9;
  background: hsl(38 92% 45%);
}
.docs-view /* ── SOLID Modal ────────────────────────────────────────────────────────── */
.solid-card {
  width: 100%;
  max-width: 480px;
}
.docs-view .solid-info {
  font-size: 0.875rem;
  color: hsl(var(--muted-foreground));
  line-height: 1.6;
  margin-bottom: 20px;
}
.docs-view .solid-config-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
}
.docs-view .solid-warning {
  font-size: 0.8rem;
  color: hsl(var(--warning));
  background: hsl(var(--warning) / 0.1);
  border: 1px solid hsl(var(--warning) / 0.2);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 20px;
  line-height: 1.5;
}
.docs-view .solid-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.docs-view /* ══════════════════════════════════════════════════════════════════════════
   NUEVO: Mensajes de estado del NIF
   ══════════════════════════════════════════════════════════════════════════
   Estos estilos dan formato al mensaje que aparece debajo del campo
   CIF/NIF del emisor. Hay tres estados:
   - .nif-ok       → Verde: el NIF existe en la BD
   - .nif-error    → Rojo: el NIF NO existe en la BD
   - .nif-checking → Gris: verificando...
*/
.nif-status {
  font-size: 0.78rem;
  line-height: 1.4;
  min-height: 0;
  transition: all 0.2s;
  margin-top: 4px;
}
.docs-view .nif-status:empty {
  display: none;
}
.docs-view .nif-ok {
  color: hsl(142 60% 28%);
  padding: 6px 10px;
  background: hsl(var(--success) / 0.08);
  border: 1px solid hsl(var(--success) / 0.2);
  border-radius: calc(var(--radius) - 2px);
}
.docs-view .nif-error {
  color: hsl(0 72% 42%);
  padding: 6px 10px;
  background: hsl(var(--destructive) / 0.08);
  border: 1px solid hsl(var(--destructive) / 0.2);
  border-radius: calc(var(--radius) - 2px);
}
.docs-view .nif-checking {
  color: hsl(var(--muted-foreground));
  padding: 6px 10px;
  background: hsl(var(--secondary) / 0.5);
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) - 2px);
}
.docs-view /* ── Form Controls ──────────────────────────────────────────────────────── */
.form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.docs-view .form-group + .form-group {
  margin-top: 16px;
}
.docs-view label {
  font-size: 0.875rem;
  font-weight: 500;
  color: hsl(var(--foreground));
}
.docs-view input,
.docs-view textarea,
.docs-view select {
  width: 100%;
  padding: 8px 12px;
  font-size: 0.875rem;
  font-family: inherit;
  color: hsl(var(--foreground));
  background: transparent;
  border: 1px solid hsl(var(--input));
  border-radius: calc(var(--radius) - 2px);
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.docs-view input::placeholder,
.docs-view textarea::placeholder {
  color: hsl(var(--muted-foreground));
}
.docs-view input:focus,
.docs-view textarea:focus,
.docs-view select:focus {
  border-color: hsl(var(--ring));
  box-shadow: 0 0 0 2px hsl(var(--ring) / 0.2);
}
.docs-view input:read-only {
  opacity: 0.7;
  cursor: default;
}
.docs-view textarea {
  resize: vertical;
  min-height: 64px;
  line-height: 1.5;
}
.docs-view input[type="file"] { display: none; }
.docs-view /* ── Buttons ────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 16px;
  font-size: 0.875rem;
  font-weight: 500;
  font-family: inherit;
  border-radius: calc(var(--radius) - 2px);
  border: none;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
  white-space: nowrap;
  line-height: 1.25rem;
}
.docs-view .btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.docs-view .btn-primary {
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}
.docs-view .btn-primary:hover:not(:disabled) { opacity: 0.9; }
.docs-view .btn-secondary {
  background: hsl(var(--secondary));
  color: hsl(var(--secondary-foreground));
}
.docs-view .btn-secondary:hover:not(:disabled) { background: hsl(var(--secondary) / 0.8); }
.docs-view .btn-destructive {
  background: hsl(var(--destructive));
  color: hsl(var(--destructive-foreground));
}
.docs-view .btn-destructive:hover:not(:disabled) { opacity: 0.9; }
.docs-view .btn-outline {
  background: transparent;
  color: hsl(var(--foreground));
  border: 1px solid hsl(var(--input));
}
.docs-view .btn-outline:hover:not(:disabled) {
  background: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}
.docs-view .btn-ghost {
  background: transparent;
  color: hsl(var(--foreground));
}
.docs-view .btn-ghost:hover:not(:disabled) {
  background: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}
.docs-view .btn-success {
  background: hsl(var(--success));
  color: hsl(var(--success-foreground));
}
.docs-view .btn-success:hover:not(:disabled) { opacity: 0.9; }
.docs-view .btn-warning {
  background: hsl(var(--warning));
  color: hsl(var(--warning-foreground));
  font-weight: 600;
}
.docs-view .btn-warning:hover:not(:disabled) { opacity: 0.9; }
.docs-view .btn-full { width: 100%; }
.docs-view .btn-lg {
  padding: 10px 20px;
  font-size: 0.925rem;
}
.docs-view .btn-icon {
  padding: 8px;
  width: 36px;
  height: 36px;
}
.docs-view /* ── Alerts ─────────────────────────────────────────────────────────────── */
.alert {
  padding: 12px 16px;
  border-radius: var(--radius);
  font-size: 0.875rem;
  margin-bottom: 16px;
  border: 1px solid;
}
.docs-view .alert-error {
  background: hsl(var(--destructive) / 0.15);
  border-color: hsl(var(--destructive) / 0.3);
  color: hsl(0 72% 42%);
}
.docs-view .alert-warning {
  background: hsl(var(--warning) / 0.1);
  border-color: hsl(var(--warning) / 0.25);
  color: hsl(38 92% 32%);
}
.docs-view .alert-success {
  background: hsl(var(--success) / 0.15);
  border-color: hsl(var(--success) / 0.3);
  color: hsl(142 60% 28%);
}
.docs-view /* ── Spinner ────────────────────────────────────────────────────────────── */
.spinner-wrap {
  display: none;
  justify-content: center;
  padding: 12px 0;
}
.docs-view .spinner-wrap.active { display: flex; }
.docs-view .spinner {
  width: 20px;
  height: 20px;
  border: 2px solid hsl(var(--border));
  border-top-color: hsl(var(--foreground));
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.docs-view .spinner-lg {
  width: 32px;
  height: 32px;
  border-width: 3px;
}
.docs-view .progress {
  height: 2px;
  background: hsl(var(--secondary));
  border-radius: 1px;
  margin-top: 16px;
  overflow: hidden;
}
.docs-view .progress-fill {
  height: 100%;
  background: hsl(var(--destructive));
  border-radius: 1px;
  transition: width 0.3s;
}
.docs-view .text-muted {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
  text-align: center;
  margin-top: 16px;
}
.docs-view /* ── Main Layout ────────────────────────────────────────────────────────── */
.app-container {
  display: none;
  max-width: 1000px;
  margin: 0 auto;
  padding: 24px 16px;
}
.docs-view .app-container.visible { display: block; }
.docs-view /* ── App Header ─────────────────────────────────────────────────────────── */
.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 0;
  margin-bottom: 24px;
  border-bottom: 1px solid hsl(var(--border));
}
.docs-view .app-header-left {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.docs-view .app-header-title {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.025em;
}
.docs-view .app-header-subtitle {
  font-size: 0.8rem;
  color: hsl(var(--muted-foreground));
}
.docs-view .app-header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.docs-view .user-badge {
  font-size: 0.8rem;
  color: hsl(var(--muted-foreground));
  padding: 4px 10px;
  background: hsl(var(--secondary));
  border-radius: calc(var(--radius) - 2px);
}
.docs-view .btn-logout {
  font-size: 0.8rem;
  padding: 4px 12px;
  background: transparent;
  color: hsl(var(--muted-foreground));
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
}
.docs-view .btn-logout:hover {
  background: hsl(var(--destructive) / 0.15);
  border-color: hsl(var(--destructive) / 0.3);
  color: hsl(0 72% 42%);
}
.docs-view /* ── Badge ──────────────────────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  font-size: 0.75rem;
  font-weight: 500;
  border-radius: 9999px;
  border: 1px solid transparent;
}
.docs-view .badge-outline {
  border-color: hsl(var(--border));
  color: hsl(var(--foreground));
}
.docs-view .badge-success {
  background: hsl(var(--success) / 0.15);
  border-color: hsl(var(--success) / 0.3);
  color: hsl(142 60% 28%);
}
.docs-view /* ── Features Section ───────────────────────────────────────────────────── */
.features-card {
  margin-bottom: 24px;
}
.docs-view .features-list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 8px;
}
.docs-view .features-list li {
  font-size: 0.85rem;
  color: hsl(var(--muted-foreground));
  padding: 6px 0 6px 24px;
  position: relative;
  line-height: 1.4;
}
.docs-view .features-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: hsl(var(--success));
  font-weight: 600;
}
.docs-view /* ── Upload Area ────────────────────────────────────────────────────────── */
.upload-area {
  border: 2px dashed hsl(var(--border));
  border-radius: var(--radius);
  padding: 48px 24px;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s;
}
.docs-view .upload-area:hover {
  border-color: hsl(var(--muted-foreground));
  background: hsl(var(--secondary) / 0.5);
}
.docs-view .upload-area.dragover {
  border-color: hsl(var(--ring));
  background: hsl(var(--ring) / 0.05);
}
.docs-view .upload-icon {
  width: 48px;
  height: 48px;
  margin: 0 auto 16px;
  background: hsl(var(--secondary));
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
}
.docs-view .upload-area h3 {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 4px;
}
.docs-view .upload-area p {
  font-size: 0.85rem;
  color: hsl(var(--muted-foreground));
  margin-bottom: 16px;
}
.docs-view /* ── File Info ──────────────────────────────────────────────────────────── */
.file-info {
  display: none;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: 16px;
  margin-top: 16px;
}
.docs-view .file-info.active { display: block; }
.docs-view .file-info p {
  font-size: 0.85rem;
  color: hsl(var(--muted-foreground));
  margin-bottom: 4px;
}
.docs-view .file-info strong {
  color: hsl(var(--foreground));
}
.docs-view .file-info-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.docs-view /* ── Loading ────────────────────────────────────────────────────────────── */
.loading {
  display: none;
  text-align: center;
  padding: 48px 0;
}
.docs-view .loading.active { display: block; }
.docs-view .loading p {
  font-size: 0.875rem;
  color: hsl(var(--muted-foreground));
  margin-top: 12px;
}
.docs-view /* ── Data Editor ────────────────────────────────────────────────────────── */
.data-editor {
  display: none;
  margin-top: 24px;
}
.docs-view .data-editor.active { display: block; }
.docs-view .editor-header {
  margin-bottom: 20px;
}
.docs-view .editor-header h3 {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.025em;
}
.docs-view .editor-header p {
  font-size: 0.85rem;
  color: hsl(var(--muted-foreground));
  margin-top: 4px;
}
.docs-view .form-section {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 16px;
}
.docs-view .form-section-title {
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid hsl(var(--border));
  display: flex;
  align-items: center;
  gap: 8px;
}
.docs-view .form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.docs-view .form-grid .form-group {
  margin-top: 0;
}
.docs-view .form-group-full {
  grid-column: 1 / -1;
}
.docs-view /* NUEVO: Clase para que la descripción ocupe más espacio en las líneas */
.form-group-desc {
  grid-column: span 2;
}
.docs-view /* ── Invoice Lines ──────────────────────────────────────────────────────── */
.line-item {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 8px;
  background: hsl(var(--secondary) / 0.3);
}
.docs-view .line-item-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
.docs-view .line-item-header h5 {
  font-size: 0.85rem;
  font-weight: 600;
  color: hsl(var(--muted-foreground));
}
.docs-view .btn-remove-line {
  font-size: 0.75rem;
  padding: 4px 10px;
  background: hsl(var(--destructive) / 0.15);
  color: hsl(0 72% 42%);
  border: 1px solid hsl(var(--destructive) / 0.2);
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
}
.docs-view .btn-remove-line:hover {
  background: hsl(var(--destructive) / 0.25);
}
.docs-view .btn-add-line {
  font-size: 0.85rem;
  padding: 8px 16px;
  background: transparent;
  color: hsl(var(--success));
  border: 1px dashed hsl(var(--success) / 0.4);
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
  margin-top: 8px;
  transition: all 0.15s;
}
.docs-view .btn-add-line:hover {
  background: hsl(var(--success) / 0.1);
  border-style: solid;
}
.docs-view /* ── Action Buttons ─────────────────────────────────────────────────────── */
.action-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid hsl(var(--border));
}
.docs-view /* ── Results / Preview ──────────────────────────────────────────────────── */
.results {
  display: none;
  margin-top: 24px;
}
.docs-view .results.active { display: block; }
.docs-view .result-tabs {
  display: flex;
  gap: 0;
  margin-bottom: 0;
  border-bottom: 1px solid hsl(var(--border));
}
.docs-view .tab {
  padding: 10px 20px;
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  font-family: inherit;
  border-bottom: 2px solid transparent;
  transition: all 0.15s;
  margin-bottom: -1px;
}
.docs-view .tab.active {
  color: hsl(var(--foreground));
  border-bottom-color: hsl(var(--foreground));
}
.docs-view .tab:hover {
  color: hsl(var(--foreground));
}
.docs-view .tab-content {
  display: none;
  border: 1px solid hsl(var(--border));
  border-top: none;
  border-radius: 0 0 var(--radius) var(--radius);
  padding: 16px;
  max-height: 400px;
  overflow-y: auto;
}
.docs-view .tab-content.active { display: block; }
.docs-view pre {
  background: hsl(240 6% 6%);
  color: hsl(var(--foreground));
  padding: 16px;
  border-radius: calc(var(--radius) - 2px);
  overflow-x: auto;
  font-size: 0.8rem;
  line-height: 1.6;
  font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', 'Consolas', monospace;
  tab-size: 2;
}
.docs-view /* ── Error & Success Messages ───────────────────────────────────────────── */
.message-error {
  background: hsl(var(--destructive) / 0.1);
  color: hsl(0 72% 42%);
  padding: 12px 16px;
  border-radius: var(--radius);
  margin-top: 16px;
  border: 1px solid hsl(var(--destructive) / 0.2);
  font-size: 0.875rem;
}
.docs-view .message-success {
  background: hsl(var(--success) / 0.1);
  color: hsl(142 60% 28%);
  padding: 12px 16px;
  border-radius: var(--radius);
  margin-top: 16px;
  border: 1px solid hsl(var(--success) / 0.2);
  font-size: 0.875rem;
}
.docs-view .preview-banner {
  background: hsl(var(--secondary));
  padding: 12px 16px;
  border-radius: var(--radius);
  margin-bottom: 16px;
  font-size: 0.875rem;
  color: hsl(var(--muted-foreground));
}
.docs-view /* ── Separator ──────────────────────────────────────────────────────────── */
.separator {
  height: 1px;
  background: hsl(var(--border));
  margin: 16px 0;
}
.docs-view /* ── Scrollbar ──────────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
.docs-view ::-webkit-scrollbar-track { background: transparent; }
.docs-view ::-webkit-scrollbar-thumb { background: hsl(var(--border)); border-radius: 3px; }
.docs-view ::-webkit-scrollbar-thumb:hover { background: hsl(var(--muted-foreground)); }
/* ── Responsive del visor (M1: el @media va SIN prefijo; sus reglas se scopean
   con .docs-view, coherente con el resto del bloque). Breakpoint canónico 640. ── */
@media (max-width: 640px) {
  .docs-view .app-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  .docs-view .app-header-right {
    width: 100%;
    justify-content: space-between;
  }
  .docs-view .form-grid {
    grid-template-columns: 1fr;
  }
  /* En móvil, la descripción no ocupa 2 columnas (solo hay 1) */
  .docs-view .form-group-desc {
    grid-column: span 1;
  }
  .docs-view .action-buttons {
    flex-direction: column;
  }
  .docs-view .action-buttons .btn {
    width: 100%;
  }
  .docs-view .solid-config-grid {
    grid-template-columns: 1fr;
  }
  .docs-view .features-list {
    grid-template-columns: 1fr;
  }
  /* Modal de tipo: una columna en móvil */
  .docs-view .tipo-options {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   FASE 4: SISTEMA DE PESTAÑAS (BROWSER-LIKE)
   ========================================================================== */
.tab-bar {
  display: flex;
  background: hsl(var(--muted) / 0.5);
  border-bottom: 1px solid hsl(var(--border));
  padding: 8px 8px 0 8px;
  overflow-x: auto;
  scrollbar-width: none; /* Oculta scrollbar en Firefox */
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x;
  gap: 4px;
  min-height: 42px;
}
.tab-bar::-webkit-scrollbar { display: none; } /* Oculta scrollbar en Chrome */

.tab {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  background: hsl(var(--muted));
  border: 1px solid hsl(var(--border));
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  transition: background-color 0.2s;
  min-width: 140px;
  max-width: 220px;
  user-select: none;
  position: relative;
}

.tab:hover { background: hsl(var(--border)); }

.tab.active {
  background: hsl(var(--card));
  color: hsl(var(--foreground));
  border-color: hsl(var(--border));
  z-index: 10;
  box-shadow: 0 -2px 8px rgba(30,41,59,.06);
}

.tab.active::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  right: 0;
  height: 2px;
  background: hsl(var(--card)); /* Solapa el borde inferior para efecto de fusión */
}

.tab-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.tab-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: hsl(var(--muted-foreground));
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  margin: -8px -10px -8px 0;
  flex-shrink: 0;
  transition: background .15s, color .1s;
}
.tab-close:hover {
  background: hsl(var(--danger));
  color: #fff;
}

/* OJO (Fase 29): NO añadas transform/filter/perspective/contain/will-change a
   .views-container ni a .view-instance. Crearían un bloque contenedor y los paneles
   desplegables (.panel-anclado), que son position:fixed para escapar del overflow:hidden
   de aquí abajo, dejarían de posicionarse contra el viewport y aparecerían descolocados.
   anclaje.js avisa por consola si detecta un ancestro así.
   M5: la hoja de detalle de móvil (#grid-detalles a ≤640px) depende de lo MISMO, y esa
   sí no tiene aviso automático: se quedaría recortada dentro del panel en vez de cubrir
   la pantalla. Son dos motivos independientes para no tocar esto. */
.views-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  background: hsl(var(--card));
}

/* La vista clonada ocupa todo el espacio absoluto */
.view-instance {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ============================================================================
   FASE 29 — PANELES ANCLADOS A UN BOTÓN (patrón común)
   Lo comparten el menú "Acciones", el selector de columnas y el menú de usuario.
   Antes cada uno se anclaba por su cuenta con `position:absolute; right:0`, que da
   por hecho que el botón está pegado al borde derecho; cuando dejaba de ser cierto
   (móvil), el panel se salía de la pantalla y el overflow:hidden de la vista lo
   amputaba. Ahora la posición la MIDE anclaje.js.

   `fixed` no es un capricho: es lo que saca al panel del overflow:hidden de
   .views-container/.view-instance. top/left/max-* los escribe el JS.
   ============================================================================ */
.panel-anclado {
  position: fixed;
  top: 0; left: 0; right: auto; bottom: auto;
  margin: 0;
  z-index: var(--z-panel-anclado);
  overflow-y: auto;
  overscroll-behavior: contain;  /* al llegar al final no arrastra la página de detrás */
}

/* Presentación en móvil (≤640px) de los paneles de la barra de herramientas: hoja
   inferior a ancho completo. No es un capricho estético: al ancho de un teléfono, un
   panel anclado a un botón cabe pero queda diminuto y lejos del pulgar. Hereda los
   valores que .column-popover ya usaba, y el mismo @keyframes slideUp que los modales. */
.panel-anclado--hoja {
  inset: auto 0 0 0 !important;
  width: 100%;
  max-width: none !important;
  max-height: 70vh !important;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 30px rgba(30, 41, 59, .15);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  animation: slideUp .25s ease;
}

/* ==========================================================================
   FASE 4: COLUMN CHOOSER (SELECTOR DINÁMICO)
   ========================================================================== */
.table-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-left: auto; /* Empuja los controles a la derecha */
}

/* Sin `position: relative`: existía solo para anclar el popover cuando era `absolute`.
   Ahora es `fixed` y lo coloca anclaje.js contra el viewport. */
.column-chooser-container {
  display: inline-flex;
}

.btn-outline {
  background: white;
  border: 1px solid #cbd5e1;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 500;
  color: #334155;
  cursor: pointer;
  display: flex;
  align-items: center;
  min-height: 36px;
  transition: background .15s, box-shadow .15s;
}
.btn-outline:hover { background: #f1f5f9; box-shadow: 0 2px 8px rgba(30,41,59,.08); }

/* La posición la pone anclaje.js (.panel-anclado): aquí solo el aspecto. */
.column-popover {
  background: white;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
  width: 240px;
  display: flex;
  flex-direction: column;
}

.column-popover-header {
  padding: 10px 14px;
  font-weight: 600;
  border-bottom: 1px solid #e2e8f0;
  background: #f8fafc;
  border-radius: 8px 8px 0 0;
  font-size: 0.85rem;
  color: #0f172a;
}

.column-list {
  max-height: 250px;
  overflow-y: auto;
  padding: 8px 0;
}

.column-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  cursor: pointer;
  font-size: 0.85rem;
  color: #334155;
}
.column-item:hover { background: #f1f5f9; }
.column-item input[type="checkbox"] { cursor: pointer; }
.column-item input[type="checkbox"]:disabled { opacity: 0.4; cursor: not-allowed; }
.column-item:has(input:disabled) { opacity: 0.5; pointer-events: none; }

/* La hoja inferior de móvil que este popover tenía en exclusiva es ahora el modo
   compartido .panel-anclado--hoja (Fase 29): la usan también el menú "Acciones" y
   cualquier desplegable futuro. Aquí solo queda lo específico: sin el tope de 250px
   de la lista, es la hoja la que manda la altura y hace el scroll. */
.panel-anclado--hoja .column-list { max-height: none; }

.column-master-row {
  padding: 8px 14px 6px;
  border-bottom: 1px solid #f1f5f9;
}
.column-master-label {
  display: flex; align-items: center; gap: 10px;
  font-size: 0.85rem; font-weight: 600; color: #0f172a; cursor: pointer;
}
.col-master-toggle { cursor: pointer; width: 15px; height: 15px; accent-color: hsl(var(--primary)); }
.column-popover-divider { height: 1px; background: #e2e8f0; margin: 2px 0; }

/* ==========================================================================
   FASE 5: BOTÓN NUEVO Y ACCIONES DE FILA
   ========================================================================== */
.btn-new-row {
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  border: none; border-radius: 8px; padding: 10px 16px;
  font-size: 0.85rem; font-weight: 600; font-family: inherit;
  cursor: pointer; white-space: nowrap; flex-shrink: 0;
  transition: opacity .15s, transform .1s;
}
.btn-new-row:hover { opacity: 0.88; transform: translateY(-1px); }

.col-acciones { white-space: nowrap; width: 80px; text-align: center; }
th.col-acciones { width: 80px; text-align: center; }

/* Columnas numéricas del detalle (Debe/Haber, importes): alineadas a la derecha. */
.data-table td.num, .data-table th.num { text-align: right; font-variant-numeric: tabular-nums; }

.btn-row-edit, .btn-row-del {
  background: transparent; border: none; cursor: pointer;
  font-size: 1rem; padding: 10px 12px; border-radius: 5px; line-height: 1;
  min-width: 40px; min-height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s;
}
.btn-row-edit:hover { background: hsl(var(--primary) / 0.1); }
.btn-row-del:hover  { background: hsl(var(--danger) / 0.12); }

/* ==========================================================================
   FASE 5: MODAL GENÉRICO CRUD
   ========================================================================== */
.modal-crud-overlay {
  position: fixed; inset: 0; z-index: 500;
  background: rgba(15, 23, 42, 0.55); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.modal-crud-box {
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: var(--radius); box-shadow: 0 20px 50px rgba(30,41,59,.18);
  width: 100%; max-width: 520px; max-height: 85vh;
  display: flex; flex-direction: column; animation: rise .25s ease;
}
.modal-crud-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 22px; border-bottom: 1px solid hsl(var(--border));
  flex-shrink: 0;
}
.modal-crud-header h3 { font-size: 1rem; font-weight: 700; }
.modal-crud-close {
  background: none; border: none; font-size: 1.1rem; cursor: pointer;
  color: hsl(var(--muted-foreground)); border-radius: 6px; padding: 10px;
  min-width: 36px; min-height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
}
.modal-crud-close:hover { background: hsl(var(--muted) / .5); }
.modal-crud-body { padding: 20px 22px; overflow-y: auto; flex: 1; }
.crud-dyn-form { display: flex; flex-direction: column; gap: 14px; }
.crud-dyn-field { display: flex; flex-direction: column; gap: 5px; }
.crud-dyn-field label {
  font-size: 0.76rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: hsl(var(--muted-foreground));
}
.crud-dyn-field input {
  padding: 10px 12px; border: 1px solid hsl(var(--border)); border-radius: 9px;
  font-size: .93rem; background: hsl(var(--card)); color: hsl(var(--foreground));
  font-family: inherit; outline: none; transition: border-color .2s;
}
.crud-dyn-field input:focus {
  border-color: hsl(var(--primary)); box-shadow: 0 0 0 3px hsl(var(--primary) / .12);
}
.modal-crud-actions { display: flex; gap: 10px; margin-top: 6px; align-items: center; }
.modal-crud-actions .btn-primary { width: auto; min-width: 120px; padding: 11px 20px; font-size: 0.9rem; }
.modal-crud-actions .btn-link { width: auto; margin-top: 0; font-size: 0.88rem; }

@keyframes slideUp {
  from { transform: translateY(100%); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

@media (max-width: 640px) {
  .modal-crud-overlay { align-items: flex-end; padding: 0; }
  .modal-crud-box {
    max-width: 100%;
    border-radius: 20px 20px 0 0;
    max-height: 92vh;
    animation: slideUp .3s cubic-bezier(.34,1.56,.64,1);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .modal-crud-header { position: relative; padding-top: 24px; }
  .modal-crud-header::before {
    content: ''; display: block; position: absolute;
    top: 10px; left: 50%; transform: translateX(-50%);
    width: 36px; height: 4px;
    background: hsl(var(--muted)); border-radius: 2px;
  }
}

/* ============================================================================
   MENÚ DE ACCIONES SOBRE DOCUMENTOS (Fase 26 — dropdown escalable)
   Deriva del patrón .user-dropdown-menu / .user-dropdown-item, con las variables
   de tema del ERP para encajar visualmente. Dentro de la vista clonada view-data.
   ============================================================================ */
.doc-actions-container { display: inline-flex; }
/* La posición la pone anclaje.js (.panel-anclado): aquí solo el aspecto. El antiguo
   `right: 0` era la causa del menú que se salía por la izquierda en móvil, y el
   `max-width: calc(100vw - 24px)` que lo acompañaba no servía de nada: limitaba el
   ancho pero nunca movía la caja. Ahora el ancho lo acota el helper. */
.doc-actions-menu {
  min-width: 220px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: 12px; box-shadow: 0 12px 32px rgba(0, 0, 0, .22);
}
.doc-actions-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  text-align: left; padding: 10px 12px; border: none; border-radius: 8px;
  cursor: pointer; background: transparent; color: hsl(var(--foreground));
  font-size: .9rem; font-family: inherit;
}
.doc-actions-item:hover { background: hsl(var(--muted) / .7); }
.doc-actions-icon { width: 1.2em; text-align: center; flex-shrink: 0; }

/* ---- Modal "Enviar por e-mail": reutiliza .modal-crud-* y .crud-dyn-form ---- */
.email-doc-ref { margin: 0 0 14px; font-size: .85rem; color: hsl(var(--muted-foreground)); }
.email-field { display: flex; flex-direction: column; gap: 5px; }
.email-field > label {
  font-size: .76rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: hsl(var(--muted-foreground));
}
.email-field input, .email-field textarea {
  padding: 10px 12px; border: 1px solid hsl(var(--border)); border-radius: 9px;
  font-size: .93rem; background: hsl(var(--card)); color: hsl(var(--foreground));
  font-family: inherit; outline: none; transition: border-color .2s; resize: vertical;
}
.email-field input:focus, .email-field textarea:focus {
  border-color: hsl(var(--primary)); box-shadow: 0 0 0 3px hsl(var(--primary) / .12);
}
.email-recipients { display: flex; flex-direction: column; gap: 4px; max-height: 160px; overflow-y: auto; }
.email-recipient {
  display: flex; align-items: center; gap: 10px; padding: 9px 11px;
  border: 1px solid hsl(var(--border)); border-radius: 9px; cursor: pointer;
  font-size: .9rem; background: hsl(var(--card));
}
.email-recipient:hover { background: hsl(var(--muted) / .5); }
.email-recipient input { margin: 0; flex-shrink: 0; }
.email-empty { font-size: .85rem; color: hsl(var(--muted-foreground)); padding: 6px 2px; margin: 0; }

/* ============================================================================
   TPV NATIVO (Fase 14 — Tabula Rasa). Reconstruido desde cero con CSS Grid.
   Clases con prefijo tpv-/articulo- aisladas del resto de la app. Reutiliza las
   variables de tema (--primary, --card, --muted, --border, --foreground, --radius,
   --danger) ya definidas en el :root al inicio de este archivo.
   ============================================================================ */
.tpv-view { height: 100%; }
.tpv-grid {
  flex: 1; min-height: 0; height: 100%;
  display: grid; grid-template-columns: 1fr 340px; gap: 16px; padding: 16px;
}

/* ---- Panel izquierdo: catálogo ---- */
.tpv-catalogo { display: flex; flex-direction: column; min-width: 0; min-height: 0; gap: 12px; }
.tpv-catalogo-head { flex-shrink: 0; }
.tpv-buscar {
  width: 100%; padding: 10px 16px; border-radius: 999px;
  border: 1px solid hsl(var(--border)); background: hsl(var(--card));
  color: hsl(var(--foreground)); font-size: .95rem;
}
.tpv-buscar:focus {
  outline: none; border-color: hsl(var(--primary));
  box-shadow: 0 0 0 3px hsl(var(--primary) / 0.12);
}

.tpv-familias { flex-shrink: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.tpv-chip {
  padding: 8px 16px; border-radius: 999px; cursor: pointer; font-size: .85rem;
  white-space: nowrap;
  border: 1px solid hsl(var(--border)); background: hsl(var(--card)); color: hsl(var(--foreground));
}
.tpv-chip:hover { background: hsl(var(--muted) / 0.5); }
.tpv-chip.active { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); border-color: hsl(var(--primary)); }

.tpv-articulos {
  flex: 1; min-height: 0; overflow-y: auto; padding-right: 4px;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px;
  align-content: start;
}
.tpv-empty { grid-column: 1 / -1; color: hsl(var(--muted-foreground)); padding: 24px; text-align: center; }

.articulo-btn {
  aspect-ratio: 1 / 1; display: flex; flex-direction: column; justify-content: space-between;
  gap: 8px; padding: 12px; text-align: left; cursor: pointer;
  border: 1px solid hsl(var(--border)); border-radius: var(--radius);
  background: hsl(var(--card)); color: hsl(var(--foreground));
  transition: transform .1s ease, box-shadow .1s ease, border-color .1s ease;
}
.articulo-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,.08); border-color: hsl(var(--primary)); }
.articulo-btn:active { transform: translateY(0); }
.articulo-btn .art-nombre {
  font-size: .9rem; font-weight: 600; line-height: 1.2;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: break-word; word-break: break-word;
}
.articulo-btn .art-precio { font-size: 1.05rem; font-weight: 700; color: hsl(var(--primary)); }

/* ---- Panel derecho: ticket ---- */
.tpv-ticket {
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
  border: 1px solid hsl(var(--border)); border-radius: var(--radius); background: hsl(var(--card));
}
.tpv-ticket-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid hsl(var(--border)); font-weight: 600;
}
.tpv-vaciar {
  padding: 6px 12px; border-radius: 8px; cursor: pointer; font-size: .8rem;
  border: 1px solid hsl(var(--border)); background: hsl(var(--card)); color: hsl(var(--danger));
}
.tpv-vaciar:hover { background: hsl(var(--danger) / 0.08); }

.tpv-cliente-row { flex-shrink: 0; padding: 10px 12px; border-bottom: 1px solid hsl(var(--border)); }
.tpv-cliente-select {
  width: 100%; padding: 8px 10px; border-radius: 8px; font-size: .88rem; cursor: pointer;
  border: 1px solid hsl(var(--border)); background: hsl(var(--card)); color: hsl(var(--foreground));
}
.tpv-cliente-select:focus { outline: none; border-color: hsl(var(--primary)); box-shadow: 0 0 0 3px hsl(var(--primary) / .12); }

.tpv-ticket-items { flex: 1; min-height: 0; overflow-y: auto; list-style: none; margin: 0; padding: 8px 12px; }
.tpv-linea {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; align-items: center;
  padding: 10px 4px; border-bottom: 1px solid hsl(var(--border) / 0.6);
}
.tpv-linea-nombre { grid-column: 1 / -1; font-size: .85rem; }
.tpv-linea-controls { display: flex; align-items: center; gap: 6px; }
.tpv-linea-btn {
  width: 30px; height: 30px; border-radius: 6px; cursor: pointer;
  font-size: 1rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid hsl(var(--border)); background: hsl(var(--card)); color: hsl(var(--foreground));
}
.tpv-linea-btn:hover { background: hsl(var(--muted) / 0.5); }
.tpv-linea-uds { min-width: 28px; text-align: center; font-variant-numeric: tabular-nums; }
.tpv-linea-subtotal { justify-self: end; font-weight: 600; font-variant-numeric: tabular-nums; }

.tpv-ticket-foot { flex-shrink: 0; padding: 16px; border-top: 1px solid hsl(var(--border)); }
.tpv-total-row {
  display: flex; align-items: baseline; justify-content: space-between;
  font-size: 1.4rem; font-weight: 700; margin-bottom: 14px;
}
.tpv-total-row span:last-child { color: hsl(var(--primary)); font-variant-numeric: tabular-nums; }
.tpv-cobrar {
  width: 100%; padding: 20px; border: none; border-radius: var(--radius); cursor: pointer;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  font-size: 1.4rem; font-weight: 700; letter-spacing: .04em;
  transition: filter .1s ease;
}
.tpv-cobrar:hover:not(:disabled) { filter: brightness(1.08); }
.tpv-cobrar:disabled { opacity: .45; cursor: not-allowed; }

/* Aviso flotante del cobro (éxito/error), anclado a body fuera de la pestaña. */
.tpv-aviso {
  position: fixed; top: 20px; left: 50%; transform: translateX(-50%); z-index: 2000;
  padding: 14px 22px; border-radius: 10px; max-width: 90vw; text-align: center;
  font-size: .95rem; font-weight: 600; color: #fff; box-shadow: 0 8px 24px rgba(0,0,0,.18);
}
.tpv-aviso-ok    { background: hsl(142 71% 40%); }
.tpv-aviso-error { background: hsl(var(--danger)); }

/* Responsive TPV: split screen vertical estricto (55% catálogo / 45% ticket),
   cada mitad con scroll interno propio; nunca se solapan. */
@media (max-width: 820px) {
  .tpv-grid {
    display: flex; flex-direction: column;
    height: 100%; overflow: hidden; padding: 0; gap: 0;
  }
  .tpv-catalogo {
    flex: 0 0 55%; height: 55%;
    display: flex; flex-direction: column; overflow: hidden; padding: 8px;
  }
  .tpv-ticket {
    flex: 0 0 45%; height: 45%; max-height: none; width: 100%;
    display: flex; flex-direction: column; overflow: hidden;
    border-left: none; border-top: 2px solid hsl(var(--border));
  }
  /* Familias en una sola fila con scroll horizontal: nunca se comen el alto del
     catálogo, así los artículos siempre conservan sitio visible. */
  .tpv-familias {
    flex-wrap: nowrap; flex-shrink: 0;
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
  }
  .tpv-familias .tpv-chip { flex-shrink: 0; }
  .tpv-articulos {
    grid-template-columns: repeat(auto-fill, minmax(105px, 1fr));
    overflow-y: auto; flex: 1; min-height: 0;
  }
  .tpv-ticket-items {
    overflow-y: auto; flex: 1; min-height: 0;
  }
  /* Compactar el "cromo" del ticket para dejar sitio a las líneas en pantallas pequeñas. */
  .tpv-ticket-head, .tpv-cliente-row { padding: 8px 12px; }
  .tpv-ticket-foot { padding: 10px 12px; }
  .tpv-total-row { font-size: 1.15rem; margin-bottom: 8px; }
  .tpv-cobrar { padding: 14px; font-size: 1.15rem; }
}

/* ---- Vista placeholder (módulos aún en construcción, p. ej. Cierre-Apertura) ---- */
.placeholder-view {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  gap: 12px; padding: 32px; color: hsl(var(--muted-foreground));
}
.placeholder-view .placeholder-icon { font-size: 3rem; }
.placeholder-view h2 { font-size: 1.3rem; color: hsl(var(--foreground)); }
.placeholder-view p { max-width: 420px; line-height: 1.5; }

/* ===========================================================================
   FASE 30 — FICHA DE TERCERO (.ter-view)
   ---------------------------------------------------------------------------
   Bloque AUTÓNOMO, a propósito. Todo el CSS del módulo de documentos
   (styles.css:795-~1850) está scopeado bajo `.docs-view` mediante un truco de
   comentarios, así que `.form-section`, `.form-grid`, `.line-item`, `.badge` o
   `.nif-status` NO aplican fuera de esa vista. En lugar de des-scoparlos —lo que
   arriesgaría romper Documentos— aquí se duplican con prefijo `.ter-`.

   Las clases NO pueden contener la subcadena `.tab`: el patch de
   querySelectorAll (app.js:60) fuerza ámbito global a esos selectores y
   rompería la barra de pestañas del workspace.
   =========================================================================== */

/* Tokens propios: --success, --warning, --destructive y --popover solo existen
   dentro de .docs-view (styles.css:765-778). Sin declararlos aquí,
   hsl(var(--success)) sería un color inválido. */
.ter-view {
  --success: 142 71% 38%;
  --warning: 38 92% 50%;
  --destructive: 0 72% 51%;
  --info: 208 88% 40%;
  --secondary: 240 5% 96%;
  --popover: 0 0% 100%;
}
:root[data-theme="dark"] .ter-view {
  --success: 142 60% 45%;
  --warning: 38 92% 55%;
  --destructive: 0 70% 55%;
  --info: 208 90% 62%;
  --secondary: 222 14% 22%;
  --popover: 222 16% 15%;
}
.ter-view, .ter-view *, .ter-view *::before, .ter-view *::after { box-sizing: border-box; }

.ter-view {
  display: flex; flex-direction: column; gap: 14px;
  padding: 18px; overflow-y: auto; height: 100%;
}

/* ---------------------------------------------------------------- cabecera */
.ter-cabecera {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 14px 18px; border-radius: var(--radius);
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
}
.ter-identidad { min-width: 220px; flex: 1 1 260px; }
.ter-identidad h2 { font-size: 1.15rem; margin: 0; color: hsl(var(--foreground)); }
.ter-subtitulo { display: flex; gap: 12px; margin-top: 4px; flex-wrap: wrap; }
.ter-mono { font-family: var(--mono); font-size: .82rem; color: hsl(var(--muted-foreground)); }
.ter-acciones { display: flex; gap: 8px; margin-left: auto; }

/* Chips de rol: qué ES este tercero (requisito 8 del encargo) */
.ter-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.ter-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px; font-size: .76rem; font-weight: 600;
  background: hsl(var(--primary) / .1); color: hsl(var(--primary));
  border: 1px solid hsl(var(--primary) / .25);
}
.ter-chip--cliente   { background: hsl(var(--success) / .12); color: hsl(var(--success));
                       border-color: hsl(var(--success) / .3); }
.ter-chip--proveedor { background: hsl(var(--info) / .12); color: hsl(var(--info));
                       border-color: hsl(var(--info) / .3); }
.ter-chip--acreedor  { background: hsl(var(--warning) / .15); color: hsl(38 92% 32%);
                       border-color: hsl(var(--warning) / .35); }
.ter-chip--agente    { background: hsl(280 60% 50% / .12); color: hsl(280 60% 45%);
                       border-color: hsl(280 60% 50% / .3); }
.ter-chip--neutro    { background: hsl(var(--muted)); color: hsl(var(--muted-foreground));
                       border-color: hsl(var(--border)); }
.ter-chip small { font-weight: 400; opacity: .8; }
:root[data-theme="dark"] .ter-chip--acreedor { color: hsl(38 92% 65%); }

/* ------------------------------------------------------------------ avisos */
.ter-avisos:empty { display: none; }
.ter-aviso {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 14px; border-radius: var(--radius); font-size: .87rem;
  border: 1px solid; margin-bottom: 8px;
}
.ter-aviso--ojo   { background: hsl(var(--warning) / .1); border-color: hsl(var(--warning) / .4);
                    color: hsl(38 92% 28%); }
.ter-aviso--error { background: hsl(var(--destructive) / .1); border-color: hsl(var(--destructive) / .4);
                    color: hsl(var(--destructive)); }
.ter-aviso--ok    { background: hsl(var(--success) / .1); border-color: hsl(var(--success) / .4);
                    color: hsl(var(--success)); }
.ter-aviso--info  { background: hsl(var(--info) / .1); border-color: hsl(var(--info) / .35);
                    color: hsl(var(--info)); }
.ter-aviso button { margin-left: auto; flex-shrink: 0; }
:root[data-theme="dark"] .ter-aviso--ojo { color: hsl(38 92% 68%); }

/* -------------------------------------------------------------- sub-pestañas */
.ter-barra {
  display: flex; gap: 2px; overflow-x: auto; scrollbar-width: thin;
  border-bottom: 1px solid hsl(var(--border));
}
.ter-tab {
  padding: 9px 16px; border: none; background: transparent; cursor: pointer;
  font-size: .9rem; font-weight: 500; white-space: nowrap;
  color: hsl(var(--muted-foreground));
  border-bottom: 2px solid transparent; transition: color .15s, border-color .15s;
}
.ter-tab:hover { color: hsl(var(--foreground)); }
.ter-tab--activa { color: hsl(var(--primary)); border-bottom-color: hsl(var(--primary)); }
.ter-num {
  display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 999px; background: hsl(var(--muted)); font-size: .72rem;
  color: hsl(var(--muted-foreground));
}
.ter-num:empty { display: none; }

.ter-panel { display: none; padding-top: 14px; }
.ter-panel--activo { display: block; }

/* ---------------------------------------------------------------- secciones */
.ter-seccion {
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: var(--radius); padding: 16px; margin-bottom: 14px;
}
.ter-seccion-cab { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.ter-seccion-cab .ter-seccion-titulo { margin: 0; border: none; padding: 0; }
.ter-seccion-cab button { margin-left: auto; }
.ter-seccion-titulo {
  font-size: .95rem; font-weight: 600; margin: 0 0 12px;
  padding-bottom: 8px; border-bottom: 1px solid hsl(var(--border));
  color: hsl(var(--foreground));
}
.ter-ayuda { font-size: .82rem; color: hsl(var(--muted-foreground)); margin: 0 0 10px; }

/* ------------------------------------------------------------------- campos */
.ter-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.ter-campo { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ter-campo > span { font-size: .8rem; font-weight: 500; color: hsl(var(--muted-foreground)); }
.ter-campo > span em { color: hsl(var(--destructive)); font-style: normal; }
.ter-campo input, .ter-campo select, .ter-campo textarea {
  padding: 8px 10px; border: 1px solid hsl(var(--input)); border-radius: 8px;
  background: hsl(var(--background)); color: hsl(var(--foreground));
  font-size: .9rem; font-family: inherit; width: 100%; min-width: 0;
}
.ter-campo input:focus, .ter-campo select:focus, .ter-campo textarea:focus {
  outline: none; border-color: hsl(var(--primary)); box-shadow: 0 0 0 3px hsl(var(--primary) / .12);
}
.ter-campo input[readonly] { background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); }
.ter-campo small { font-size: .74rem; color: hsl(var(--muted-foreground)); }
.ter-campo--ancho { grid-column: span 2; }
.ter-campo--total { grid-column: 1 / -1; }
.ter-campo--corto { max-width: 150px; }
.ter-campo--error input, .ter-campo--error select, .ter-campo--error textarea {
  border-color: hsl(var(--destructive)); box-shadow: 0 0 0 3px hsl(var(--destructive) / .12);
}
.ter-campo--error > span { color: hsl(var(--destructive)); }
.ter-campo textarea { resize: vertical; }

/* Semáforo del NIF, alimentado por SP_VALIDA_NIF */
.ter-nif-estado { min-height: 1.1em; font-size: .76rem; }
.ter-nif-estado.es-ok       { color: hsl(var(--success)); }
.ter-nif-estado.es-error    { color: hsl(var(--destructive)); }
.ter-nif-estado.es-cargando { color: hsl(var(--muted-foreground)); }
.ter-nif-estado.es-aviso    { color: hsl(38 92% 32%); }
:root[data-theme="dark"] .ter-nif-estado.es-aviso { color: hsl(38 92% 65%); }

/* Campo + botón "+" de alta rápida de catálogo */
.ter-combo-fila { display: flex; gap: 6px; align-items: stretch; }
.ter-combo-fila > input, .ter-combo-fila > select { flex: 1 1 auto; min-width: 0; }
.ter-btn-mas {
  flex: 0 0 auto; width: 34px; border-radius: 8px; cursor: pointer;
  border: 1px dashed hsl(var(--primary) / .5); background: hsl(var(--primary) / .06);
  color: hsl(var(--primary)); font-size: 1.05rem; line-height: 1;
}
.ter-btn-mas:hover { background: hsl(var(--primary) / .14); border-style: solid; }

/* ------------------------------------------ sub-rejillas (dir./cont./bancos) */
.ter-lista { display: flex; flex-direction: column; gap: 10px; }
.ter-lista:empty::after {
  content: "No hay registros todavía."; display: block; padding: 18px;
  text-align: center; color: hsl(var(--muted-foreground)); font-size: .87rem;
  border: 1px dashed hsl(var(--border)); border-radius: var(--radius);
}
.ter-fila {
  border: 1px solid hsl(var(--border)); border-radius: var(--radius);
  padding: 12px; background: hsl(var(--background));
}
.ter-fila--defecto { border-color: hsl(var(--primary) / .45); background: hsl(var(--primary) / .04); }
.ter-fila-cab { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.ter-fila-titulo { font-weight: 600; font-size: .9rem; color: hsl(var(--foreground)); }
.ter-fila-resumen { font-size: .8rem; color: hsl(var(--muted-foreground)); }
.ter-fila-acciones { display: flex; gap: 6px; margin-left: auto; }
.ter-btn-icono {
  border: 1px solid hsl(var(--border)); background: hsl(var(--card));
  border-radius: 7px; padding: 4px 9px; cursor: pointer; font-size: .8rem;
  color: hsl(var(--muted-foreground));
}
.ter-btn-icono:hover { border-color: hsl(var(--primary)); color: hsl(var(--primary)); }
.ter-btn-icono--peligro:hover { border-color: hsl(var(--destructive)); color: hsl(var(--destructive)); }
.ter-btn-icono[disabled] { opacity: .45; cursor: not-allowed; }

/* -------------------------------------------------------------------- roles */
.ter-roles-detalle { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.ter-rol-linea {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  border: 1px solid hsl(var(--border)); border-radius: 9px; font-size: .87rem;
  background: hsl(var(--background));
}
.ter-rol-linea .ter-mono { margin-left: auto; }
.ter-roles-alta { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ter-roles-alta select {
  padding: 8px 10px; border: 1px solid hsl(var(--input)); border-radius: 8px;
  background: hsl(var(--background)); color: hsl(var(--foreground)); font-size: .9rem;
}

/* --------------------------------------------- combo con búsqueda (combo.js) */
/* Anclaje.abrir() fuerza display:flex al mostrar el panel, así que la dirección
   de columna es obligatoria: sin ella las opciones se colocarían en fila. */
.ter-combo-panel {
  flex-direction: column;
  max-height: 300px; overflow-y: auto; min-width: 240px; padding: 4px;
  background: hsl(var(--popover)); border: 1px solid hsl(var(--border));
  border-radius: var(--radius); box-shadow: 0 10px 30px hsl(240 21% 15% / .16);
}
.ter-combo-opcion {
  padding: 7px 10px; border-radius: 7px; cursor: pointer; font-size: .87rem;
  color: hsl(var(--foreground));
}
.ter-combo-opcion:hover, .ter-combo-opcion.es-activa { background: hsl(var(--primary) / .1); }
.ter-combo-opcion small { display: block; font-size: .75rem; color: hsl(var(--muted-foreground)); }
.ter-combo-vacio { padding: 12px; text-align: center; font-size: .83rem;
                   color: hsl(var(--muted-foreground)); }
.ter-combo-crear {
  padding: 8px 10px; border-radius: 7px; cursor: pointer; font-size: .85rem;
  color: hsl(var(--primary)); font-weight: 600;
  border-top: 1px solid hsl(var(--border)); margin-top: 4px;
}
.ter-combo-crear:hover { background: hsl(var(--primary) / .1); }

/* El panel del combo se cuelga del clon de la pestaña, pero Anclaje lo posiciona
   con position:fixed, así que necesita su propia capa. Misma que .panel-anclado. */
.ter-combo-panel { z-index: var(--z-panel-anclado); }

/* --------------------------------------------------------------- responsive */
@media (max-width: 1100px) {
  .ter-campo--ancho { grid-column: span 1; }
}
@media (max-width: 820px) {
  .ter-view { padding: 12px; }
  .ter-grid { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
  .ter-acciones { width: 100%; margin-left: 0; }
  .ter-acciones button { flex: 1; }
}
@media (max-width: 640px) {
  .ter-grid { grid-template-columns: 1fr; }
  .ter-campo--corto { max-width: none; }
  .ter-cabecera { padding: 12px; }
  .ter-seccion { padding: 12px; }
  .ter-fila-acciones { width: 100%; margin-left: 0; }
}
