/* ============================================================
   ZH Technologies — Design Tokens (nueva paleta)
   Fuente: ZH Material Design System
   ============================================================ */
:root {
  /* ── Brand ──────────────────────────────────────────────── */
  --color-primary: #3a5f84;
  --color-primary-dim: #a5caf4;
  --color-primary-container: #53779e;
  --color-brand-dark: #003366;
  --color-brand-accent: #4f7ba6;
  --color-focus-cyan: #00e5ff;
  --color-on-primary: #ffffff;
  --color-secondary: #3c6188;
  --color-tertiary: #555d64;

  /* ── Semantic ────────────────────────────────────────────── */
  --color-error: #c0392b;
  --color-success: #1a7a4a;
  --color-warning: #ba7517;
  /* Naranja distinto del ámbar de warning — estados intermedios (ni éxito ni aviso clásico). */
  --color-attention: #c2540b;

  /* ── Surface / Background ────────────────────────────────── */
  --color-background: #f8f9fb;
  --color-surface: #ffffff;
  --color-surface-bright: #f8f9fb;
  --color-surface-dim: #d9dadc;
  --color-surface-container: #edeef0;
  --color-surface-container-low: #f2f4f6;
  --color-surface-container-high: #e7e8ea;

  /* ── Text ────────────────────────────────────────────────── */
  --color-text-primary: #1a1d23;
  --color-text-secondary: #6b7280;
  --color-on-surface: #191c1e;
  --color-on-surface-variant: #42474e;
  --color-outline: #73777f;
  --color-outline-variant: #c2c7cf;

  /* ── Border ──────────────────────────────────────────────── */
  --color-border: rgba(0, 0, 0, 0.1);

  /* ── Border Radius ────────────────────────────────────────── */
  --radius-xs: 2px;
  --radius-sm: 4px;
  --radius-md: 7px; /* inputs, buttons */
  --radius-lg: 9px; /* cards */
  --radius-xl: 12px; /* modals, large panels */
  --radius-pill: 999px;

  /* ── Spacing (4px grid) ──────────────────────────────────── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;

  /* ── App / platform shell content (LayoutFrame) ─────────── */
  --shell-content-padding: var(--space-6);
  --shell-content-padding-compact: var(--space-4);
  --shell-content-max-width: 1440px;
  --shell-content-gap: var(--space-6);

  /* ── Typography ───────────────────────────────────────────── */
  /* Escala tipográfica única del ERP. --text-headline-lg-* está reservada
     exclusivamente para pantallas especiales (Login, First Run, Onboarding,
     Wizards principales, Empty States) — nunca para pantallas CRUD. */
  --font-family: "Inter", system-ui, -apple-system, sans-serif;
  --font-family-mono: "SF Mono", "Cascadia Code", ui-monospace, Consolas, monospace;

  --text-headline-lg-size: 28px;
  --text-headline-lg-height: 36px;
  --text-headline-lg-weight: 600;
  --text-headline-lg-spacing: -0.02em;

  /* H1 — títulos principales de páginas CRUD */
  --text-headline-md-size: 20px;
  --text-headline-md-height: 28px;
  --text-headline-md-weight: 600;
  --text-headline-md-spacing: -0.01em;

  /* H2 — paneles, tarjetas, bloques */
  --text-headline-sm-size: 18px;
  --text-headline-sm-height: 26px;
  --text-headline-sm-weight: 600;

  /* H3 — subsecciones */
  --text-title-sm-size: 16px;
  --text-title-sm-height: 24px;
  --text-title-sm-weight: 600;

  --text-body-lg-size: 15px;

  /* Body — párrafos, contenido, inputs, selects, textareas, celdas de tabla */
  --text-body-md-size: 14px;
  --text-body-md-height: 22px;
  --text-body-md-weight: 400;

  /* Label — único estilo oficial de etiqueta de campo */
  --text-label-md-size: 14px;
  --text-label-md-height: 20px;
  --text-label-md-weight: 600;

  /* Header de tabla */
  --text-label-sm-size: 12px;
  --text-label-sm-weight: 600;
  --text-label-sm-spacing: 0.03em;

  /* Help text — texto de ayuda bajo campos */
  --text-help-size: 12px;
  --text-help-height: 18px;
  --text-help-weight: 400;

  /* Badge — mismo tamaño que header de tabla pero peso distinto (500 vs 600) */
  --text-badge-size: 12px;
  --text-badge-height: 16px;
  --text-badge-weight: 500;

  /* ── Tinted surfaces ─────────────────────────────────────── */
  --color-surface-primary-tint: #e8f0f8; /* table thead, subtle primary accent */

  /* ── Inverse surface (tooltips, snackbars sobre fondo oscuro) ── */
  --color-inverse-surface: #2e3132;
  --color-inverse-on-surface: #f0f1f3;

  /* ── Gradients ────────────────────────────────────────────── */
  --gradient-brand: linear-gradient(
    135deg,
    var(--color-secondary) 0%,
    var(--color-primary) 100%
  );

  /* ── Shadows ──────────────────────────────────────────────── */
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.06);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.1), 0 1px 4px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.12), 0 4px 8px rgba(0, 0, 0, 0.06);

  /* ── Transitions ──────────────────────────────────────────── */
  --transition: 0.15s ease;
  --transition-slow: 0.3s ease;

  /* ── Token aliases (shorthand + missing refs) ─────────────── */
  /* Typography shorthands */
  --text-xs: var(--text-label-sm-size);
  --text-sm: var(--text-body-md-size);

  /* Help text — usado por páginas que referenciaban un token inexistente */
  --text-body-sm-size: var(--text-help-size);

  /* Surface aliases */
  --color-border-light: rgba(0, 0, 0, 0.06); /* lighter separator */
  --color-text-tertiary: var(--color-outline); /* most subtle text */

  /* Color-fixed aliases (Material 3 pattern used in KPI icons, plan badges) */
  --color-primary-fixed: rgba(58, 95, 132, 0.1);
  --color-secondary-fixed: rgba(60, 97, 136, 0.1);
  --color-tertiary-fixed: #dbe3eb;

  /* Semantic containers */
  --color-error-container: rgba(192, 57, 43, 0.1);
  --color-primary-subtle: rgba(
    58,
    95,
    132,
    0.1
  ); /* used in permission badges */

  /* Info = primary — mismo criterio que .zh-form-alert--info / .badge--info / .zh-toast--info */
  --color-info: var(--color-primary);

  /* Anillo de foco de inputs (3px box-shadow) — mismo criterio que .zh-toggle-switch.is-pressed */
  --color-focus-ring: color-mix(in srgb, var(--color-primary) 18%, transparent);

  /* Duración corta para transiciones puntuales (barras de progreso, iconos) */
  --motion-duration-fast: 0.15s;

  /* Interlineado compacto (descripciones secundarias en pickers/resultados) */
  --line-height-snug: 1.3;

  /* Valor por defecto de la barra de progreso de carga de archivos — el
     componente lo sobrescribe por instancia vía style inline (ZhFileUpload.tsx). */
  --upload-progress: 0%;

  /* ── Glass overlay (ZHAppTenantHeader — cabecera translúcida sobre --color-primary) ── */
  --color-glass-surface-10: rgba(255, 255, 255, 0.1);
  --color-glass-surface-12: rgba(255, 255, 255, 0.12);
  --color-glass-surface-15: rgba(255, 255, 255, 0.15);
  --color-glass-surface-18: rgba(255, 255, 255, 0.18);
  --color-glass-surface-20: rgba(255, 255, 255, 0.2);
  --color-glass-border-25: rgba(255, 255, 255, 0.25);
  --color-glass-border-35: rgba(255, 255, 255, 0.35);
  --color-overlay-dark-12: rgba(0, 0, 0, 0.12);
  --color-overlay-dark-18: rgba(0, 0, 0, 0.18);
  --color-overlay-dark-38: rgba(0, 0, 0, 0.38);
}
/*
  CSS legacy compartido.
  Entra antes de zh-ui.css para que el Design System oficial pueda prevalecer.
  No usar en pantallas nuevas.
*/
/* Utilidades legacy — INFRAESTRUCTURA EN PROCESO DE RETIRO (Fase 3B).
   Preferir tokens/clases ZH en código nuevo. No agregar clases nuevas aquí.

   Auditoría Fase 3B: de 68 clases definidas originalmente, 57 no tenían
   ninguna referencia en frontend/src/**/
*.tsx y fueron eliminadas. Las 11
   restantes siguen en uso real y se mantienen aquí como núcleo compartido
   (multi-módulo) o pendientes de mover a su módulo específico:

   - Reutilizadas por 5+ módulos (quedan aquí, no son "específicas" de nada):
     .pg-pad-40, .pg-row-inactive, .pg-td-right, .pg-th-right
   - Usadas por 2 módulos (candidatas a promoverse a zh-ui.css si se vuelven
     a necesitar en un tercero):
     .pg-icon-18
   - Usadas por un único módulo — candidatas a moverse a su CSS de módulo en
     una próxima pasada (no movidas ahora para no multiplicar archivos CSS
     por 1-2 reglas cada uno): .pg-desc-subtle, .pg-state-pad, .pg-th-actions
     (access/ProfilesPage.css), .pg-icon-primary (inventory/warehouses/BodegasPage.css),
     .pg-text-muted-sm (settings/geography — sin CSS propio hoy). */

.pg-th-right {
  text-align: right;
}
.pg-td-right {
  text-align: right;
}
.pg-row-inactive {
  opacity: 0.65;
}
.pg-pad-40 {
  padding: 40px;
}
/* .pg-overflow-x ELIMINADA (Bloque 15A) — sin consumidores, duplicaba .table-scroll (ver zh-ui.css). */
.pg-icon-18 {
  font-size: 18px;
}
.pg-icon-primary {
  color: var(--color-primary);
}
.pg-desc-subtle {
  margin: 0;
  font-size: var(--text-label-sm-size);
}
.pg-state-pad {
  padding: var(--space-6);
}
.pg-text-muted-sm {
  font-size: 12px;
  color: var(--color-text-secondary);
}
.pg-th-actions {
  width: 180px;
}
/* ============================================================
   ZH Technologies — Page Template
   Clases pg-* compartidas por TODAS las páginas de usuario.
   Requiere: design-tokens.css

   ÍNDICE
   1.  Page Wrapper
   2.  Page Header (breadcrumb + título + acciones)
   3.  KPI / Stat Cards
   4.  Section Card
   5.  Form Grid dentro de secciones
   6.  Controles de tabla (búsqueda, filtros, paginación)
   7.  Pie de tabla (leyenda, timestamp)
   8.  Actividad / Logs de movimiento
   9.  Accent Card (promo / CTA azul)
   10. Totales de factura / resumen
   11. Barra de acciones inferior
   12. Inputs editables inline (tablas de formulario)
   ============================================================ */
/* ── 1. PAGE WRAPPER ─────────────────────────────────────── */
.pg-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  max-width: none;
  min-width: 0;
}
/* ── 2. PAGE HEADER ──────────────────────────────────────── */
.pg-header-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.pg-header-left {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.pg-header-right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
  flex-wrap: wrap;
}
.pg-breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.pg-breadcrumb-item {
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  letter-spacing: var(--text-label-sm-spacing);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.pg-breadcrumb-sep {
  font-size: 14px;
  color: var(--color-text-secondary);
  vertical-align: middle;
}
/* .pg-kicker ELIMINADO (Bloque 12B) — sin consumidores. */
.pg-result-count {
  font-size: 12px;
  color: var(--color-text-secondary);
  white-space: nowrap;
  align-self: center;
}
.pg-title {
  font-size: var(--text-headline-md-size);
  font-weight: var(--text-headline-md-weight);
  letter-spacing: var(--text-headline-md-spacing);
  line-height: var(--text-headline-md-height);
  color: var(--color-text-primary);
  margin: 0;
}
.pg-subtitle {
  font-size: var(--text-body-md-size);
  line-height: var(--text-body-md-height);
  color: var(--color-text-secondary);
  margin: 0;
}
/* Header meta-fields (folio, fecha, moneda) */
.pg-header-fields {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
}
@media (max-width: 640px) {
  .pg-header-fields {
    grid-template-columns: 1fr;
  }
}
/* .pg-header-field/.pg-header-field-label ELIMINADOS (Bloque 12B) — sin consumidores. */
/* ── 3. KPI / STAT CARDS ─────────────────────────────────── */
.pg-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
}
@media (max-width: 900px) {
  .pg-kpis {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 480px) {
  .pg-kpis {
    grid-template-columns: 1fr;
  }
}
.pg-kpi {
  background: var(--color-surface);
  padding: var(--space-5);
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 128px;
  position: relative;
  overflow: hidden;
}
.pg-kpi-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
.pg-kpi-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.pg-kpi-icon .material-symbols-outlined {
  font-size: 22px;
}
.pg-kpi-icon--primary {
  background: var(--color-primary-fixed);
  color: var(--color-primary);
}
.pg-kpi-icon--secondary {
  background: var(--color-secondary-fixed);
  color: var(--color-secondary);
}
.pg-kpi-icon--tertiary {
  background: var(--color-tertiary-fixed);
  color: var(--color-tertiary);
}
.pg-kpi-icon--success {
  background: color-mix(in srgb, var(--color-success) 10%, transparent);
  color: var(--color-success);
}
.pg-kpi-icon--warning {
  background: color-mix(in srgb, var(--color-warning) 10%, transparent);
  color: var(--color-warning);
}
.pg-kpi-icon--error {
  background: var(--color-error-container);
  color: var(--color-error);
}
.pg-kpi-icon--neutral {
  background: var(--color-surface-container);
  color: var(--color-text-secondary);
}
.pg-kpi-icon--info {
  background: var(--color-primary-fixed);
  color: var(--color-primary);
}
/* .pg-kpi-badge/--success/--warning/--error/--neutral ELIMINADOS (Bloque 11A)
   — sin consumidores; ReportKpiCard compone <Badge> oficial desde el
   Bloque 6D, y los 2 usos sueltos restantes (CompanyProfileSettingsSection,
   OperationSettingsSection) migraron a <Badge> directo. */
.pg-kpi-bottom {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pg-kpi-label {
  font-size: var(--text-label-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-text-secondary);
  margin: 0;
}
.pg-kpi-value {
  font-size: var(--text-headline-md-size);
  font-weight: var(--text-headline-md-weight);
  letter-spacing: var(--text-headline-md-spacing);
  color: var(--color-text-primary);
  margin: 0;
}
/* Value tone (Bloque 12G-3) — color semántico opcional del valor numérico,
   vía la prop `valueTone` de ReportKpiCard. Aditiva: solo toca color, nunca
   tamaño/peso/spacing ya definidos por .pg-kpi-value. Cierra la última
   diferencia visual detectada en la migración de edm-kpi-card (12G-2):
   .edm-metric--success/--danger coloreaban el número directamente, algo que
   ReportKpiCard no soportaba hasta ahora. */
.pg-kpi-value--success {
  color: var(--color-success);
}
.pg-kpi-value--danger {
  color: var(--color-error);
}
.pg-kpi-unit {
  font-size: var(--text-help-size);
  font-weight: var(--text-help-weight);
  color: var(--color-text-secondary);
  margin-left: var(--space-1);
}
/* Trend indicator (icon + texto), promovido desde .dsh-kpi-trend (Bloque 6D) */
.pg-kpi-trend {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  margin-top: var(--space-1);
}
.pg-kpi-trend .material-symbols-outlined {
  font-size: 16px;
}
.pg-kpi-trend--success {
  color: var(--color-success);
}
.pg-kpi-trend--warning {
  color: var(--color-warning);
}
.pg-kpi-trend--neutral {
  color: var(--color-text-secondary);
}
/* Variante horizontal (icon left, text right) */
.pg-kpi--h {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-4);
  min-height: auto;
}
/* Interactive variant (Bloque 12G-1) — permite usar ReportKpiCard como
   tarjeta KPI clicable (p. ej. un filtro por estado). Se activa
   automáticamente cuando <ReportKpiCard onClick={...}> renderiza <button>
   en vez de <div>. El área clicable es la tarjeta completa (ícono + badge +
   label + value + trend), no solo el número — decisión de UX explícita para
   evitar el problema detectado en 12G-0 (título fuera del área clicable en
   edm-kpi-card). Aditiva: solo normaliza el reset nativo de <button> y
   agrega hover/foco — nunca toca layout/spacing ya definidos por .pg-kpi.
   Sin consumidores todavía (preparación de capacidad, Bloque 12G-1). */
.pg-kpi--interactive {
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition:
    box-shadow var(--transition),
    border-color var(--transition),
    background var(--transition);
}
.pg-kpi--interactive:hover {
  background: var(--color-surface-container-low);
}
.pg-kpi--interactive:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
/* Active/selected state (Bloque 12G-1) — combina con .pg-kpi--interactive
   cuando la prop `active` de ReportKpiCard es true, para reflejar qué
   filtro está aplicado actualmente. Mismo tratamiento visual que tenía
   .edm-kpi-card--active (borde + sombra primary), generalizado al SSOT. */
.pg-kpi--active {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 1px var(--color-primary);
}
/* ── 4. SECTION CARD ─────────────────────────────────────── */
.pg-section {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.pg-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}
.pg-section-header-left {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.pg-section-icon {
  font-size: 20px;
  color: var(--color-primary);
  vertical-align: middle;
}
.pg-section-label {
  font-size: var(--text-label-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-text-primary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0;
}
.pg-section-body {
  padding: var(--space-5);
}
/* .pg-form-grid* / .pg-field / .pg-field-label ELIMINADOS (Bloque 12B) — sin consumidores. */
/* ── 6. TABLE CONTROLS ───────────────────────────────────── */
.pg-table-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border);
  flex-wrap: wrap;
}
.pg-table-controls-left {
  display: flex;
  gap: var(--space-2);
  flex: 1;
  max-width: 440px;
}
.pg-table-controls-right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-secondary);
  font-size: 12px;
  white-space: nowrap;
}
/* Search input */
.pg-search {
  position: relative;
  flex: 1;
}
.pg-search .material-symbols-outlined {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 20px;
  color: var(--color-text-secondary);
  pointer-events: none;
}
.pg-search input {
  width: 100%;
  padding-left: 36px;
  padding-right: 12px;
}
/* Pagination inline controls */
.pg-pagination-controls {
  display: flex;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-left: var(--space-2);
}
.pg-pagination-btn {
  padding: 6px;
  border: none;
  background: var(--color-surface);
  cursor: pointer;
  display: flex;
  align-items: center;
  color: var(--color-text-secondary);
  transition: background var(--transition);
}
.pg-pagination-btn:not(:last-child) {
  border-right: 1px solid var(--color-border);
}
.pg-pagination-btn:hover:not(:disabled) {
  background: var(--color-surface-container-low);
}
.pg-pagination-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.pg-pagination-btn .material-symbols-outlined {
  font-size: 18px;
}
/* Variante con texto visible (Bloque 10A) — para paginación con etiquetas
   ("Anterior"/"Siguiente") + resumen ("Página X de Y"), a diferencia de
   .pg-pagination-controls/.pg-pagination-btn que son solo-ícono. Los botones
   en sí usan <ZHBtn> (ya oficial, sin CSS propio necesario) dentro de
   .pg-pagination-actions; el texto de resumen usa .pg-pagination-summary. */
.pg-pagination-summary {
  font-size: 13px;
  color: var(--color-text-secondary);
  margin: 0;
}
.pg-pagination-actions {
  display: flex;
  gap: var(--space-2);
}
/* ── 7. TABLE FOOTER ─────────────────────────────────────── */
.pg-table-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-4);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
  gap: var(--space-3);
}
/* .pg-legend* ELIMINADOS (Bloque 12B) — sin consumidores. */
.pg-table-timestamp {
  font-size: 12px;
  color: var(--color-text-secondary);
  font-style: italic;
}
/* .pg-activity-* ELIMINADOS (Bloque 12B) — sin consumidores. */
/* .pg-accent-card* ELIMINADOS (Bloque 12B) — sin consumidores. */
/* .pg-totals* ELIMINADOS (Bloque 12B) — sin consumidores. */
/* ── 11. ACTIONS BAR ─────────────────────────────────────── */
.pg-actions-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
}
.pg-actions-info {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-text-secondary);
  background: var(--color-surface-container-low);
  padding: 8px var(--space-4);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  font-size: 12px;
  line-height: 1.4;
  flex: 1;
  min-width: 0;
}
.pg-actions-info .material-symbols-outlined {
  font-size: 20px;
  flex-shrink: 0;
}
.pg-actions-buttons {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  flex-shrink: 0;
}
@media (max-width: 600px) {
  .pg-actions-bar {
    flex-direction: column;
    align-items: stretch;
  }
  .pg-actions-buttons {
    justify-content: stretch;
  }
  .pg-actions-buttons .zh-btn {
    flex: 1;
    justify-content: center;
  }
}
/* .pg-editable-input* / .pg-add-row / .pg-row-delete ELIMINADOS (Bloque 12B) — sin consumidores. */
/*
  SSOT de componentes visuales reutilizables.
  Botones, campos, cards, badges, tablas, modales, alerts, grids y utilidades oficiales.
*/
/* ============================================================
   ZH Global Component Library
   Requires: design-tokens.css (loaded via index.css)
   ============================================================

   ARQUITECTURA
   ┌─────────────────────────────────────────────┐
   │ index.css                                    │
   │  └── @import design-tokens.css  (variables) │
   │  └── @import zh-ui.css          (este archivo)│
   │                                             │
   │ Componentes: solo estilos únicos del        │
   │ componente; todo lo reutilizable vive aquí. │
   └───────────────────────────────────────────────┘

   ÍNDICE
   1. Tipografía
   2. Botones (.zh-btn)
   3. Formularios — inputs/select/textarea
   4. Campos (.zh-field)
   5. Alertas / Notices (.zh-form-alert)
   6. Form Header / Body / Section
   7. Tenant Header
   8. Toggle
   9. Cards (.card, .table-card)
   10. Tablas (.table)
   11. Badges (.badge)
   12. Page Shell / Layout
   13. Card Sections — ELIMINADO (Bloque 12B, sin consumidores)
   14. Screen Heading
   16. Estados (empty / loading / error)
   17. Modales
   19. Utilidades de espaciado y layout
   20. Auth Layout (.zh-auth-bg, .zh-auth-wrapper, .zh-auth-brand)
   21. Avatar (.zh-avatar)
   22. Status Badge (.zh-status)
   23. Entity Item (.zh-entity-item)
   24. Metric Card — ELIMINADO (Bloque 6B, sin consumidores)
   25. Global Topbar (.zh-app-userMenuPopover, footer btn)
   26. Global Footer — ELIMINADO (Bloque 12B, sin consumidores)
   27. Auth Form Card (.zh-auth-card, .zh-auth-form, .zh-auth-input, .zh-auth-submit)
   28. Patrones responsive compartidos
   29. Toast (.zh-toast)
   30. Line Row (.zh-line-card, .zh-line-action-rail, .zh-line-action, .zh-line-content,
       .zh-line-action-menu, .zh-line-action-item)
   ============================================================ */
/* ── 1. TIPOGRAFÍA ────────────────────────────────────────── */
h1,
h2,
h3,
h4,
h5,
h6 {
  font-weight: 600;
  color: var(--color-text-primary);
  line-height: 1.3;
}
h1 {
  font-size: var(--text-headline-md-size);
  letter-spacing: var(--text-headline-md-spacing);
}
h2 {
  font-size: var(--text-headline-sm-size);
}
h3 {
  font-size: var(--text-title-sm-size);
}
a {
  color: var(--color-primary);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
.text-muted {
  color: var(--color-text-secondary);
}
/* .text-sm/.text-xs/.text-error/.text-success ELIMINADOS (Bloque 12B) — sin
   consumidores (no confundir con --text-sm/--text-xs, tokens de
   design-tokens.css consumidos por .subtle, esos sí siguen vivos). */
.mono {
  font-family: var(--font-family-mono);
  font-size: 12px;
  color: var(--color-text-secondary);
}
.zh-font-mono {
  font-family: var(--font-family-mono);
}
/* Título de sección compacto (11px/700, mayúsculas, tracking 0.06em) — patrón repetido
   idéntico en varias secciones de sidebar/paneles compactos (encabezado de sección,
   total destacado, checklist). No hay token dedicado a esta combinación en
   design-tokens.css; se expone como utilidad global en vez de repetir los 4 valores en
   cada módulo. El color se deja fuera a propósito: cada consumidor define su propio
   color (neutro, énfasis, warning, etc.) según el contexto (SALES-DS-GLOBAL-VISUAL-16). */
.zh-section-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.subtle {
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
}
/* .truncate ELIMINADO (Bloque 12B) — sin consumidores. */
/* ── 2. BOTONES ───────────────────────────────────────────── */
.zh-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 38px;
  padding: 0 16px;
  font-family: var(--font-family);
  font-size: var(--text-label-md-size);
  font-weight: var(--text-label-md-weight);
  letter-spacing: 0.01em;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition:
    background var(--transition),
    color var(--transition),
    border-color var(--transition),
    box-shadow var(--transition),
    opacity var(--transition),
    transform 0.08s ease;
}
.zh-btn:active:not(:disabled) {
  transform: scale(0.97);
}
.zh-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
/* Sizes */
.zh-btn--md {
  height: 34px;
  padding: 0 14px;
  font-size: 13px;
}
.zh-btn--sm {
  height: 28px;
  padding: 0 10px;
  font-size: 12px;
}
.zh-btn--xs {
  height: 24px;
  padding: 0 8px;
  font-size: 11px;
}
/* Variants */
.zh-btn--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}
.zh-btn--primary:hover:not(:disabled) {
  background: color-mix(
    in srgb,
    var(--color-primary) 85%,
    var(--color-text-primary)
  );
}
.zh-btn--secondary {
  background: var(--color-surface-container-low);
  color: var(--color-primary);
  border-color: var(--color-border);
}
.zh-btn--secondary:hover:not(:disabled) {
  background: var(--color-surface-container);
}
.zh-btn--ghost {
  background: transparent;
  color: var(--color-text-secondary);
  border-color: var(--color-border);
}
.zh-btn--ghost:hover:not(:disabled) {
  background: var(--color-surface-container-low);
  color: var(--color-text-primary);
}
.zh-btn--destructive {
  background: transparent;
  color: var(--color-error);
  border-color: color-mix(in srgb, var(--color-error) 35%, transparent);
}
.zh-btn--destructive:hover:not(:disabled) {
  background: color-mix(in srgb, var(--color-error) 8%, transparent);
}
/* Success (Bloque 13G) — misma arquitectura que --primary (fondo sólido +
   texto on-primary + borde a juego, oscurecido en hover vía color-mix).
   :disabled se resuelve con la regla compartida .zh-btn:disabled, igual que
   el resto de variantes — no necesita override propio. */
.zh-btn--success {
  background: var(--color-success);
  color: var(--color-on-primary);
  border-color: var(--color-success);
}
.zh-btn--success:hover:not(:disabled) {
  background: color-mix(
    in srgb,
    var(--color-success) 85%,
    var(--color-text-primary)
  );
}
/* CTA (SALES-DS-CTA-11) — acción principal de alto impacto de un flujo (p.ej.
   "Emitir Factura"). Mayor peso visual que --primary: mismo fondo/texto sólido
   sobre --color-primary, pero más grande, en mayúsculas y con más tracking.
   :disabled se resuelve con la regla compartida .zh-btn:disabled. */
.zh-btn--cta {
  height: auto;
  padding: 10px 24px;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}
.zh-btn--cta:hover:not(:disabled) {
  filter: brightness(1.1);
}
.zh-inline-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-primary);
  font-family: var(--font-family);
  font-size: var(--text-help-size);
  font-weight: var(--text-label-md-weight);
}
/* ── 3. FORMULARIOS — inputs ─────────────────────────────── */
input,
select,
textarea {
  font-family: var(--font-family);
  font-size: var(--text-body-md-size);
  color: var(--color-text-primary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 0 12px;
  height: 38px;
  width: 100%;
  outline: none;
  transition:
    border-color var(--transition),
    box-shadow var(--transition);
}
textarea {
  height: auto;
  min-height: 88px;
  padding: 8px 12px;
  line-height: 1.5;
  resize: vertical;
}
select {
  appearance: none;
  cursor: pointer;
  background-color: var(--color-surface-container-low);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 32px;
  border-color: var(--color-outline-variant, var(--color-border));
}
.zh-select--compact {
  font-size: var(--text-label-sm-size);
  height: auto;
  padding: 5px 32px 5px var(--space-2);
  border-width: 1.5px;
}
select:hover {
  background-color: var(--color-surface);
}
select:focus {
  background-color: var(--color-surface);
}
input::placeholder,
textarea::placeholder {
  color: var(--color-outline);
}
/* NUM-001 (AI-RULES/PR-RULES-CATALOG.md#f-05) — base de ZhDecimalInput/ZhNumberInput:
   todo dato numérico se alinea a la derecha por defecto. Componente base, no excepción local. */
.zh-numeric-input {
  text-align: right;
}
input:hover,
select:hover,
textarea:hover {
  border-color: var(--color-outline);
}
input:focus,
select:focus,
textarea:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
input:disabled,
select:disabled,
textarea:disabled {
  background: var(--color-surface-container-low);
  opacity: 0.6;
  cursor: not-allowed;
}
/* Checkbox / Radio */
input[type="checkbox"],
input[type="radio"] {
  width: 16px;
  height: 16px;
  border-radius: var(--radius-sm);
  padding: 0;
  flex-shrink: 0;
  cursor: pointer;
  accent-color: var(--color-primary);
}
input[type="radio"] {
  border-radius: var(--radius-pill);
}
/* Checkbox/radio inline label */
.zh-checkbox-label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  cursor: pointer;
  font-size: var(--text-body-md-size);
  font-weight: 500;
  color: var(--color-text-primary);
  padding: var(--space-2) 0;
  user-select: none;
}
.zh-checkbox-label input[type="checkbox"] {
  appearance: none;
  width: 18px;
  height: 18px;
  border: 2px solid var(--color-outline);
  border-radius: var(--radius-xs);
  background: var(--color-surface);
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
  transition:
    background var(--transition),
    border-color var(--transition);
}
.zh-checkbox-label input[type="checkbox"]:checked {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.zh-checkbox-label input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 1px;
  width: 6px;
  height: 10px;
  border: solid var(--color-on-primary);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.zh-checkbox-label input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.zh-checkbox-label input[type="checkbox"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.zh-checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-1) var(--space-4);
}
/* Date picker reset */
input[type="date"] {
  appearance: none;
}
/* Uppercase text inputs (e.g. SKU/codes) */
.zh-input--upper {
  text-transform: uppercase;
}
/* Densidad compacta reutilizable (Bloque 8A.1) — misma especificación que
   .zh-field--compact .zh-field-control input, pero aplicable directamente
   sobre un input suelto (p.ej. dentro de una celda de tabla), sin requerir
   el wrapper <ZHField density="compact">. Usar vía prop `density="compact"`
   de ZhTextInput/ZhDecimalInput/ZhDateInput/ZhSelect/ZhTextarea — mismo
   selector de clase para las 5, sin variante `.zh-select--compact`/
   `.zh-textarea--compact` propia (SSOT, ver Bloque 14A-1). */
.zh-input--compact {
  font-size: 13px;
  height: auto;
  padding: var(--space-2) var(--space-3);
  border-width: 1.5px;
}
/* Reserva espacio para el chevron del <select> en densidad compacta — el resto
   de campos de .zh-input--compact (input/textarea) no llevan icono de fondo. */
select.zh-input--compact {
  padding-right: 28px;
}
/* <ZHInputGroup>: agrupa un prefijo/sufijo (p.ej. "$") con un input Zh*Input en
   un solo control visual — reemplaza wrappers locales tipo `.pdl-line__cost-group`
   que cada módulo reimplementaba a mano cada vez que un input necesitaba un
   adorno. Reusa los mismos tokens que el input global (border/radius/focus-ring)
   en vez de definir los suyos propios (PURCHASES-DS-GLOBAL-COMPONENT-04). */
.zh-input-group {
  display: flex;
  align-items: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  overflow: hidden;
}
.zh-input-group:focus-within {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.zh-input-group__prefix,
.zh-input-group__suffix {
  padding: 0 var(--space-2);
  color: var(--color-text-secondary);
  font-family: var(--font-family);
  font-size: var(--text-body-md-size);
  flex-shrink: 0;
}
.zh-input-group input,
.zh-input-group select,
.zh-input-group textarea {
  border: none;
  background: transparent;
  box-shadow: none;
}
.zh-input-group input:focus,
.zh-input-group select:focus,
.zh-input-group textarea:focus {
  box-shadow: none;
  outline: none;
}
/* ── 4. CAMPOS (.zh-field) ────────────────────────────────── */
.zh-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
/* Label — estilo único oficial, compartido con .zh-auth-label y .pg-field-label */
/* .pg-field-label/.pg-header-field-label ELIMINADOS de este selector
   compartido (Bloque 12B) — sin consumidores. */
.zh-field-label,
.zh-auth-label {
  font-size: var(--text-label-md-size);
  font-weight: var(--text-label-md-weight);
  line-height: var(--text-label-md-height);
  color: var(--color-text-primary);
  text-transform: none;
  letter-spacing: normal;
}
.zh-field-required {
  color: var(--color-error);
  margin-left: 3px;
}
/* ZHFieldLabel standalone — mismo look-and-feel de .zh-field-label, sin depender del
   wrapper .zh-field. --md hereda la tipografía compartida; --sm cubre labels compactos de
   líneas/cards/métricas (antes sf-*/
pdl-* por módulo). */
.zh-field-label--md {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.zh-field-label--sm {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  letter-spacing: var(--text-label-sm-spacing);
  color: var(--color-text-primary);
}
.zh-field-label__required {
  color: var(--color-error);
}
.zh-field-label__optional {
  color: var(--color-text-secondary);
  font-weight: 400;
}
/* ZHMoneyValue — valor monetario de solo lectura, reemplaza el patrón manual
   "$" + formatMoney(value) repetido por módulo. Sin tokens dedicados de "strong"/"total"
   en el DS: --strong/--total reutilizan el mismo peso (700) ya usado por otros elementos
   destacados de zh-ui.css (.zh-auth-brand-name, .zh-avatar); --total usa además
   --text-body-lg-size (15px, ya existente) para diferenciarse como valor principal. */
/* ERP-DS-VISUAL-CONSISTENCY-CLOSEOUT-01 — money es una unidad visual
   indivisible: `white-space: nowrap` evita que el símbolo y el valor (dos
   <span> hijos del inline-flex) envuelvan a líneas distintas cuando el
   contenedor padre es angosto (tablas, mini-cards, cols de precio). */
.zh-money-value {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  color: var(--color-text-primary);
  white-space: nowrap;
}
.zh-money-value--start {
  justify-content: flex-start;
}
.zh-money-value--end {
  justify-content: flex-end;
}
.zh-money-value--default {
  font-size: var(--text-body-md-size);
  font-weight: var(--text-body-md-weight);
}
/* PURCHASES-DS-GLOBAL-COMPONENT-04 (revisión) — tier faltante para montos
   secundarios/de menor peso visual dentro de una línea (p.ej. ICE/IRBPNR junto
   al IVA principal): antes cada módulo envolvía el ZHMoneyValue en un div con
   font-size/color locales para lograr este look "de-enfatizado". */
.zh-money-value--muted {
  font-size: var(--text-help-size);
  font-weight: 400;
  color: var(--color-text-secondary);
}
.zh-money-value--strong {
  font-size: var(--text-body-md-size);
  font-weight: 700;
}
.zh-money-value--total {
  font-size: var(--text-body-lg-size);
  font-weight: 700;
}
/* PURCHASES-DS-GLOBAL-COMPONENT-04 — tier faltante para el total más
   destacado de una línea/card (p.ej. Total Neto de una línea de compra):
   ninguna emphasis existente llegaba a ese peso visual, así que cada módulo
   lo recreaba con font-size/weight locales. Mismo tamaño que ya tenía el
   look aprobado (20px/800, antes repartido entre erp-form-core.css 18px base
   + un override local de purchases-invoice.css a 20px) — solo se relocaliza
   la propiedad al componente global en vez de dos reglas CSS por pantalla. */
.zh-money-value--grand {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.5px;
}
.zh-money-value__symbol {
  color: var(--color-text-secondary);
}
.zh-money-value__amount {
  font-variant-numeric: tabular-nums;
}
.zh-money-value--empty {
  color: var(--color-text-secondary);
}
/* PURCHASES-DS-GLOBAL-COMPONENT-04 — <ZHDataValue>: dato de solo lectura no
   monetario (SKU, cantidad, stock, ingreso a inventario, etc.). Reemplaza los
   `.pdl-cost-val`/`.pdl-stock-val`/`.pdl-line__product-meta-value` locales que
   cada módulo reimplementaba con su propio tamaño/peso/font-family. Todas las
   variantes usan var(--font-family) salvo `--code` (única excepción
   monoespaciada, documentada, para códigos técnicos reales). */
.zh-data-value {
  font-family: var(--font-family);
  color: var(--color-text-primary);
}
.zh-data-value--default {
  font-size: var(--text-body-md-size);
  font-weight: 600;
}
.zh-data-value--muted {
  font-size: var(--text-help-size);
  font-weight: 400;
  color: var(--color-text-secondary);
}
/* ERP-DS-VISUAL-CONSISTENCY-CLOSEOUT-01 (fix) — `--numeric` daba el mismo
   font-weight (700) que `--strong`, sin diferenciarse más que por tamaño: en
   filas con varios datos numéricos seguidos (p.ej. "Producto recibido XML")
   todo se leía igual de negrita que el total, sin jerarquía. `--numeric` solo
   alinea dígitos (tabular-nums); el peso "medio" (600) es el mismo que
   `--default`, dejando `--strong` (700) como la única variante realmente en
   negrita. */
.zh-data-value--numeric {
  font-size: var(--text-body-md-size);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.zh-data-value--strong {
  font-size: var(--text-title-sm-size);
  font-weight: 700;
}
.zh-data-value--code {
  font-family: var(--font-family-mono);
  font-size: var(--text-help-size);
  font-weight: 600;
  color: var(--color-text-secondary);
}
.zh-data-value--tone-success {
  color: var(--color-success);
}
.zh-data-value--tone-danger {
  color: var(--color-error);
}
.zh-data-value--italic {
  font-style: italic;
}
/* ERP-DS-CODE-VALUE-02 — utilidad global para código técnico/documental
   (SKU, clave de acceso, secuencial, nro. de autorización, código SRI) cuando
   el markup ya tiene su propia clase local con tamaño/peso/color propios y
   solo necesita el font-family monoespaciado del DS — evita repetir
   `font-family: var(--font-family-mono)` en CSS de módulo. Combinar con la
   clase local existente, nunca reemplazarla. */
.zh-code-value {
  font-family: var(--font-family-mono);
}
/* ERP-DS-MONO-REMAINING-01 -- alias historico de .zh-code-value. Vivia como
   font-family-mono local en modules/inventory/kardex/pages/KardexPage.css
   pero tiene consumidores cruzados (Kardex y
   modules/purchases/components/PurchaseReceptionXmlViewModal.tsx via
   className="kdx-field-value kdx-mono") -- se promueve aca para que ningun
   modulo vuelva a definir font-family-mono local, sin tener que tocar esos
   consumidores existentes. Nuevos usos deberian preferir .zh-code-value. */
.kdx-mono {
  font-family: var(--font-family-mono);
}
/* <ZHInfoRow>: par label/valor compacto para paneles de detalle (líneas de
   documento, contexto XML, inventario, info comercial) — reemplaza pares
   `.pdl-cost-label`/`.pdl-cost-val` locales repetidos por módulo. Solo da
   layout: la tipografía la deciden `label` (normalmente ZHFieldLabel size="sm")
   y `value` (ZHDataValue/ZHMoneyValue) que el consumidor pasa como children. */
.zh-info-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
}
.zh-info-row + .zh-info-row {
  margin-top: 2px;
}
.zh-info-row--wide {
  align-items: flex-start;
}
.zh-info-row--wide .zh-info-row__value {
  text-align: right;
  white-space: normal;
}
.zh-info-row__value {
  text-align: right;
  white-space: nowrap;
}
.zh-field-control {
  position: relative;
}
.zh-field-control input,
.zh-field-control select,
.zh-field-control textarea {
  width: 100%;
}
/* Error state */
.zh-field--error .zh-field-control input,
.zh-field--error .zh-field-control select,
.zh-field--error .zh-field-control textarea {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 12%, transparent);
}
/* Success state */
.zh-field--success .zh-field-control input,
.zh-field--success .zh-field-control select {
  border-color: var(--color-success);
}
/* Read-only */
.zh-field--readonly .zh-field-control input,
.zh-field--readonly .zh-field-control select {
  border-style: dashed;
}
/* Compact (densidad de grilla de líneas — reemplaza al antiguo .pf-field) */
.zh-field--compact {
  gap: 4px;
}
.zh-field--compact .zh-field-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.zh-field--compact .zh-field-control input,
.zh-field--compact .zh-field-control select,
.zh-field--compact .zh-field-control textarea {
  /* Replica exacta del tamaño de .pf-field (erp-form.css) — deliberadamente por debajo
     de --text-body-md-size para preservar la densidad de las grillas de líneas. */
  font-size: 13px;
  height: auto;
  padding: var(--space-2) var(--space-3);
  border-width: 1.5px;
}
.zh-field--compact .zh-field-control textarea {
  min-height: 52px;
}
.zh-field--compact .zh-field-hint {
  font-size: 11px;
}
/* Hints */
.zh-field-hint {
  font-size: var(--text-help-size);
  line-height: var(--text-help-height);
  color: var(--color-text-secondary);
  margin: var(--space-1) 0 0;
}
.zh-field-hint--error {
  color: var(--color-error);
}
.zh-field-hint--success {
  color: var(--color-success);
}
.zh-field-hint--warning {
  color: var(--color-warning);
}
.zh-field-hint--info {
  color: var(--color-primary);
}
.zh-field-hint--muted {
  color: var(--color-outline);
}
/* Grid de campos */
.zh-grid {
  display: grid;
  gap: 14px;
}
.zh-grid--1 {
  grid-template-columns: 1fr;
}
.zh-grid--2 {
  grid-template-columns: 1fr 1fr;
}
.zh-grid--3 {
  grid-template-columns: 1fr 1fr 1fr;
}
.zh-grid--4 {
  grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 720px) {
  .zh-grid--4 {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 560px) {
  .zh-grid--2,
  .zh-grid--3,
  .zh-grid--4 {
    grid-template-columns: 1fr;
  }
}
.zh-col-span-2 {
  grid-column: 1 / span 2;
}
/* .zh-col-span-3 ELIMINADO (Bloque 12B) — sin consumidores. */
/* Acciones del formulario */
.zh-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
}
.zh-form-actions-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: var(--space-4);
}
.zh-form-actions-row--end {
  justify-content: flex-end;
}
.zh-form-actions-row--lg {
  margin-top: var(--space-8);
}
@media (max-width: 440px) {
  .zh-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .zh-actions .zh-btn {
    width: 100%;
    justify-content: center;
  }
  .zh-form-actions-row {
    flex-direction: column;
    align-items: stretch;
  }
  .zh-form-actions-row .zh-btn {
    width: 100%;
    justify-content: center;
  }
}
/* ── 5. ALERTAS / NOTICES ────────────────────────────────── */
.zh-form-alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  margin-bottom: var(--space-4);
}
.zh-form-alert--success {
  background: color-mix(in srgb, var(--color-success) 8%, transparent);
  border-color: color-mix(in srgb, var(--color-success) 30%, transparent);
  color: var(--color-success);
}
.zh-form-alert--error {
  background: color-mix(in srgb, var(--color-error) 8%, transparent);
  border-color: color-mix(in srgb, var(--color-error) 28%, transparent);
  color: var(--color-error);
}
.zh-form-alert--warning {
  background: color-mix(in srgb, var(--color-warning) 8%, transparent);
  border-color: color-mix(in srgb, var(--color-warning) 28%, transparent);
  color: var(--color-warning);
}
.zh-form-alert--info {
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
  border-color: color-mix(in srgb, var(--color-primary) 25%, transparent);
  color: var(--color-primary);
}
.zh-form-alert--attention {
  background: rgba(194, 84, 11, 0.08);
  border-color: rgba(194, 84, 11, 0.28);
  color: var(--color-attention);
}
.zh-form-alert--neutral {
  background: var(--color-surface-container);
  border-color: var(--color-border);
  color: var(--color-text-secondary);
}
.zh-form-alert-icon {
  flex-shrink: 0;
  margin-top: 1px;
  width: 18px;
  height: 18px;
}
.zh-form-alert-message {
  font-size: var(--text-body-md-size);
  font-weight: 600;
  margin: 0;
  color: inherit;
}
.zh-form-alert-detail {
  font-size: var(--text-body-md-size);
  margin: 3px 0 0;
  opacity: 0.85;
}
.zh-page-notice {
  margin: 0 0 var(--space-4);
}
.zh-page-notice:last-child {
  margin-bottom: 0;
}
.zh-page-notice .zh-form-alert {
  margin-bottom: 0;
}
/* ── 6. FORM HEADER / BODY / SECTION ─────────────────────── */
.zh-form-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 18px 20px;
  color: var(--color-on-primary);
  background: var(--gradient-brand);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
}
.zh-form-header-left {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.zh-form-header-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.zh-form-header-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  transition:
    background var(--transition),
    color var(--transition);
  flex-shrink: 0;
}
.zh-form-header-close .material-symbols-outlined {
  font-size: 18px;
}
.zh-form-header-close:hover {
  background: rgba(255, 255, 255, 0.22);
  color: var(--color-on-primary);
}
.zh-form-header-close:focus-visible {
  outline: 2px solid var(--color-on-primary);
  outline-offset: 1px;
}
.zh-form-logo {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.12);
  outline: 1px solid rgba(255, 255, 255, 0.18);
}
.zh-form-header-text {
  min-width: 0;
}
.zh-form-title {
  margin: 0;
  font-size: var(--text-headline-sm-size);
  font-weight: var(--text-headline-sm-weight);
  line-height: var(--text-headline-sm-height);
  color: var(--color-on-primary);
  letter-spacing: 0.01em;
}
.zh-form-subtitle {
  margin: var(--space-1) 0 0;
  font-size: var(--text-body-md-size);
  font-weight: 400;
  color: var(--color-on-primary);
  opacity: 0.82;
}
.zh-form-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  background: rgba(255, 255, 255, 0.14);
  outline: 1px solid rgba(255, 255, 255, 0.2);
  color: var(--color-on-primary);
}
.zh-form-zh-logo {
  height: 16px;
  width: auto;
  filter: brightness(0) invert(1);
  opacity: 0.9;
}
.zh-form-body {
  background: var(--color-surface);
  border: 0.5px solid var(--color-border);
  padding: var(--space-5) var(--space-6) var(--space-6);
  border-radius: 0 0 var(--radius-xl) var(--radius-xl);
}
.zh-form-body--standalone {
  border-radius: var(--radius-xl);
}
.zh-form-section {
  padding: var(--space-4) 0;
  border-bottom: 0.5px solid var(--color-border);
}
.zh-form-section:last-child {
  border-bottom: none;
}
.zh-form-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 var(--space-3);
  font-size: var(--text-title-sm-size);
  font-weight: var(--text-title-sm-weight);
  line-height: var(--text-title-sm-height);
  color: var(--color-text-primary);
}
.zh-form-section-title::before {
  content: "";
  width: 3px;
  height: 14px;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  flex-shrink: 0;
}
.zh-form-section-desc {
  margin: -6px 0 var(--space-3);
  font-size: 12px;
  color: var(--color-text-secondary);
}
/* ── Simulador de precio/margen (CreateItemModal — Compras) ──────────────
   Misma grilla oficial (.zh-grid--4) que el resto del modal — esta clase
   solo agrega el fondo de "tarjeta de resultado" alrededor de esa grilla,
   nunca un sistema de alineación paralelo. */
.citm-margin-sim {
  margin-top: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.citm-margin-sim__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
}
.citm-margin-sim__label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-secondary);
}
.citm-margin-sim__value {
  font-size: 18px;
  font-weight: 800;
  color: var(--color-text-primary);
}
.citm-margin-sim__value--pct {
  font-size: 20px;
  color: var(--color-primary);
}
.citm-margin-sim__value--neg {
  color: var(--color-error);
}
@media (max-width: 520px) {
  .zh-form-body {
    padding: 18px;
  }
  .zh-form-header {
    flex-wrap: wrap;
  }
  .zh-form-title,
  .zh-form-subtitle {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
/* ── 7. TENANT HEADER ────────────────────────────────────── */
.zh-tenant-header {
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--gradient-brand);
  border: 0.5px solid rgba(255, 255, 255, 0.1);
}
/* App-shell variant (.zh-app-tenantHeader) styled in components/zh/ZHAppTenantHeader.css */
.zh-tenant-badge {
  background: rgba(255, 255, 255, 0.15);
  color: white;
  font-size: 10px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  border: 0.5px solid rgba(255, 255, 255, 0.2);
}
/* ── 8. TOGGLE ────────────────────────────────────────────── */
.zh-toggle {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: 12px 14px;
  border-radius: var(--radius-lg);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-border);
}
.zh-toggle-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.zh-toggle-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-primary);
}
.zh-toggle-desc {
  font-size: 12px;
  color: var(--color-text-secondary);
}
.zh-toggle-switch {
  position: relative;
  width: 42px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-container);
  border: 1px solid var(--color-border);
  cursor: pointer;
  flex-shrink: 0;
  transition:
    background var(--transition),
    opacity var(--transition);
}
.zh-toggle-switch[aria-checked="true"] {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.zh-toggle-switch.is-pressed {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}
.zh-toggle-switch[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
}
.zh-toggle-thumb {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  box-shadow: var(--shadow-xs);
  transition: left var(--transition);
}
.zh-toggle-switch[aria-checked="true"] .zh-toggle-thumb {
  left: 21px;
}
/* ── 9. CARDS ────────────────────────────────────────────── */
.card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow var(--transition);
}
.card-header {
  padding: var(--space-5);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.card-body {
  padding: var(--space-5);
}
/* Size variant — larger radius (dashboard, overview panels) */
.card--xl {
  border-radius: var(--radius-xl);
}
/* Table Card (sin padding lateral en tabla) */
.table-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  overflow-x: auto;
  width: 100%;
}
.table-card .table-card-body {
  padding: 0;
}
.table-card > form,
.table-card .table-card-body > form {
  padding: var(--space-5);
}
/* Table scroll wrapper (Bloque 12F-1) — SSOT del patrón "wrapper neutro de
   scroll horizontal para <table>" (una sola declaración: overflow-x: auto).
   Consolida 4 clases duplicadas detectadas en la auditoría 12F-0
   (.pg-overflow-x en legacy-pages.css, .prd-table-wrap en items-catalog.css,
   .rpt-table-wrap en ReportPageTemplate.css, .security-scroll en
   SecuritySettingsPage.css) — mismo comportamiento exacto, mismas 19+7+1+1
   consumidores reales repartidos en 4 archivos distintos. Esta fase solo
   agrega la clase SSOT; las 4 clases legacy y sus consumidores TSX no se
   tocan todavía (Bloque 12F-2). Auditoría 15A (alcance: prefijos
   pf-/prd-/pg-/md-/sales-/pur-/br-/zh-input): .pg-overflow-x y
   .prd-table-wrap quedaron sin consumidores TSX y fueron eliminadas.
   .security-scroll ya no existe (eliminada en Bloque 12F-3C, ver
   SecuritySettingsPage.css). .rpt-table-wrap quedó sin consumidores TSX
   detectados en esta auditoría pero está fuera del alcance de prefijos de
   15A (prefijo rpt-) — no se elimina aquí, queda para un barrido dedicado.
   Distinta de .table-card: esta es un wrapper
   neutro sin chrome (sin borde/sombra/radio/padding), para usar cuando la
   tabla no necesita la "card" completa — ej. <div className="table-scroll">
   <table className="table">...</table></div>. */
.table-scroll {
  overflow-x: auto;
}
/* Fila/registro de detalle compacta con delimitación visual por borde/sombra.
   Distinta de .card: esta es una unidad de LISTA (un registro entre varios,
   ej. una línea de compra/venta expandible con sub-bloques), más liviana
   (radius-md + shadow-xs en vez de radius-lg + shadow-sm) y sin header/body
   ni overflow:hidden — el consumidor define su propio padding/gutter interno
   y horizontal. Pensada para que varios registros consecutivos queden juntos
   sin perder separación visual (borde+sombra, no margen grande) — validado
   primero en Compras (.pdl-line-row). Aplicar solo a listas donde cada
   registro es un bloque/tarjeta con contenido variable, no a filas de tabla
   densa ni a componentes que ya tengan su propia tarjeta. Sin hover/focus:
   no es una fila clickeable/interactiva por sí sola. */
.zh-detail-line {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-xs);
  margin-bottom: var(--space-2);
}
.zh-detail-line:last-child {
  margin-bottom: 0;
}
/* ── 10. TABLAS ──────────────────────────────────────────── */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-body-md-size);
}
.table th {
  text-align: left;
  padding: 11px var(--space-4);
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  letter-spacing: var(--text-label-sm-spacing);
  text-transform: uppercase;
  color: var(--color-on-surface-variant);
  background: var(--color-surface-primary-tint);
  border-bottom: 1px solid var(--color-border);
}
.table td {
  padding: 12px var(--space-4);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-primary);
  vertical-align: middle;
  transition: background var(--transition);
}
.table tr:last-child td {
  border-bottom: none;
}
.table tbody tr:hover td {
  background: var(--color-surface-container-low);
}
/* Compact variant */
.table--compact th {
  padding: 8px var(--space-3);
}
.table--compact td {
  padding: 8px var(--space-3);
}
/* Neutral variant (Bloque 9B) — reproduce la identidad visual histórica de
   .pf-table (erp-form-core.css, ya en retiro): encabezado gris neutro en vez
   del tinte de marca, texto más claro, borde de encabezado más grueso, borde
   de celda visible incluso en la última fila. Aditiva: solo toca color/
   fondo/borde/tamaño de fuente, nunca padding — combina sin conflicto con
   .table--compact (que solo toca padding). No usar sola: siempre junto a
   .table, ej. className="table table--compact table--neutral". */
.table--neutral {
  font-size: 13px;
}
.table--neutral th {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--color-text-secondary);
  background: var(--color-surface-container-low);
  border-bottom: 2px solid var(--color-border);
}
.table--neutral td {
  border-bottom: 1px solid var(--color-surface-container-low);
}
.table--neutral tr:last-child td {
  border-bottom: 1px solid var(--color-surface-container-low);
}
/* Align-top variant (Bloque 12D) — para tablas con contenido multilínea por
   celda (p. ej. descripción + metadatos apilados, o un chip + un control de
   búsqueda inline) donde el centrado vertical por defecto de .table descoloca
   el contenido superior. Aditiva: solo toca vertical-align, nunca padding —
   combina sin conflicto con .table--compact y .table--neutral. No usar sola:
   siempre junto a .table, ej. className="table table--neutral table--align-top". */
.table--align-top td {
  vertical-align: top;
}
/* Matrix/spreadsheet variant (Bloque 12F-3B) — para tablas tipo matriz (filas
   = entidad, columnas = atributos/permisos), donde cada celda es una unidad
   visual propia con borde en las 4 caras y contenido centrado (p. ej. un
   toggle por celda), en vez del estilo "lista con separador inferior" de
   .table. Detectada como necesidad real en la auditoría 12C/12F-3A
   (security-table). Aditiva: solo toca border/text-align, nunca padding —
   combina con .table--compact y .table--neutral (debe declararse después de
   .table--neutral en el className para que el borde completo prevalezca
   sobre el border-bottom de la variante neutral). No usar sola: siempre
   junto a .table, ej.
   className="table table--compact table--neutral table--matrix". */
.table--matrix th,
.table--matrix td {
  border: 1px solid var(--color-border);
  text-align: center;
}
.table--matrix tr:last-child td {
  border-bottom: 1px solid var(--color-border);
}
/* Sticky-column pattern (Bloque 12D, completado en 12F-3B) — capacidad
   preparada, sin consumidores aún. Detectada como necesidad real en la
   auditoría 12C (security-table): una tabla con scroll horizontal necesita
   fijar una columna (típicamente la primera, identificatoria) mientras el
   resto se desplaza. No se asume "primera columna" automáticamente porque
   .table se usa con distinto número y orden de columnas según el módulo —
   la celda a fijar debe marcarse explícitamente. Requiere un contenedor con
   overflow-x: auto (ya lo provee .table-card, o .table-scroll). Uso
   previsto, cuando se autorice una migración real:
     <table className="table table--sticky-column">
       <th className="table__sticky-cell">...</th>
       ...
       <td className="table__sticky-cell">...</td>
   No mezclar padding aquí: solo position/left/z-index/background/text-align.
   La celda pegajosa se mantiene alineada a la izquierda aunque la tabla use
   .table--matrix (centrado por defecto), porque típicamente aloja contenido
   de identidad multilínea, no un valor centrado. Completado en 12F-3B con
   dos casos detectados al revisar el patrón contra un consumidor real:
   (1) el fondo del <th> pegajoso debe seguir al de .table--neutral cuando
   ambas variantes se combinan; (2) el hover de fila (.table tbody
   tr:hover td) debe alcanzar también a la celda pegajosa — sin esto, al
   pasar el mouse sobre una fila se vería una celda sin resaltar en medio de
   una fila resaltada. */
.table--sticky-column .table__sticky-cell {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--color-surface);
  text-align: left;
}
.table--sticky-column th.table__sticky-cell {
  background: var(--color-surface-primary-tint);
}
.table--neutral.table--sticky-column th.table__sticky-cell {
  background: var(--color-surface-container-low);
}
.table tbody tr:hover .table__sticky-cell {
  background: var(--color-surface-container-low);
}
/* .zh-tr-clickable ELIMINADO (Bloque 12B) — sin consumidores. */
/* ── 11. BADGES ──────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--text-badge-size);
  font-weight: var(--text-badge-weight);
  line-height: var(--text-badge-height);
  white-space: nowrap;
}
/* .badge--green/--red/--gray/--blue/--orange ELIMINADOS (Bloque 12B) — sin
   consumidores reales (el variantClassMap de <Badge> en PageShell.tsx nunca
   produce estos nombres literalmente; solo aparecían en un comentario de
   ZHForm.tsx, ya corregido). */
/* Status badges (solid) */
.badge--success {
  background: var(--color-success);
  color: var(--color-on-primary);
}
/* .badge--danger ELIMINADO (Bloque 12B) — duplicado exacto de .badge--error,
   nunca producido por variantClassMap (no existe variante "danger"). */
.badge--error {
  background: var(--color-error);
  color: var(--color-on-primary);
}
.badge--warning {
  background: var(--color-warning);
  color: var(--color-on-primary);
}
.badge--info {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.badge--neutral {
  background: var(--color-surface-container);
  color: var(--color-text-secondary);
}
/* Shape / text modifiers */
.badge--md {
  border-radius: var(--radius-md);
}
.badge--upper {
  text-transform: uppercase;
  letter-spacing: var(--text-label-sm-spacing);
}
/* PURCHASES-DS-GLOBAL-COMPONENT-04 — único modificador de <Badge> con
   tipografía monoespaciada: para códigos técnicos (SKU, código de
   proveedor/auxiliar, secuenciales), nunca por defecto. Combina con
   cualquier `variant` de color (p.ej. neutral para código normal, warning
   para código con alerta) en vez de necesitar un chip local por módulo. */
.badge--code {
  font-family: var(--font-family-mono);
}
/* .zh-inline-check ELIMINADO (Bloque 12B) -- sin consumidores. */
/* ── 12. PAGE SHELL / LAYOUT ────────────────────────────── */
.page-shell {
  width: 100%;
  max-width: none;
}
.page-shell-heading {
  margin-bottom: var(--space-4);
}
.page-shell--compactHeading {
  margin-top: -8px;
}
.zh-page-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
/* Page shell focus */
.page-shell button:focus-visible,
.page-shell a:focus-visible,
.table-card button:focus-visible,
.table-card a:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
/* .zh-card-section y familia (-header/-title/-right/-body) ELIMINADOS
   (Bloque 12B) -- sin consumidores. */
/* ── 14. SCREEN HEADING ──────────────────────────────────── */
.zh-screen-heading {
  margin: 0 0 var(--space-4);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--color-border);
}
.zh-screen-heading-kicker {
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  letter-spacing: var(--text-label-sm-spacing);
  text-transform: uppercase;
  color: var(--color-text-secondary);
  margin-bottom: 6px;
}
.zh-screen-heading-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.zh-screen-heading-main {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-width: 0;
  flex: 1;
}
.zh-screen-heading-chip {
  width: 4px;
  height: 28px;
  flex-shrink: 0;
  margin-top: 3px;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
}
.zh-screen-heading-copy {
  min-width: 0;
}
.zh-screen-heading-title {
  margin: 0;
  font-size: var(--text-headline-md-size);
  font-weight: var(--text-headline-md-weight);
  letter-spacing: var(--text-headline-md-spacing);
  color: var(--color-text-primary);
  line-height: var(--text-headline-md-height);
}
.zh-screen-heading-sub {
  margin: var(--space-1) 0 0;
  font-size: var(--text-body-md-size);
  color: var(--color-text-secondary);
  line-height: var(--text-body-md-height);
}
.zh-screen-heading-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* ── 16. ESTADOS ─────────────────────────────────────────── */
.empty-state,
.loading-state {
  text-align: center;
  padding: 48px var(--space-6);
  color: var(--color-text-secondary);
  font-size: 14px;
  border-radius: var(--radius-lg);
  border: 1px dashed var(--color-border);
}
.error-state {
  padding: 14px var(--space-5);
  background: color-mix(in srgb, var(--color-error) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-error) 25%, transparent);
  color: var(--color-error);
  border-radius: var(--radius-md);
  font-size: 13px;
}
/* ── 17. MODALES ─────────────────────────────────────────── */
@keyframes zh-modal-in {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@keyframes zh-overlay-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.zh-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(25, 28, 30, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: var(--space-6);
  backdrop-filter: blur(2px);
  animation: zh-overlay-in 0.15s ease both;
}
.zh-modal {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  width: 100%;
  max-width: 520px;
  animation: zh-modal-in 0.18s cubic-bezier(0.4, 0, 0.2, 1) both;
}
/* ── Size variants ── */
.zh-modal--sm {
  max-width: 420px;
}
.zh-modal--md {
  max-width: 520px;
}
.zh-modal--lg {
  max-width: min(720px, 95vw);
}
.zh-modal--xl {
  max-width: min(900px, 95vw);
}
.zh-modal--2xl {
  max-width: min(1080px, 95vw);
}
.zh-modal--full {
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 32px);
}
.zh-modal-body {
  padding: var(--space-5) var(--space-6) var(--space-6);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.zh-modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-container-low);
  flex-shrink: 0;
}
/* .zh-modal-header/.zh-modal-title/.zh-modal-close ELIMINADOS (Bloque 12B) --
   ya documentados como "legacy" (prefer ZHModal component), 0 consumidores
   confirmados. */
/* ── 17b. DRAWER LATERAL (no modal — mantiene la tabla de fondo visible) ── */
@keyframes zh-drawer-in {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
  }
}
.zh-drawer-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  /* Sin backdrop oscuro a propósito: el usuario debe seguir viendo la tabla de fondo. */
  background: transparent;
  display: flex;
  justify-content: flex-end;
}
.zh-drawer {
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  border-left: 1px solid var(--color-border);
  height: 100%;
  display: flex;
  flex-direction: column;
  width: 100%;
  animation: zh-drawer-in 0.2s cubic-bezier(0.4, 0, 0.2, 1) both;
}
.zh-drawer--sm {
  max-width: 380px;
}
.zh-drawer--md {
  max-width: 460px;
}
.zh-drawer--lg {
  max-width: min(640px, 95vw);
}
.zh-drawer-body {
  padding: 20px 22px 24px;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.zh-drawer-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-container-low);
  flex-shrink: 0;
}
@media (max-width: 640px) {
  .zh-modal-overlay {
    padding: var(--space-3);
  }
  .zh-modal--lg,
  .zh-modal--xl,
  .zh-modal--2xl {
    max-width: calc(100vw - 24px);
  }
  .zh-modal-body {
    padding: var(--space-4);
  }
  .zh-modal-footer {
    padding: var(--space-3) var(--space-4);
  }
  .zh-drawer--sm,
  .zh-drawer--md,
  .zh-drawer--lg {
    max-width: 100vw;
  }
}
/* ── 17b. ZHDataTable / ZHFilterBar ──────────────────────── */
.zh-datatable-row--clickable {
  cursor: pointer;
}
.zh-datatable-row--clickable:hover {
  background: var(--color-surface-container-low);
}
.zh-datatable-total {
  color: var(--color-text-secondary);
  font-size: 13px;
}
.zh-filterbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}
.zh-filterbar__field {
  min-width: 160px;
}
.zh-filterbar__field--grow {
  flex: 1;
  min-width: 220px;
}
.zh-filterbar__clear {
  margin-left: auto;
}
.zh-filterbar__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  width: 100%;
}
/* ── 18. CONFIRM DIALOG (.zh-confirm-*) ─────────────────── */
.zh-confirm-dialog {
  max-width: 440px;
}
.zh-confirm-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.zh-confirm-icon {
  font-size: 22px;
  flex-shrink: 0;
}
.zh-confirm-title {
  font-size: 15px;
  font-weight: 600;
  margin: 0;
  color: var(--color-text-primary);
}
.zh-confirm-body {
  padding: var(--space-5);
}
.zh-confirm-message {
  font-size: 13px;
  color: var(--color-text-secondary);
  margin: 0;
  line-height: 1.6;
}
/* ── 19. UTILIDADES DE LAYOUT Y ESPACIADO ──────────────── */
/* Flexbox */
.zh-flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.zh-flex-end {
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 10px;
}
/* .zh-inline-row/.zh-inline-row-right/.zh-wrap/.zh-relative/.zh-grid-row
   ELIMINADOS (Bloque 12B) — sin consumidores. */
.zh-stack {
  display: flex;
  flex-direction: column;
}
/* Spacing */
/* .zh-m-0 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-mt-4 {
  margin-top: var(--space-1);
}
/* .zh-mt-6 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-mt-8 {
  margin-top: var(--space-2);
}
.zh-mt-10 {
  margin-top: 10px;
}
/* .zh-mt-12 ELIMINADO (Bloque 12B) — sin consumidores. */
/* .zh-mt-14 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-mt-16 {
  margin-top: var(--space-4);
}
.zh-mb-4 {
  margin-bottom: var(--space-1);
}
/* .zh-mb-6 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-mb-8 {
  margin-bottom: var(--space-2);
}
/* .zh-mb-10 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-mb-12 {
  margin-bottom: var(--space-3);
}
/* .zh-mb-14 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-mb-16 {
  margin-bottom: var(--space-4);
}
/* Gap */
/* .zh-gap-3 ELIMINADO (Bloque 12B) — sin consumidores. */
/* .zh-gap-6 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-gap-8 {
  gap: var(--space-2);
}
/* .zh-gap-10 ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-gap-12 {
  gap: var(--space-3);
}
/* .zh-gap-14 ELIMINADO (Bloque 12B) — sin consumidores. */
/* .zh-gap-16 ELIMINADO (Bloque 12B) — sin consumidores. */
/* Text */
/* .zh-text-center ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-text-muted {
  color: var(--color-text-secondary);
}
.zh-text-xs {
  font-size: var(--text-label-sm-size);
}
/* ERP-DS-VISUAL-CONSISTENCY-CLOSEOUT-01 — título de fila/card (nombre de
   producto/item en línea de documento o card de venta): peso destacado
   compartido por Compras (`.pdl-line__product-name`) y Ventas
   (`.sf-product__name`), antes duplicado en cada módulo con su propio
   font-weight/color locales. La clase local conserva solo tamaño (puede
   variar por densidad de pantalla) y layout; el peso/color vienen de aquí. */
.zh-row-title {
  font-weight: 700;
  color: var(--color-text-primary);
}
/* .zh-items-end ELIMINADO (Bloque 12B) — sin consumidores. */
/* Color swatch (type="color" input) */
.zh-color-swatch {
  width: 48px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
  flex-shrink: 0;
}
/* Icon sizes (material-symbols-outlined) */
.zh-icon-sm {
  font-size: 14px;
}
.zh-icon-md {
  font-size: 16px;
}
.zh-icon-lg {
  font-size: 18px;
}
.zh-icon-xl {
  font-size: 32px;
}
/* .sr-only/.zh-visually-hidden ELIMINADOS (Bloque 12B) — sin consumidores. */
/* ── 20. AUTH LAYOUT ─────────────────────────────────────── */
.zh-auth-bg {
  min-height: 100vh;
  background: linear-gradient(
    135deg,
    var(--color-surface-primary-tint) 0%,
    var(--color-surface-container-low) 50%,
    var(--color-surface-primary-tint) 100%
  );
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  padding: var(--space-6);
}
.zh-auth-bg-orb {
  position: fixed;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.55;
  pointer-events: none;
  z-index: 0;
}
.zh-auth-bg-orb--tr {
  width: 420px;
  height: 420px;
  top: -80px;
  right: -80px;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--color-primary) 28%, transparent) 0%,
    transparent 70%
  );
}
.zh-auth-bg-orb--bl {
  width: 360px;
  height: 360px;
  bottom: -60px;
  left: -60px;
  background: radial-gradient(
    circle,
    rgba(60, 97, 136, 0.2) 0%,
    transparent 70%
  );
}
.zh-auth-bg-grid {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: radial-gradient(
    var(--color-outline-variant) 1px,
    transparent 1px
  );
  background-size: 32px 32px;
  opacity: 0.03;
}
.zh-auth-wrapper {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 440px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
}
.zh-auth-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}
.zh-auth-brand-icon {
  width: 52px;
  height: 52px;
  border-radius: var(--radius-lg);
  background: var(--gradient-brand);
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-md);
  color: var(--color-on-primary);
  font-size: 24px;
}
.zh-auth-brand-name {
  font-size: 22px;
  font-weight: 700;
  color: var(--color-text-primary);
  letter-spacing: -0.02em;
  margin: 0;
}
.zh-auth-brand-sub {
  font-size: 13px;
  color: var(--color-text-secondary);
  margin: 0;
}
/* ── 21. AVATAR ──────────────────────────────────────────── */
.zh-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
  flex-shrink: 0;
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
  user-select: none;
}
/* .zh-avatar--sm/--lg ELIMINADOS (Bloque 12B) — sin consumidores; único
   generador dinámico de variante (CompanySelectPage.tsx) solo cicla
   primary/secondary/tertiary. */
.zh-avatar--square {
  border-radius: var(--radius-md);
}
.zh-avatar--primary {
  background: color-mix(in srgb, var(--color-primary) 14%, transparent);
  color: var(--color-primary);
}
.zh-avatar--secondary {
  background: color-mix(in srgb, var(--color-secondary) 14%, transparent);
  color: var(--color-secondary);
}
.zh-avatar--tertiary {
  background: color-mix(in srgb, var(--color-tertiary) 14%, transparent);
  color: var(--color-tertiary);
}
/* .zh-avatar--success/--error ELIMINADOS (Bloque 12B) — sin consumidores. */
/* ── 22. STATUS BADGE ────────────────────────────────────── */
.zh-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  letter-spacing: var(--text-label-sm-spacing);
  white-space: nowrap;
}
.zh-status::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex-shrink: 0;
}
.zh-status--active {
  background: color-mix(in srgb, var(--color-success) 10%, transparent);
  color: var(--color-success);
}
.zh-status--active::before {
  background: var(--color-success);
}
.zh-status--suspended {
  background: color-mix(in srgb, var(--color-warning) 10%, transparent);
  color: var(--color-warning);
}
.zh-status--suspended::before {
  background: var(--color-warning);
}
.zh-status--inactive {
  background: var(--color-surface-container);
  color: var(--color-text-secondary);
}
.zh-status--inactive::before {
  background: var(--color-outline);
}
.zh-status--pending {
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  color: var(--color-primary);
}
.zh-status--pending::before {
  background: var(--color-primary);
}
/* PURCHASES-DS-GLOBAL-COMPONENT-04 — variante que faltaba para indicadores
   críticos/error (p.ej. stock crítico) — antes cada módulo reimplementaba el
   punto de color a mano (`.pdl-stock-label--danger::before { content: "● " }`). */
.zh-status--danger {
  background: color-mix(in srgb, var(--color-error) 10%, transparent);
  color: var(--color-error);
}
.zh-status--danger::before {
  background: var(--color-error);
}
/* ── 23. ENTITY ITEM (lista de selección clickeable) ─────── */
.zh-entity-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 12px var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  transition:
    border-color var(--transition),
    box-shadow var(--transition);
}
.zh-entity-item:hover {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-xs);
}
.zh-entity-item-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.zh-entity-item-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zh-entity-item-sub {
  font-size: 11px;
  color: var(--color-text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zh-entity-item-right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}
/* 24. METRIC CARD -- .zh-metric-card y familia (.zh-metric-card-top,
   .zh-metric-label, .zh-metric-trend/--up/--warning/--neutral,
   .zh-metric-value, .zh-metric-sparkline, .zh-metric-sparkline-bar)
   ELIMINADOS (Bloque 6B) -- 0 consumidores confirmados en ningun .tsx/.ts
   del repositorio (ni literal ni por construccion dinamica de clase). El
   patron de KPI card realmente adoptado es .pg-kpi (styles/page-template.css,
   componente ReportKpiCard, 16 consumidores) -- pendiente de decision de
   consolidacion en un bloque posterior.
*/
/* ── 25. GLOBAL TOPBAR ───────────────────────────────────── */
/* Moved to components/zh/ZHAppTenantHeader.css (app-shell header only). */
/* .zh-app-footer y familia (.zh-app-footer-inner/-brand/-brand-name/-copy/
   -nav/-link) ELIMINADOS (Bloque 12B) -- ningun componente de app-shell
   renderiza un footer global; 0 consumidores confirmados. */
/* ── 27. AUTH FORM CARD ──────────────────────────────────── */
/* Shared by ForgotPasswordPage, ResetPasswordPage, PasswordResetPage (formerly §24) */
.zh-auth-card {
  width: 100%;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  padding: var(--space-8);
}
/* Modificador: card sin padding propio, para componer con .zh-auth-card-body
   cuando la card necesita una región interna (p.ej. footer full-bleed). */
.zh-auth-card--flush {
  padding: 0;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.zh-auth-card-body {
  padding: var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.zh-auth-card-body--center {
  text-align: center;
}
.zh-auth-card-header {
  text-align: center;
  margin-bottom: var(--space-8);
}
.zh-auth-card-title {
  font-size: var(--text-headline-lg-size);
  font-weight: var(--text-headline-lg-weight);
  letter-spacing: var(--text-headline-lg-spacing);
  line-height: var(--text-headline-lg-height);
  color: var(--color-text-primary);
  margin: 0 0 12px;
}
.zh-auth-card-desc {
  font-size: var(--text-body-md-size);
  line-height: var(--text-body-md-height);
  color: var(--color-on-surface-variant);
  margin: 0;
}
/* Form */
.zh-auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.zh-auth-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.zh-auth-label {
  display: block;
  /* tipografía heredada de la regla unificada .zh-field-label/.zh-auth-label/.pg-field-label */
}
/* Fila de campo con acción inline (p.ej. label + "¿olvidaste tu contraseña?") */
.zh-auth-field-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}
/* Link de texto pequeño reutilizable dentro de formularios de auth */
.zh-auth-link {
  font-family: var(--font-family);
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  letter-spacing: var(--text-label-sm-spacing);
  color: var(--color-primary);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  text-decoration: none;
  transition: text-decoration var(--transition);
}
.zh-auth-link:hover {
  text-decoration: underline;
}
/* Input con ícono */
.zh-auth-input-wrap {
  position: relative;
}
.zh-auth-input-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 20px;
  color: var(--color-outline);
  pointer-events: none;
}
.zh-auth-input {
  width: 100%;
  height: 44px;
  padding: 0 var(--space-4) 0 40px;
  font-family: var(--font-family);
  font-size: var(--text-body-md-size);
  color: var(--color-text-primary);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  outline: none;
  transition:
    border-color var(--transition),
    box-shadow var(--transition);
}
.zh-auth-input::placeholder {
  color: rgba(115, 119, 127, 0.5);
}
.zh-auth-input:hover {
  border-color: var(--color-outline);
}
.zh-auth-input:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
.zh-auth-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.zh-auth-field--error .zh-auth-input {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 12%, transparent);
}
.zh-auth-field-error {
  font-size: var(--text-help-size);
  color: var(--color-error);
}
/* .zh-auth-field-hint y familia (--success/--error/--info) ELIMINADOS
   (Bloque 12B) — sin consumidores (las páginas de auth usan
   .zh-auth-field-error, no esta familia de hint). */
/* Submit */
.zh-auth-submit {
  width: 100%;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-family);
  font-size: var(--text-label-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-on-primary);
  background: var(--color-primary-container);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition:
    background var(--transition),
    transform 0.08s ease;
}
.zh-auth-submit:hover:not(:disabled) {
  background: var(--color-primary);
}
.zh-auth-submit:active:not(:disabled) {
  transform: scale(0.98);
}
.zh-auth-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.zh-auth-submit .material-symbols-outlined {
  font-size: 18px;
}
.zh-auth-submit--loading {
  cursor: wait;
  opacity: 0.82;
}
.zh-auth-submit-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid color-mix(in srgb, var(--color-on-primary) 35%, transparent);
  border-top-color: var(--color-on-primary);
  border-radius: 50%;
  animation: zh-auth-spin 0.7s linear infinite;
  flex-shrink: 0;
}
@keyframes zh-auth-spin {
  to {
    transform: rotate(360deg);
  }
}
/* Info section */
.zh-auth-divider {
  margin-top: var(--space-8);
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border);
}
.zh-auth-info-box {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  background: var(--color-surface-container-low);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
}
.zh-auth-info-icon {
  color: var(--color-primary);
  font-size: 20px;
  flex-shrink: 0;
  margin-top: 1px;
}
.zh-auth-info-title {
  font-size: var(--text-label-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-text-primary);
  margin: 0 0 var(--space-2);
}
.zh-auth-info-list {
  font-size: 12px;
  line-height: 1.5;
  color: var(--color-on-surface-variant);
  padding-left: var(--space-4);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  list-style: disc;
}
/* Back button */
.zh-auth-back {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  margin-top: var(--space-8);
  padding: 0;
  font-family: var(--font-family);
  font-size: var(--text-label-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-primary);
  background: none;
  border: none;
  cursor: pointer;
  transition: opacity var(--transition);
}
.zh-auth-back:hover {
  opacity: 0.75;
}
.zh-auth-back-arrow {
  font-size: 18px;
  transition: transform var(--transition);
}
.zh-auth-back:hover .zh-auth-back-arrow {
  transform: translateX(-3px);
}
/* Decorative banner */
.zh-auth-banner {
  width: 100%;
  height: 120px;
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  overflow: hidden;
  position: relative;
  background: linear-gradient(
    135deg,
    var(--color-surface-container) 0%,
    var(--color-surface-dim) 100%
  );
  display: flex;
  align-items: center;
  justify-content: center;
}
.zh-auth-banner-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    var(--color-background) 0%,
    transparent 100%
  );
  pointer-events: none;
}
.zh-auth-banner-icon {
  font-size: 48px;
  color: var(--color-outline-variant);
  opacity: 0.45;
  position: relative;
  z-index: 1;
}
/* Utility footer */
.zh-auth-footer {
  text-align: center;
}
.zh-auth-footer-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}
.zh-auth-footer-link {
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-sm-weight);
  color: var(--color-outline);
  text-decoration: none;
  transition: color var(--transition);
}
.zh-auth-footer-link:hover {
  color: var(--color-primary);
  text-decoration: none;
}
.zh-auth-footer-sep {
  color: var(--color-outline-variant);
}
.zh-auth-footer-copy {
  font-size: 12px;
  color: var(--color-outline);
  opacity: 0.6;
}
@media (max-width: 480px) {
  .zh-auth-card {
    padding: var(--space-6);
  }
  .zh-auth-card-body {
    padding: var(--space-6);
  }
  .zh-auth-card-title {
    font-size: 22px;
  }
  .zh-auth-card-header {
    margin-bottom: var(--space-6);
  }
}
/* ── 29. TOAST (.zh-toast) ──────────────────────────────── */
.zh-toast-container {
  position: fixed;
  top: var(--space-5);
  right: var(--space-5);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  pointer-events: none;
}
@keyframes zh-toast-in {
  from {
    opacity: 0;
    transform: translateX(24px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
.zh-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-body-md-size);
  font-weight: 500;
  box-shadow: var(--shadow-md);
  min-width: 260px;
  max-width: 380px;
  animation: zh-toast-in 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.zh-toast--success {
  background: color-mix(in srgb, var(--color-success) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-success) 30%, transparent);
  color: var(--color-success);
}
.zh-toast--error {
  background: color-mix(in srgb, var(--color-error) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-error) 28%, transparent);
  color: var(--color-error);
}
.zh-toast--warning {
  background: color-mix(in srgb, var(--color-warning) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-warning) 28%, transparent);
  color: var(--color-warning);
}
.zh-toast--info {
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-primary) 25%, transparent);
  color: var(--color-primary);
}
.zh-toast__icon {
  font-size: 18px;
  flex-shrink: 0;
}
.zh-toast__msg {
  flex: 1;
}
.zh-toast__close {
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.6;
  transition: opacity var(--transition);
  padding: 2px;
  color: inherit;
}
.zh-toast__close:hover {
  opacity: 1;
}
/* ── 28. PATRONES RESPONSIVE COMPARTIDOS ────────────────── */
/*
   Aplicados automáticamente por convención de nombres.
   No requiere cambios en HTML/JSX.
*/
/* Tabla responsive (640px) */
@media (max-width: 640px) {
  .responsive-table thead {
    display: none;
  }
  .responsive-table tbody {
    display: grid;
    gap: var(--space-3);
  }
  .responsive-table tr {
    display: block;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    padding: var(--space-2) var(--space-4);
  }
  .responsive-table td {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--space-3);
    border: none;
    padding: 0.35rem 0;
    text-align: right;
    font-size: 12px;
  }
  .responsive-table td::before {
    content: attr(data-label);
    text-align: left;
    color: var(--color-text-secondary);
    font-weight: 600;
    flex: 0 0 42%;
    font-size: 12px;
  }
}
/* Barra de filtros */
[class$="-list-filters"] {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
/* Paginación */
[class$="-pagination"] {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-4);
  justify-content: flex-end;
  align-items: center;
}
[class$="-pagination-label"] {
  line-height: 32px;
  color: var(--color-text-secondary);
}
/* Celdas de acciones */
[class$="-actions-cell"],
[class$="-cell-actions"] {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
/* Fila de búsqueda */
[class$="-search-row"] {
  margin-bottom: var(--space-3);
}
/* Etiquetas de campo en detalles */
[class$="-field-label"],
[class$="-detail-label"] {
  font-size: var(--text-label-sm-size);
  color: var(--color-text-secondary);
  margin-bottom: 2px;
}
/* Grid de detalle 3 columnas */
[class$="-detail-grid"] {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
@media (max-width: 768px) {
  [class$="-detail-grid"] {
    grid-template-columns: 1fr;
  }
}
/* Fila de acciones */
[class$="-action-row"] {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.zh-picker {
  position: relative;
}
.zh-picker__input-wrap {
  position: relative;
}
.zh-picker__selected {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.zh-picker__selected-body {
  flex: 1;
}
.zh-picker__selected-name,
.zh-picker__result-name {
  font-size: var(--text-body-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-text-primary);
}
.zh-picker__selected-id,
.zh-picker__result-meta {
  font-size: var(--text-body-sm-size);
  color: var(--color-text-secondary);
  font-family: var(--font-family-mono);
}
.zh-picker__result-meta {
  margin-top: 2px;
}
.zh-picker__clear {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-secondary);
  padding: 0;
}
.zh-picker__clear-icon {
  font-size: 18px;
}
.zh-picker__loading {
  position: absolute;
  right: var(--space-2);
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--text-body-sm-size);
  color: var(--color-text-secondary);
}
.zh-picker__dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 50;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--color-text-primary) 12%, transparent);
  max-height: 240px;
  overflow-y: auto;
  margin-top: var(--space-1);
}
.zh-picker__empty {
  padding: var(--space-3) var(--space-4);
  color: var(--color-text-secondary);
  font-size: var(--text-body-md-size);
  text-align: center;
}
.zh-picker__empty-help {
  margin-top: var(--space-2);
}
.zh-picker__empty-message {
  color: var(--color-text-secondary);
  font-size: var(--text-body-sm-size);
  margin-bottom: var(--space-2);
}
.zh-picker__link {
  color: var(--color-primary);
}
.zh-picker__result {
  display: block;
  width: 100%;
  padding: 10px 14px;
  border: none;
  text-align: left;
  cursor: pointer;
  background: transparent;
}
.zh-picker__result--focused {
  background: var(--color-surface-container-low);
}
.zh-picker__result-main {
  min-width: 0;
}
.zh-picker__result-code {
  display: inline-flex;
  align-items: center;
  margin-right: var(--space-2);
  font-family: var(--font-family-mono);
  font-size: var(--text-xs);
  font-weight: var(--text-label-sm-weight);
  color: var(--color-primary);
}
.zh-picker__result-desc {
  margin-top: var(--space-1);
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
  line-height: var(--line-height-snug);
}
.zh-picker__result-extra {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-left: var(--space-3);
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.zh-picker__result-extra-label {
  font-weight: var(--text-label-sm-weight);
}
.zh-picker__result-extra-value {
  font-family: var(--font-family-mono);
  color: var(--color-text-primary);
}
/* ZHMoneyValue (PURCHASES-DS-MONEY-01) hereda el tamaño compacto de la fila
   "extra" del picker (--text-xs) en vez de imponer su propio tamaño por
   defecto — evita que el precio se envuelva/desborde la fila nowrap. */
.zh-picker__result-extra-value .zh-money-value {
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
}
/* .zh-picker__create-btn ELIMINADO (Bloque 13H) — migrado a
   <ZHBtn variant="primary" size="sm"> en CustomerPicker.tsx. */
.zh-picker__create-icon {
  font-size: 16px;
}
/* ── ZHPickerResultItem — fila seleccionable genérica de dropdowns/autocompletes
   (ver ZHPickerResultItem.tsx) ───────────────────────────────────────────── */
.zh-picker-result-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 10px 14px;
  border: none;
  border-radius: 0;
  text-align: left;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-family);
}
.zh-picker-result-item:hover:not(:disabled) {
  background: var(--color-surface-container-low);
}
.zh-picker-result-item--selected {
  background: var(--color-surface-container-low);
}
.zh-picker-result-item:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.zh-picker-result-item__icon {
  font-size: 18px;
  color: var(--color-text-secondary);
  flex-shrink: 0;
}
.zh-picker-result-item__content {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.zh-picker-result-item__title {
  font-size: var(--text-body-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-text-primary);
}
.zh-picker-result-item__subtitle {
  margin-top: 2px;
  font-size: var(--text-body-sm-size);
  color: var(--color-text-secondary);
}
.zh-picker-result-item__meta {
  margin-top: 2px;
  font-size: var(--text-body-sm-size);
  color: var(--color-text-secondary);
  font-family: var(--font-family-mono);
}
/* ── ZHToggleTile — tile/tarjeta seleccionable de un grupo de opciones exclusivas
   (ver ZHToggleTile.tsx) ─────────────────────────────────────────────────── */
.zh-toggle-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  padding: var(--space-2) 6px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text-primary);
  cursor: pointer;
  font-family: var(--font-family);
  transition:
    border-color var(--transition),
    background var(--transition),
    color var(--transition);
}
.zh-toggle-tile:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.zh-toggle-tile--active {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.zh-toggle-tile__icon {
  font-size: 18px;
  color: inherit;
}
.zh-toggle-tile__content {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
}
.zh-toggle-tile__title {
  font-size: var(--text-label-sm-size);
  font-weight: var(--text-label-md-weight);
  text-transform: uppercase;
  color: inherit;
}
.zh-toggle-tile__subtitle {
  margin-top: 2px;
  font-size: var(--text-body-sm-size);
  color: inherit;
  opacity: 0.85;
}
/* ── ZHPickerSelectedValue — tarjeta de valor seleccionado de un picker
   (ver ZHPickerSelectedValue.tsx) ───────────────────────────────────────── */
.zh-picker-selected-value {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.zh-picker-selected-value__content {
  flex: 1;
  min-width: 0;
}
.zh-picker-selected-value__title {
  font-size: var(--text-body-md-size);
  font-weight: var(--text-label-md-weight);
  color: var(--color-text-primary);
}
.zh-picker-selected-value__subtitle {
  margin-top: 2px;
  font-size: var(--text-body-sm-size);
  color: var(--color-text-secondary);
}
.zh-picker-selected-value__meta {
  margin-top: 2px;
  font-size: var(--text-body-sm-size);
  color: var(--color-text-secondary);
  font-family: var(--font-family-mono);
}
.zh-picker-selected-value__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}
.zh-ml-1 {
  margin-left: var(--space-1);
}
.zh-datatable-page-number {
  padding: 0 10px;
  display: flex;
  align-items: center;
}
/* Table text alignment utilities */
/* .zh-text-align-left ELIMINADO (Bloque 12B) — sin consumidores. */
.zh-text-align-center {
  text-align: center;
}
.zh-text-align-right {
  text-align: right;
}
/* Celda numérica: alineación derecha + mono + tamaño (Bloque 7B, ex .pf-td--num) */
.zh-table-cell--num {
  text-align: right;
  font-family: var(--font-family-mono);
  font-size: 12px;
  font-weight: 500;
}
/* Fila de estado vacío dentro de <table> (Bloque 7B, ex .pf-table-empty) */
.zh-table-empty {
  padding: var(--space-8) var(--space-5);
  text-align: center;
  color: var(--color-text-secondary);
  font-size: 13px;
}
.zh-form-logo {
  color: var(--color-on-primary);
}
/* .zh-document-picker__* ELIMINADO (Bloque 12B) -- sin consumidores; ningun
   componente picker de documentos usa este namespace hoy. */
/* ── 30. LINE ROW (.zh-line-card / .zh-line-action-rail / .zh-line-action / .zh-line-content) ── */
/* Fila de ítem con rail de acciones lateral + contenido (con skeleton).
   Generaliza los patrones ad-hoc .sf-product__* (sales-product-card.css) y
   .pdl-line__* (purchases-invoice.css) en un componente único reutilizable. */
.zh-line-card {
  display: flex;
  width: 100%;
  max-width: 960px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
  overflow: hidden;
}
/* Estructura mínima de rail + body — cada módulo consumidor decide el estilo visual interno
   (padding, ancho, colores) con su propio CSS; ver `.sf-product-card` en Ventas. */
.zh-line-card__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.zh-line-card__body {
  flex: 1;
  min-width: 0;
}
.zh-line-action-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  width: 64px;
  flex-shrink: 0;
  padding: var(--space-4) 0;
  background: var(--color-surface-container-low);
  border-right: 1px solid var(--color-border-light);
}
.zh-line-action-rail__index {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-text-tertiary);
  font-family: var(--font-family-mono);
}
.zh-line-action {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.zh-line-action__label {
  font-size: 10px;
  font-weight: 700;
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.zh-line-action__label--danger {
  color: var(--color-error);
}
.zh-line-action__btn--sm .material-symbols-outlined {
  font-size: 18px;
}
.zh-line-action__btn--md .material-symbols-outlined {
  font-size: 20px;
}
.zh-line-action__btn--lg .material-symbols-outlined {
  font-size: 22px;
}
/* Fondo tenue en reposo (no solo hover) para la acción destructiva grande
   (ej. eliminar línea) — reutiliza el token de peligro, sin hardcodear color.
   Preserva el tratamiento visual que ya tenía .pdl-line__delete-btn. */
.zh-line-action__btn--lg.prd-icon-btn--danger {
  background: color-mix(in srgb, var(--color-error) 8%, transparent);
  border-radius: var(--radius-sm);
}
.zh-line-action--compact {
  gap: 0;
}
.zh-line-action__btn--tone-warning.prd-icon-btn {
  color: var(--color-warning);
}
.zh-line-action__btn--tone-warning.prd-icon-btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--color-warning) 10%, transparent);
}
.zh-line-action__label--warning {
  color: var(--color-warning);
}
/* ── ZHLineAction kind="menu" — trigger + panel (ex .pdl-product-menu*) ── */
.zh-line-action-menu {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.zh-line-action-menu__trigger {
  width: 32px;
  min-height: 40px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-secondary);
  cursor: pointer;
  transition:
    color var(--transition),
    background var(--transition),
    border-color var(--transition);
}
.zh-line-action-menu__trigger--primary {
  color: var(--color-primary);
}
.zh-line-action-menu__trigger-icon {
  font-size: 18px;
}
.zh-line-action-menu__trigger-chevron {
  font-size: 14px;
  line-height: 1;
  transition: transform var(--transition);
}
.zh-line-action-menu__trigger-chevron--open {
  transform: rotate(180deg);
}
.zh-line-action-menu__trigger:hover:not(:disabled),
.zh-line-action-menu__trigger:focus-visible,
.zh-line-action-menu__trigger[aria-expanded="true"] {
  border-color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
}
.zh-line-action-menu__trigger:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}
.zh-line-action-menu__panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 30;
  width: min(320px, 80vw);
  padding: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  display: grid;
  gap: var(--space-1);
  text-align: left;
}
.zh-line-action-menu__panel--end {
  left: auto;
  right: 0;
}
.zh-line-action-item {
  width: 100%;
  min-height: 32px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-2);
  padding: 6px 8px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-primary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.zh-line-action-item:hover:not(:disabled),
.zh-line-action-item:focus-visible {
  background: var(--color-surface-container-low);
}
.zh-line-action-item:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.zh-line-action-item__icon {
  font-size: 16px;
  flex-shrink: 0;
}
.zh-line-action-item--primary {
  color: var(--color-primary);
}
.zh-line-action-item--warning {
  color: var(--color-warning);
}
.zh-line-action-item--danger {
  color: var(--color-error);
}
.zh-line-content {
  flex: 1;
  min-width: 0;
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
}
.zh-line-content__skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.zh-line-content__skeleton-bar {
  display: block;
  height: 12px;
  border-radius: var(--radius-xs);
  background: var(--color-surface-container);
  animation: zh-line-skeleton-pulse 1.4s ease-in-out infinite;
}
.zh-line-content__skeleton-bar--title {
  width: 70%;
  height: 14px;
}
.zh-line-content__skeleton-bar--sub {
  width: 45%;
}
.zh-line-content__skeleton-bar--meta {
  width: 55%;
}
@keyframes zh-line-skeleton-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}
/* ── Reset mínimo ──────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
/* ── Base ──────────────────────────────────────────────────── */
html {
  scroll-behavior: smooth;
}
body {
  font-family: var(--font-family);
  font-size: var(--text-body-md-size);
  line-height: var(--text-body-md-height);
  font-weight: var(--text-body-md-weight);
  background-color: var(--color-background);
  color: var(--color-text-primary);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* ── Accesibilidad ─────────────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
/* ── Material Symbols ──────────────────────────────────────── */
.material-symbols-outlined {
  font-variation-settings:
    "FILL" 0,
    "wght" 400,
    "GRAD" 0,
    "opsz" 24;
  vertical-align: middle;
  user-select: none;
  line-height: 1;
}
/* ── Scrollbar ──────────────────────────────────────────────── */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--color-outline-variant) transparent;
}
::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}
::-webkit-scrollbar-thumb {
  background: var(--color-outline-variant);
  border-radius: var(--radius-pill);
}
