/* =========================================
     TIPOGRAFÍA (Satoshi, la misma que usa la referencia — Fontshare,
     gratis para uso comercial, © Indian Type Foundry)
     ========================================= */
  @font-face {
    font-family: "Satoshi";
    src: url("files/fonts/Satoshi-Regular.woff2") format("woff2"),
      url("files/fonts/Satoshi-Regular.woff") format("woff");
    font-weight: 400; font-display: swap; font-style: normal;
  }
  @font-face {
    font-family: "Satoshi";
    src: url("files/fonts/Satoshi-Medium.woff2") format("woff2"),
      url("files/fonts/Satoshi-Medium.woff") format("woff");
    font-weight: 500; font-display: swap; font-style: normal;
  }
  @font-face {
    font-family: "Satoshi";
    src: url("files/fonts/Satoshi-Bold.woff2") format("woff2"),
      url("files/fonts/Satoshi-Bold.woff") format("woff");
    font-weight: 700; font-display: swap; font-style: normal;
  }
  @font-face {
    font-family: "Satoshi";
    src: url("files/fonts/Satoshi-Black.woff2") format("woff2"),
      url("files/fonts/Satoshi-Black.woff") format("woff");
    font-weight: 900; font-display: swap; font-style: normal;
  }

/* =========================================
     VARIABLES GLOBALES (Colores y Radios)
     ========================================= */
  :root {
    /* Paleta calcada de TailAdmin (tailwind.config.js: primary/boxdark/bodydark/meta-*),
       manteniendo los mismos nombres de variable de Loyka para que todo el
       resto de este archivo se retematice solo con este bloque.
       --loyka-terracota quedó con el azul "primary" de TailAdmin de fábrica
       y nunca se cambió por el terracota real de la marca (el naranja quemado
       del logo, #B3461B — ver public/files/logo-header.png). Se ajusta acá a
       un tono derivado de ese mismo color pero un poco más claro/saturado
       para que sirva de texto/ícono legible sobre el fondo oscuro (el del
       logo, muy fiel al original, no pasa el contraste mínimo como texto). */
    --loyka-terracota: #E2632B;  /* acento principal: terracota real de la marca */
    --loyka-ocre: #259AE6;       /* "meta-5": azul informativo */
    --loyka-oliva: #10B981;      /* "meta-3": verde éxito */
    --loyka-danger: #DC3545;     /* "meta-1": rojo peligro — separado del acento a propósito */
    --loyka-warning: #FFBA00;    /* "meta-6": ámbar advertencia */
    --loyka-bg: #1A222C;         /* "boxdark-2": fondo de página */
    --loyka-card-bg: #24303F;    /* "boxdark": fondo de tarjetas/paneles */
    --loyka-text: #DEE4EE;       /* "bodydark1" */
    --loyka-text-muted: #AEB7C0; /* "bodydark" */
    --loyka-border: #2E3A47;     /* "strokedark" */
    --loyka-red-glow: rgba(226, 99, 43, 0.18);
    --loyka-orange: var(--loyka-terracota);
    --accent: var(--loyka-terracota);

    /* Radios estructurales — más chicos, como en la referencia */
    --radius-sm: 4px;
    --radius-md: 6px;
    --radius-lg: 8px;
  }

  /* =========================================
     CONFIGURACIÓN BASE APP NATIVA
     ========================================= */
  * { 
    -webkit-tap-highlight-color: transparent; 
    -webkit-touch-callout: none;
    cursor: default; 
  }

  input, textarea { 
    caret-color: auto !important; 
    cursor: text !important;
  }

  button, .button, a, .loyka-card, .tabs li a, .panel-handler, label, .sidebar-link {
    cursor: pointer !important;
    -webkit-user-select: none !important; 
    user-select: none !important;
  }

  select, .select, .select select {
    pointer-events: auto !important;
    user-select: auto !important;
    -webkit-user-select: auto !important;
  }

  *:focus, *:active { outline: none !important; }
  .button:focus, .button:active, .input:focus, .select select:focus, .textarea:focus {
    box-shadow: none !important;
  }
  .loyka-card:focus, .loyka-card:active { outline: none !important; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); }

  body { 
    background-color: var(--loyka-bg); 
    color: var(--loyka-text);
    padding-bottom: 20px;
    font-family: 'Satoshi', sans-serif;
    position: relative;
  }

  body::before {
    content: ""; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
    pointer-events: none; z-index: -2; 
    background-image: url('https://lh3.googleusercontent.com/d/1XVrlMvrtz2TF5pbkASFlOCv9o6jq9tpm');
    background-repeat: no-repeat; background-position: center center;
    background-size: 50%; opacity: 0.03; 
  }

  body::after {
    content: ""; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
    pointer-events: none; z-index: -1; 
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.04'/%3E%3C/svg%3E");
    background-color: rgba(226, 99, 43, 0.02);
  }

  /* =========================================
     SECCIONES Y PANELES
     ========================================= */
  .section-app { 
    display: none; 
    animation: fadeIn 0.3s ease; 
  }
  .section-app.is-active { display: block; }
  @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

  #pantalla-login {
    position: fixed; top: 0; left: 0; width: 100%; height: 100%;
    background: var(--loyka-bg); z-index: 9999; 
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    padding: 20px; transition: opacity 0.5s ease;
  }

  .panel-sheet {
    position: fixed; bottom: -100%; left: 0; width: 100%; 
    background: white; border-radius: 30px 30px 0 0; 
    z-index: 2000; transition: bottom 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    max-height: 90vh; overflow-y: auto;
  }
  .panel-sheet.is-active { bottom: 0; }
  .panel-handler { width: 40px; height: 4px; background: #ddd; border-radius: 10px; margin: 15px auto; }
  .panel-overlay {
    position: fixed; top: 0; left: 0; width: 100%; height: 100%;
    background: rgba(0,0,0,0.4); display: none; z-index: 1999;
  }
  .panel-overlay.is-active { display: block; }
  .modal { z-index: 3000; } 

  /* =========================================
     EASTER EGGS
     ========================================= */
  .spin-picante { animation: spinFire 0.8s ease-in-out; filter: drop-shadow(0 0 10px #d9411e) saturate(150%); }
  @keyframes spinFire { 0% { transform: rotate(0deg) scale(1); } 50% { transform: rotate(180deg) scale(1.2); } 100% { transform: rotate(360deg) scale(1); } }
  .aji-volador { position: fixed; font-size: 5rem; z-index: 9999; pointer-events: none; animation: volar 1.5s cubic-bezier(0.25, 1, 0.5, 1) forwards; }
  @keyframes volar { 0% { transform: translate(-10vw, 110vh) rotate(-45deg); opacity: 1; } 100% { transform: translate(110vw, -10vh) rotate(360deg); opacity: 0; } }

  /* =========================================
     SCROLLBARS Y UI POLISH
     ========================================= */
  ::-webkit-scrollbar { width: 6px; height: 6px; }
  ::-webkit-scrollbar-track { background: transparent; }
  ::-webkit-scrollbar-thumb { background: var(--loyka-border); border-radius: 10px; }
  ::-webkit-scrollbar-thumb:hover { background: var(--loyka-text-muted); }

  input[type=number]::-webkit-inner-spin-button,
  input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
  input[type=number] { -moz-appearance: textfield; appearance: textfield; }

  /* ==========================================
     TEMA OSCURO BASE Y ELEMENTOS BULMA
     ========================================== */
  html, html.dark-mode { background-color: var(--loyka-bg) !important; color-scheme: dark; } 
  
  .dark-mode {
    body, #pantalla-login { background-color: var(--loyka-bg) !important; color: var(--loyka-text) !important; }
    
    .panel-sheet, .modal-card-body, .modal-card-head, .modal-card-foot, .modal-card,
    .box, .card-gasto, .stat-card, .has-background-light, .has-background-white {
      background-color: var(--loyka-card-bg) !important; 
      border-color: var(--loyka-border) !important;
      color: var(--loyka-text) !important;
    }

    .box, .card-gasto, .stat-card {
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2) !important; 
      border-radius: var(--radius-md) !important;
    }

    .title, .label, strong, .has-text-dark, .has-text-black, .has-text-grey-dark, .insumo-name { color: #FFFFFF !important; }
    .help, .has-text-grey, .has-text-grey-light { color: var(--loyka-text-muted) !important; }
    .section-title { color: var(--loyka-terracota) !important; }

    .input, .select select, .textarea {
      background-color: #181818 !important; border-color: var(--loyka-border) !important; 
      color: var(--loyka-text) !important; border-radius: var(--radius-sm) !important; box-shadow: none !important; transition: all 0.2s ease;
    }
    .input::placeholder, .textarea::placeholder { color: #666666 !important; }
    select option { background-color: #181818; color: var(--loyka-text); }
    
    .input:focus, .select select:focus, .textarea:focus,
    .input:active, .select select:active, .textarea:active {
      border-color: var(--loyka-orange) !important;
      box-shadow: inset 0 1px 2px rgba(0,0,0,0.1), 0 0 0 1px var(--loyka-orange), 0 0 15px var(--loyka-red-glow) !important;
    }

    .table, .table th, .table td { background-color: transparent !important; border-color: var(--loyka-border) !important; color: var(--loyka-text) !important; box-shadow: none !important; }
    .table thead th, .table thead tr { background-color: var(--loyka-card-bg) !important; color: var(--loyka-text-muted) !important; }
    .table.is-striped tbody tr:nth-child(even) { background-color: #181818 !important; }
    .table.is-hoverable tbody tr:hover { background-color: #242424 !important; }

    /* Tablas más espaciosas y con encabezado más discreto (todas las tablas
       de la app usan la misma clase .table de Bulma, así que este único
       cambio se ve reflejado en toda la app). */
    .table:not(.is-narrow) td, .table:not(.is-narrow) th { padding: 0.85em 1em !important; }
    .table thead th { font-size: 0.68rem !important; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 700 !important; border-bottom-width: 2px !important; }
    .table.is-narrow td, .table.is-narrow th { padding: 0.55em 0.75em !important; }

    .has-text-primary, .has-text-info, .has-text-link, .has-text-info-dark, .has-text-link-dark { color: var(--loyka-ocre) !important; }
    .has-text-success, .has-text-success-dark { color: var(--loyka-oliva) !important; }
    .has-text-danger, .has-text-danger-dark { color: var(--loyka-danger) !important; }
    .has-text-warning, .has-text-warning-dark { color: var(--loyka-warning) !important; }

    .has-background-primary, .has-background-info, .has-background-link, .tag.is-primary, .tag.is-info, .tag.is-link, .button.is-primary, .button.is-info, .button.is-link { background-color: var(--loyka-ocre) !important; color: #fff !important; border-color: transparent !important; }
    .has-background-success, .tag.is-success, .button.is-success { background-color: var(--loyka-oliva) !important; color: #fff !important; border-color: transparent !important; }
    .has-background-danger, .tag.is-danger, .button.is-danger { background-color: var(--loyka-danger) !important; color: #fff !important; border-color: transparent !important; }
    .has-background-warning, .tag.is-warning, .button.is-warning { background-color: var(--loyka-warning) !important; color: #1C2434 !important; border-color: transparent !important; }

    .has-background-primary-light, .has-background-info-light, .has-background-link-light, .notification.is-info.is-light { background-color: rgba(37, 154, 230, 0.12) !important; border-color: transparent !important; }
    .has-background-success-light, .notification.is-success.is-light { background-color: rgba(16, 185, 129, 0.12) !important; border-color: transparent !important; }
    .has-background-danger-light, .notification.is-danger.is-light { background-color: rgba(220, 53, 69, 0.12) !important; border-color: transparent !important; }
    .has-background-warning-light, .notification.is-warning.is-light { background-color: rgba(255, 186, 0, 0.15) !important; border-color: transparent !important; }

    .button.is-light, .tag.is-light, .notification.is-light { background-color: #2A2A2A !important; color: var(--loyka-text) !important; border-color: var(--loyka-border) !important; }
    .button.is-info.is-light, .button.is-primary.is-light, .button.is-link.is-light, .tag.is-info.is-light, .tag.is-primary.is-light { background-color: rgba(37, 154, 230, 0.15) !important; color: var(--loyka-ocre) !important; border-color: transparent !important; }
    .button.is-success.is-light, .tag.is-success.is-light { background-color: rgba(16, 185, 129, 0.15) !important; color: var(--loyka-oliva) !important; border-color: transparent !important; }
    .button.is-danger.is-light, .tag.is-danger.is-light { background-color: rgba(220, 53, 69, 0.15) !important; color: var(--loyka-danger) !important; border-color: transparent !important; }
    .button.is-warning.is-light, .tag.is-warning.is-light { background-color: rgba(255, 186, 0, 0.18) !important; color: var(--loyka-warning) !important; border-color: transparent !important; }

    .button.is-info.is-light:hover, .button.is-primary.is-light:hover { background-color: var(--loyka-ocre) !important; color: #fff !important; }
    .button.is-success.is-light:hover { background-color: var(--loyka-oliva) !important; color: #fff !important; }
    .button.is-danger.is-light:hover { background-color: var(--loyka-danger) !important; color: #fff !important; }
    .button.is-warning.is-light:hover { background-color: var(--loyka-warning) !important; color: #1C2434 !important; }
    .button.is-outlined { background-color: transparent !important; color: var(--loyka-text) !important; border-color: var(--loyka-border) !important; }
    .button.is-outlined:hover { background-color: #2A2A2A !important; color: #fff !important; }

    .tabs.is-toggle.is-fullwidth a { background-color: #181818 !important; border-color: var(--loyka-border) !important; color: var(--loyka-text-muted) !important; border-radius: var(--radius-sm); }
    .tabs.is-toggle.is-fullwidth li.is-active a { background-color: var(--loyka-orange) !important; border-color: var(--loyka-orange) !important; color: #fff !important; }
    [style*="border: 1px"], [style*="border-top: 1px"] { border-color: var(--loyka-border) !important; }
    [style*="color: #"] { color: var(--loyka-text) !important; }

    .drag-handle { background-color: transparent !important; border-color: transparent !important; }
    .drag-handle:hover { background-color: rgba(255,255,255,0.1) !important; }
    .sortable-ghost { background-color: rgba(255,255,255,0.05); }
    .autocomplete-dropdown { background-color: #1f2937; border-color: #374151; box-shadow: 0 8px 20px rgba(0,0,0,0.4); }
    .autocomplete-item { border-bottom: 1px solid #374151; color: #f3f4f6; }
    .autocomplete-item:hover { background-color: #374151; color: #fff; }
    .skeleton-line { background-color: #2d2d2d; }
  }
  
  /* ==========================================
     LAYOUT Y COMPONENTES
     ========================================== */
  .loyka-app-layout {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
  }
  .loyka-sidebar {
    width: 260px; flex-shrink: 0; display: none; flex-direction: column;
    /* position:fixed (no sticky): el sidebar nunca se mueve ni participa en
       el alto de .loyka-app-layout. Con sticky, aunque el contenido del menú
       (los links + el pie de usuario) es corto, la caja igual reservaba un
       viewport completo (height:100vh) para poder "pegarse" — eso hacía que
       una página con poco contenido quedara estirada a 100vh de más, y que
       al llegar al final del scroll el sidebar se despegara y se corriera
       junto con la página. Con fixed, el contenido principal simplemente le
       deja el espacio con margin-left (ver .loyka-main-content) y el sidebar
       queda quieto siempre. */
    position: fixed; top: 0; left: 0; height: 100vh;
    /* position:fixed crea su propio contexto de apilamiento aunque z-index
       quede en "auto" — sin ponerle uno explícito acá, ese contexto completo
       (con todo lo de adentro, incluido el panel de notificaciones) se
       compara con el resto de la página solo por orden en el HTML, y pierde
       contra cualquier elemento posicionado de #page-content (ej. el .select
       de Bulma) por venir antes en el documento. Con z-index explícito acá,
       ya no importa el orden: gana por valor. */
    z-index: 10;
    padding: 20px 14px; border-right: 1px solid var(--loyka-border);
  }
  /* #main-nav es hijo directo del sidebar (que es flex column): crece para
     empujar .loyka-sidebar-bottom (saludo/logout/widget) hasta el fondo, y es
     el único que scrollea (no el sidebar completo) para que overflow-y:auto
     no le recorte en x al panel de notificaciones, que necesita "escaparse"
     del ancho del sidebar (ver .loyka-notif-panel). min-height:0 es necesario
     para que un hijo flex-grow pueda encogerse y scrollear en vez de estirar
     el contenedor. */
  /* overscroll-behavior: contain evita que, al llegar al límite del scroll
     del menú, el gesto siga encadenándose hacia la página de atrás (y
     viceversa) — se nota sobre todo con touch en el celular. */
  #main-nav { flex-grow: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
  #main-nav::-webkit-scrollbar { width: 4px; }
  #main-nav::-webkit-scrollbar-thumb { background: #374151; border-radius: 10px; }

  .loyka-main-content {
    flex-grow: 1;
    min-width: 0;
    padding: 24px;
  }

  /* Fundido corto al cambiar de sección (navegación SPA en auth.js) */
  #page-content { transition: opacity 0.15s ease; }
  #page-content.is-loading { opacity: 0; }

  .sidebar-section-label {
    font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.8px; font-weight: 700;
    color: var(--loyka-text-muted); opacity: 0.7; padding: 0 16px; margin-bottom: 10px;
  }
  .sidebar-link { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-radius: 8px; color: var(--loyka-text-muted); font-weight: 600; transition: all 0.2s ease; background: transparent; border: 1px solid transparent; margin-bottom: 2px; }
  .sidebar-link:hover, .sidebar-link.is-active-nav { background: var(--loyka-card-bg); color: var(--loyka-text); border-color: var(--loyka-border); }
  .sidebar-link svg { width: 20px; height: 20px; }
  .sidebar-link.is-active-nav svg { color: var(--accent); }

  /* Logo integrado arriba del sidebar: mismo ancho que el panel, en vez de
     vivir en una barra superior aparte (así se ven como un solo bloque). */
  .loyka-sidebar .loyka-brand { padding: 2px 0 18px 0; }
  .loyka-sidebar .loyka-brand .loyka-badge-logo { width: 100%; height: auto; }

  /* Nombre + fila de acciones (configuración, correo, usuarios, cerrar
     sesión), al fondo del sidebar. */
  .loyka-sidebar-bottom {
    border-top: 1px solid var(--loyka-border); margin-top: 14px; padding-top: 14px;
    display: flex; flex-direction: column; gap: 10px;
  }
  .loyka-account-header { display: flex; align-items: center; gap: 10px; min-width: 0; }
  .loyka-account-name {
    margin: 0; font-size: 0.85rem; color: var(--loyka-text); font-weight: 600;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .loyka-account-actions { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
  /* Ancho fijo e igual para los 5 (antes flex:1 en los 5, pero los 2 que
     viven adentro de .loyka-notif-wrapper terminaban más angostos que los
     otros 3 — un caso raro de flexbox anidado con flex-basis:0% que no vale
     la pena perseguir. Con ancho fijo no hay ambigüedad posible, y
     justify-content:space-between en el contenedor los reparte parejo en
     todo el ancho, como antes. */
  .loyka-account-actions .btn-loyka-icon { flex: 0 0 auto; width: 34px; justify-content: center; }

  /* Avatar de perfil: foto (img) o iniciales (span) — mismo tamaño y forma
     para que se puedan intercambiar sin saltos de layout. Tamaño por
     defecto pensado para la barra lateral; .is-small lo achica para la
     tabla de Usuarios y .is-large para el tab de Configuración. */
  .loyka-avatar {
    width: 36px; height: 36px; border-radius: 999px; flex-shrink: 0;
    object-fit: cover; display: flex; align-items: center; justify-content: center;
  }
  .loyka-avatar-iniciales {
    background: rgba(226, 99, 43, 0.18); color: var(--loyka-terracota);
    font-weight: 700; font-size: 0.8rem; letter-spacing: 0.3px;
  }
  .loyka-avatar.is-small { width: 28px; height: 28px; font-size: 0.68rem; }
  .loyka-avatar.is-large { width: 72px; height: 72px; font-size: 1.3rem; }

  /* Campanita de correo nuevo: botón + badge + panel desplegable, anclados
     al wrapper (position:relative) para que el panel "flote" sobre el resto
     del sidebar en vez de empujar el layout. */
  .loyka-notif-wrapper { position: relative; flex: 0 0 auto; display: flex; }
  .loyka-notif-badge {
    display: none; position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px;
    background: var(--loyka-terracota); color: #fff; border-radius: 999px;
    font-size: 0.65rem; font-weight: 700; line-height: 16px; text-align: center; padding: 0 3px;
  }
  .loyka-notif-badge.is-visible { display: block; }
  .loyka-notif-panel {
    display: none; position: absolute; bottom: calc(100% + 8px); left: 0; width: 360px;
    max-height: 440px; overflow-y: auto; overflow-x: hidden; background: var(--loyka-card-bg);
    border: 1px solid var(--loyka-border); border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); z-index: 40; padding: 10px;
  }
  .loyka-notif-panel.is-active { display: block; }
  .loyka-notif-panel-header {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.6px; font-weight: 700;
    color: var(--loyka-text-muted); opacity: 0.85; margin: 14px 0 6px 0; padding: 0 2px;
  }
  .loyka-notif-panel-header:first-child { margin-top: 0; }
  /* Contador junto al título de cada sección: mismo look que .panel-pill del
     Dashboard (ver loyka-stat-icon/.panel-pill), para que el panel se sienta
     parte de la misma interfaz en vez de un componente aparte. */
  .loyka-notif-panel-count {
    display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px;
    padding: 0 5px; border-radius: 999px; background: rgba(220, 53, 69, 0.18); color: var(--loyka-danger);
    font-size: 0.68rem; font-weight: 800; letter-spacing: normal; text-transform: none;
  }
  .loyka-notif-item {
    display: flex; align-items: flex-start; gap: 10px; padding: 8px; border-radius: 8px; margin-bottom: 2px;
  }
  .loyka-notif-item:hover { background: rgba(255, 255, 255, 0.06); }
  /* Chip de ícono con color por categoría — mismo patrón que .loyka-stat-icon
     de las tarjetas del Dashboard, solo que compacto para caber en una fila. */
  .loyka-notif-icon {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 30px; height: 30px;
    border-radius: 8px; margin-top: 1px; background: rgba(226, 99, 43, 0.14); color: var(--loyka-terracota);
  }
  .loyka-notif-icon svg { width: 16px; height: 16px; }
  .loyka-notif-icon.is-success, .loyka-stat-icon.is-success { background: rgba(16, 185, 129, 0.16); color: var(--loyka-oliva); }
  .loyka-notif-icon.is-ocre, .loyka-stat-icon.is-ocre { background: rgba(37, 154, 230, 0.18); color: var(--loyka-ocre); }
  .loyka-notif-icon.is-warning, .loyka-stat-icon.is-warning { background: rgba(255, 186, 0, 0.16); color: var(--loyka-warning); }
  .loyka-notif-icon.is-danger, .loyka-stat-icon.is-danger { background: rgba(220, 53, 69, 0.16); color: var(--loyka-danger); }
  .loyka-notif-body { min-width: 0; flex-grow: 1; }
  .loyka-notif-item .loyka-notif-remitente {
    display: block; font-weight: 600; font-size: 0.8rem; color: var(--loyka-text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .loyka-notif-item .loyka-notif-asunto {
    display: block; font-size: 0.75rem; color: var(--loyka-text-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .loyka-notif-item .loyka-notif-fecha { font-size: 0.68rem; color: var(--loyka-text-muted); opacity: 0.7; }
  .loyka-notif-empty {
    display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
    padding: 24px 12px; color: var(--loyka-text-muted);
  }
  .loyka-notif-empty svg { width: 26px; height: 26px; opacity: 0.5; }

  /* Barra mínima solo-mobile: hamburger + logo chico. En desktop el logo real
     vive arriba del sidebar, así que esta barra queda oculta (.is-hidden-desktop). */
  .loyka-mobile-topbar {
    display: flex; align-items: center; gap: 12px; padding: 12px 16px;
    background: rgba(18, 18, 18, 0.8); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--loyka-border); position: sticky; top: 0; z-index: 1000;
  }
  .loyka-mobile-topbar .loyka-badge-logo { height: 32px; width: auto; }

  @media (max-width: 1023px) {
    .loyka-sidebar.is-mobile-active {
      display: flex !important; position: fixed; top: 0; left: 0; height: 100vh;
      z-index: 3000; background: var(--loyka-bg); padding: 20px 10px 20px 20px;
      width: 260px; box-shadow: 4px 0 15px rgba(0,0,0,0.5);
    }
    .sidebar-overlay { display: none; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.5); z-index: 2999; }
    .sidebar-overlay.is-active { display: block; }
    /* Con el menú móvil abierto, la página de atrás no debe poder scrollear
       (si no, arrastrar el dedo dentro del menú mueve las dos cosas). */
    body.menu-mobile-abierto { overflow: hidden; }
  }
  @media (min-width: 1024px) {
    .loyka-sidebar { display: flex; }
    .is-hidden-desktop { display: none !important; }
    /* Compensa que el sidebar (fixed) ya no reserva su espacio dentro del
       flex de .loyka-app-layout — mismo ancho que .loyka-sidebar. Va en
       #page-content (por id, no por .loyka-main-content): cada página
       (inicio.html, ventas.html, etc.) repite esa misma clase en su propio
       <main> raíz, que auth.js inyecta ADENTRO de #page-content — si el
       margin fuera por clase, se aplicaría dos veces (anidado). */
    #page-content { margin-left: 260px; }
  }

  /* .section-app ya no existe en el DOM (quedó de antes de que el ruteo
     pasara a cargar cada página como fragmento HTML vía fetch, ver
     loadPage() en auth.js) — el selector de abajo era muerto, por eso la
     tarjeta principal de cada página no tenía borde visible y se perdía
     contra el fondo (se notaba mucho en páginas con poco contenido, tipo
     Clientes o Lotes: quedaba un choclón oscuro sin límite claro). */
  .loyka-main-content .box {
    background-color: var(--loyka-card-bg) !important;
    border-radius: 10px !important;
    /* --loyka-border (#2E3A47) es casi el mismo tono que loyka-card-bg
       (#24303F) — como borde de tarjeta quedaba invisible. Un borde claro
       translúcido se nota sin importar el bg de atrás (no depende de que
       haya suficiente diferencia entre dos oscuros), que es como se suele
       separar tarjetas en temas oscuros. */
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35) !important;
  }

  .form-header .title { display: flex; align-items: center; justify-content: center; gap: 12px; color: #f3f4f6 !important; font-weight: 700 !important; margin-bottom: 0.5rem !important; }
  .form-header .title svg { width: 28px; height: 28px; color: var(--loyka-orange); filter: drop-shadow(0 0 8px var(--loyka-red-glow)); }
  .form-header .subtitle { color: #9ca3af; margin-top: 0 !important; font-size: 0.9rem; }

  .drag-handle { cursor: grab; padding: 4px; border-radius: 6px; transition: background 0.2s; display: inline-flex; align-items: center; justify-content: center; }
  .drag-handle:hover { background-color: rgba(0,0,0,0.05); }
  .drag-handle:active { cursor: grabbing !important; }
  .sortable-ghost { opacity: 0.4; transform: scale(0.98); background-color: rgba(0,0,0,0.05); border-radius: var(--radius-md); }

  .btn-loyka-primary {
    background-color: var(--loyka-terracota); border: none; color: #fff; font-weight: 600;
    border-radius: var(--radius-sm); transition: all 0.3s ease; display: inline-flex;
    align-items: center; justify-content: center; gap: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
  }
  .btn-loyka-primary:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); background-color: #2C3AAE; color: #fff !important; }
  .btn-loyka-primary.is-loading::after { border-color: transparent transparent #fff #fff !important; }

  .tabla-scroll { border: 1px solid var(--loyka-border); border-radius: var(--radius-md); overflow: hidden; }
  .tabla-scroll .table { margin-bottom: 0 !important; }
  
  .button.is-small svg, .lucide-icon-small { width: 16px !important; height: 16px !important; }
  .button.is-medium svg { width: 20px !important; height: 20px !important; }

  .loyka-badge-logo {
    display: block; height: 50.4px; width: auto; border-radius: var(--radius-sm);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
  }


  .btn-loyka-outline {
    background: transparent; border: 1px solid #444; color: #e0e0e0; border-radius: var(--radius-sm);
    padding: 6px 12px; font-size: 0.8rem; font-weight: 600; cursor: pointer; display: flex;
    align-items: center; gap: 6px; transition: all 0.2s ease; font-family: 'Satoshi', sans-serif;
  }
  .btn-loyka-outline:hover { background: #2e2e2e; border-color: #666; color: #fff; }
  .btn-loyka-icon { padding: 6px; }
  .btn-loyka-outline svg { width: 16px; height: 16px; }

  /* Lenguaje de tarjeta "plano": sin brillos ni gradientes, radio chico,
     sombra apenas insinuada — se nota, pero no compite con el contenido. */
  .loyka-card {
    background: var(--loyka-card-bg); border-radius: 8px; border: 1px solid var(--loyka-border);
    padding: 20px; cursor: pointer; transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
    display: flex; flex-direction: column;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  }
  .loyka-card:hover { transform: translateY(-2px); border-color: var(--accent); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25); }
  /* Un transform en la tarjeta crea un nuevo contexto de posicionamiento para
     cualquier descendiente position:fixed (como .insumo-menu-dropdown), así
     que mientras el menú está abierto se anula: si no, el menú terminaba
     posicionado relativo a la tarjeta en vez de a la pantalla (pasaba con el
     mouse encima, y en iOS con el :hover que queda "pegado" tras un tap). */
  .loyka-card.tiene-menu-abierto { transform: none !important; }
  .loyka-card-icon {
    margin-bottom: 14px; display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: 8px; background: rgba(226, 99, 43, 0.14); color: var(--accent);
  }
  .loyka-card-icon svg { width: 20px; height: 20px; }
  .loyka-card-title { font-size: 0.9rem; font-weight: 700; color: var(--loyka-text); margin-bottom: 4px; }
  .loyka-card-desc { font-size: 0.8rem; color: var(--loyka-text-muted); line-height: 1.5; margin: 0; }

  /* Variante compacta: misma tarjeta, menos aire, para grillas con muchos ítems (ej. Bodega). */
  .loyka-card-compact { padding: 14px; }
  .loyka-card-compact .loyka-card-title { font-size: 0.78rem; margin-bottom: 4px; }
  .loyka-card-compact .loyka-card-desc { font-size: 0.74rem; line-height: 1.35; }
  .loyka-card-compact .tag { font-size: 0.65rem; padding: 2px 8px; }

  /* Cabecera de tarjeta con título + botones en flujo normal (no flotando
     encima), para que un nombre largo nunca quede tapado por los botones. */
  .insumo-card-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 6px; }
  .insumo-card-header .loyka-card-title { flex: 1; min-width: 0; margin-bottom: 0; }

  .insumo-menu { position: relative; flex-shrink: 0; }
  .insumo-menu .btn-toggle-menu-insumo { padding: 0 8px; }
  /* position: fixed (no absolute) a propósito: la tarjeta (.loyka-card) tiene
     overflow: hidden para recortar su brillo decorativo en las esquinas, y
     eso recortaba este menú también apenas se salía del borde de la tarjeta.
     Con fixed, el top/right se calculan en JS al abrirlo (ver gestion.js). */
  .insumo-menu-dropdown {
    display: none; position: fixed; z-index: 50;
    background: var(--loyka-card-bg); border: 1px solid var(--loyka-border); border-radius: var(--radius-md);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4); min-width: 180px; padding: 4px;
  }
  .insumo-menu-dropdown.is-active { display: block; }
  .insumo-menu-item {
    display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
    background: none; border: none; padding: 8px 10px; border-radius: var(--radius-sm);
    font-size: 0.78rem; color: var(--loyka-text); cursor: pointer;
  }
  .insumo-menu-item:hover { background: rgba(255, 255, 255, 0.06); }
  .insumo-menu-item.has-text-danger:hover { background: rgba(220, 53, 69, 0.12); }

  /* =========================================
     TOAST Y TABLAS MÓVILES (CON NESTING)
     ========================================= */
  #toast-container { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 99999; display: flex; flex-direction: column; gap: 10px; pointer-events: none; width: 90%; max-width: 400px; }
  .loyka-toast { padding: 12px 20px; border-radius: 50px; color: white; font-weight: 600; font-size: 0.9rem; display: flex; align-items: center; justify-content: center; gap: 8px; box-shadow: 0 4px 15px rgba(0,0,0,0.3); animation: slideUpToast 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards; text-align: center; }
  .loyka-toast.is-success { background: linear-gradient(135deg, var(--loyka-oliva), #0B815A); }
  .loyka-toast.is-danger { background: linear-gradient(135deg, var(--loyka-danger), #A3232F); }
  .loyka-toast.is-warning { background: linear-gradient(135deg, var(--loyka-warning), #B38300); color: #1C2434; }
  .loyka-toast.is-info { background: linear-gradient(135deg, var(--loyka-ocre), #1A73B3); color: #fff; }
  .loyka-toast.fade-out { animation: fadeOutToast 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards; }

  @keyframes slideUpToast { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
  @keyframes fadeOutToast { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(20px); } }

  /* =========================================
     REPORTAR BUG (BOTONES FLOTANTES)
     ========================================= */
  /* A propósito discretos: opacidad baja en reposo, suben al pasar el mouse.
     Van sueltos sobre el viewport (no dentro del sidebar, a diferencia de
     los otros íconos de acción) porque así los pidió el usuario: que no se
     vean mucho. */
  .loyka-fab {
    width: 40px; height: 40px; border-radius: 999px;
    display: flex; align-items: center; justify-content: center;
    background: var(--loyka-card-bg); border: 1px solid var(--loyka-border);
    color: var(--loyka-text-muted); opacity: 0.55; cursor: pointer;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); transition: opacity 0.2s, color 0.2s;
  }
  .loyka-fab:hover { opacity: 1; color: var(--loyka-terracota); }
  .loyka-fab svg { width: 18px; height: 18px; }

  .loyka-fab-right { position: fixed; bottom: 20px; right: 20px; z-index: 45; }

  /* .loyka-sidebar es fixed, 260px de ancho, pero solo VISIBLE desde
     1024px (ver .loyka-sidebar / @media min-width:1024px más abajo). Bajo
     1024px el sidebar está fuera de pantalla salvo que esté abierto, así
     que left:20px es seguro; desde 1024px hay que correrse a la derecha
     del sidebar (260px + 20px de aire) para no quedar tapado bajo su fila
     de acciones (.loyka-account-actions). */
  .loyka-fab-wrapper-left { position: fixed; bottom: 20px; left: 20px; z-index: 45; }
  @media (min-width: 1024px) {
    .loyka-fab-wrapper-left { left: 280px; }
  }
  /* El panel (.loyka-notif-panel, definido arriba) tiene 360px fijos, que
     nunca desbordan cuando vive dentro del sidebar porque el sidebar ya le
     reserva ese espacio. Acá el wrapper flota suelto sobre el viewport, así
     que en pantallas angostas 360px sí se pasaría del ancho disponible —
     se limita con min() para que nunca exceda el viewport. */
  .loyka-fab-wrapper-left .loyka-notif-panel { width: min(360px, calc(100vw - 40px)); }

  /* Texto del reporte: a diferencia de .loyka-notif-asunto (una línea con
     ellipsis, pensada para un asunto de correo corto), acá el texto puede
     ser largo y necesita leerse completo. */
  .loyka-reporte-bug-texto {
    font-size: 0.78rem; color: var(--loyka-text); white-space: normal;
    overflow-wrap: break-word; margin: 2px 0 4px 0;
  }
  .loyka-reporte-bug-acciones { display: flex; gap: 6px; margin-top: 2px; }

  @media screen and (max-width: 768px) {
    .tabla-scroll {
      border: none !important; background: transparent !important; overflow-x: visible !important;
      
      table:not(.no-cards) {
        background: transparent !important; display: block;
        
        thead { display: none; }
        tbody { display: block; }
        
        tbody tr {
          display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 6px 12px; padding: 16px; margin-bottom: 16px;
          border-radius: var(--radius-lg); background-color: #fff; border: 1px solid #f0f0f0;
          box-shadow: 0 4px 12px rgba(0,0,0,0.05); position: relative;
        }

        .dark-mode & tbody tr { background-color: #1f2937 !important; border-color: #374151 !important; box-shadow: 0 4px 12px rgba(0,0,0,0.2); }

        tbody td { display: flex; flex-direction: column; justify-content: center; padding: 0 !important; border: none !important; }
        tbody td:first-child { grid-column: 1 / -1; margin-bottom: 8px; align-items: flex-start !important; text-align: left !important; }
        tbody td:last-child {
          grid-column: 1 / -1; display: flex; flex-direction: row; justify-content: flex-end; align-items: center;
          flex-wrap: wrap; gap: 8px; margin-top: 8px; padding-top: 14px !important; border-top: 1px solid #f0f0f0 !important;
        }

        .dark-mode & tbody td:last-child { border-top-color: #374151 !important; }
        
        tbody td:nth-child(3):not(:last-child) { align-items: flex-end !important; text-align: right !important; }
        tbody td.has-text-centered, tbody td.has-text-right { text-align: inherit !important; }
        tbody td:first-child:last-child { align-items: center !important; text-align: center !important; border-top: none !important; padding: 16px !important; margin: 0 !important; }

        tfoot { display: block; }
        tfoot tr { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-radius: var(--radius-md); background: #fdfdfd; margin-bottom: 8px; border: 1px solid #f0f0f0; }
        
        .dark-mode & tfoot tr { background-color: #1f2937 !important; border-color: #374151 !important; }
        tfoot td { display: block; border: none !important; padding: 0 !important; }
        tfoot td[colspan] { text-align: left !important; flex-grow: 1; }
      }
    }
  }

  /* =========================================
     OTROS COMPONENTES
     ========================================= */
  .autocomplete-dropdown {
    display: none; position: absolute; top: 100%; left: 0; right: 0; z-index: 100;
    max-height: 200px; overflow-y: auto; border: 1px solid #dbdbdb; border-radius: var(--radius-sm);
    margin-top: 4px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); background: #fff;
  }
  .autocomplete-item { padding: 8px 12px; cursor: pointer; border-bottom: 1px solid #eee; transition: background 0.2s; font-size: 0.85rem; display: flex; align-items: center; gap: 8px; }
  .autocomplete-item:last-child { border-bottom: none; }
  .autocomplete-item:hover { background-color: #f5f5f5; color: var(--loyka-orange); font-weight: bold; }

  .skeleton-line { background-color: #e0e0e0; border-radius: 4px; animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
  @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
  .skeleton-row-venta td { padding: 12px 8px !important; }
  .skeleton-row-anotacion { animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite; }

  .offline-banner { display: none; position: sticky; top: 85px; background-color: var(--loyka-warning); color: #1C2434; text-align: center; padding: 8px; font-size: 0.8rem; z-index: 1040; }
  .lucide-spin { animation: spin 1.5s linear infinite; }
  @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

  .card-gasto { background: white; border-radius: 15px; padding: 15px; margin-bottom: 15px; box-shadow: 0 4px 10px rgba(0,0,0,0.05); border: 1px solid #f0f0f0; }
  .section-title { font-size: 0.85rem; font-weight: 700; color: var(--loyka-terracota); text-transform: uppercase; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; }
  .row-insumo { display: flex; gap: 4px; margin-bottom: 10px; padding-bottom: 10px; align-items: flex-end; width: 100%; border-bottom: 1px solid #d0d0d0; }
  .row-insumo:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
  .insumo-info { flex: 0 0 60%; width: 60%; box-sizing: border-box; padding-right: 4px; }
  .input-cant { flex: 0 0 40%; width: 40%; box-sizing: border-box; }
  .insumo-name { font-size: 0.8rem; font-weight: 600; color: #4a4a4a; display: block; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* =========================================
     FORZAR ESPACIADO Y AIRE AL GRID
     ========================================= */
  .section-app,
  .section-app .box,
  .loyka-main-content .box {
    padding: 1.5rem !important;
    box-sizing: border-box !important;
  }

  .loyka-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 16px;
    padding: 0.5rem !important;
    margin: 0 auto !important;
    width: 100% !important;
  }

  /* =========================================
     VENTAS: FORMULARIO + CARRITO EN COLUMNAS
     ========================================= */
  /* minmax(0, …) en vez de fracciones a secas — mismo motivo que
     .dashboard-charts-grid más abajo: sin el mínimo en 0 explícito, un
     hijo con contenido "ancho" (nombre de producto largo, etc.) puede
     empujar la columna más ancha que el espacio real disponible. */
  .venta-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; }
  @media (min-width: 900px) {
    .venta-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); align-items: start; }
    .venta-grid-cart { position: sticky; top: 110px; }
  }
  .venta-cart-box { border: 1px solid var(--loyka-border); background: var(--loyka-card-bg) !important; }

  /* =========================================
     DASHBOARD: GRÁFICOS (Chart.js)
     ========================================= */
  /* minmax(0, 1fr) en vez de 1fr a secas: un track "1fr" a secas respeta el
     ancho mínimo de contenido de lo que tenga adentro (min-width:auto, el
     mismo default de flex) — acá adentro vive un <canvas> de Chart.js que
     antes de que el resize responsive corra mide 300px fijos, así que el
     track (y la tarjeta, y todo lo que viene después) no podía angostarse
     más que eso y se salía del viewport en celular. minmax(0, 1fr) anula
     ese mínimo implícito. */
  .dashboard-charts-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; margin-top: 8px; }
  @media (min-width: 1024px) { .dashboard-charts-grid { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); align-items: stretch; } }
  .loyka-chart-card { margin: 0 !important; display: flex; flex-direction: column; min-width: 0; }
  .loyka-chart-canvas-wrap { position: relative; height: 280px; flex-grow: 1; min-width: 0; }

  /* =========================================
     DASHBOARD: ESTADO FINANCIERO / RENDIMIENTO GLOBAL
     ========================================= */
  .dashboard-panels-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; margin-top: 8px; }
  @media (min-width: 1024px) { .dashboard-panels-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; } }

  /* Fila de estadísticas arriba del Dashboard — el resumen "de un vistazo",
     antes de entrar en gráficos y detalle. */
  .dashboard-stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; margin-bottom: 28px; }
  .loyka-stat-card {
    background: var(--loyka-card-bg); border: 1px solid var(--loyka-border); border-radius: 10px;
    padding: 20px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  }
  .loyka-stat-icon {
    display: flex; align-items: center; justify-content: center; width: 44px; height: 44px;
    border-radius: 10px; background: rgba(226, 99, 43, 0.14); color: var(--loyka-terracota); margin-bottom: 16px;
  }
  .loyka-stat-icon svg { width: 22px; height: 22px; }
  .loyka-stat-icon.is-success { background: rgba(16, 185, 129, 0.16); color: var(--loyka-oliva); }
  .loyka-stat-icon.is-ocre { background: rgba(37, 154, 230, 0.18); color: var(--loyka-ocre); }
  .loyka-stat-value { font-size: 1.5rem; font-weight: 800; color: var(--loyka-text); line-height: 1.2; }
  .loyka-stat-value.has-text-danger { color: var(--loyka-danger) !important; }
  .loyka-stat-label { font-size: 0.78rem; color: var(--loyka-text-muted); font-weight: 600; margin-top: 4px; }
  .loyka-stat-trend { display: inline-flex; align-items: center; gap: 4px; font-size: 0.75rem; font-weight: 700; margin-top: 10px; }
  .loyka-stat-trend.is-up { color: var(--loyka-oliva); }
  .loyka-stat-trend.is-down { color: var(--loyka-danger); }
  .loyka-stat-trend svg { width: 14px; height: 14px; }

  .panel-card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
  .panel-card-header h3 { margin: 0; }
  .panel-pill {
    display: inline-flex; align-items: center; gap: 4px; padding: 4px 12px;
    border-radius: 999px; font-size: 0.75rem; font-weight: 700; white-space: nowrap;
  }
  .panel-pill.is-good { background: rgba(16, 185, 129, 0.18); color: var(--loyka-oliva); }
  .panel-pill.is-bad { background: rgba(220, 53, 69, 0.18); color: var(--loyka-danger); }

  .panel-hero-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--loyka-text-muted); font-weight: 700; }
  .panel-hero-value { font-size: 2rem; font-weight: 800; color: var(--loyka-text); line-height: 1.2; margin: 4px 0 12px; }
  .panel-alerta-linea { font-size: 0.85rem; color: var(--loyka-warning); font-weight: 600; display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
  .panel-alerta-linea svg { width: 15px; height: 15px; }

  .panel-mini-boxes { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin: 16px 0; }
  .panel-mini-box {
    background: rgba(255, 255, 255, 0.03); border: 1px solid var(--loyka-border);
    border-radius: var(--radius-md); padding: 10px 12px; text-align: left;
    display: flex; align-items: center; gap: 8px;
    transition: transform 0.15s ease, border-color 0.15s ease;
  }
  .panel-mini-box:hover { transform: translateY(-2px); border-color: var(--loyka-terracota); }
  .panel-mini-icon {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 32px; height: 32px; border-radius: var(--radius-md);
    background: rgba(226, 99, 43, 0.14); color: var(--loyka-terracota);
  }
  .panel-mini-icon svg { width: 16px; height: 16px; }
  .panel-mini-icon.is-success { background: rgba(16, 185, 129, 0.16); color: var(--loyka-oliva); }
  .panel-mini-icon.is-ocre { background: rgba(37, 154, 230, 0.18); color: var(--loyka-ocre); }
  .panel-mini-box .panel-mini-label { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.4px; color: var(--loyka-text-muted); font-weight: 700; }
  /* Antes 1.15rem: con un monto largo ($ millones, 7+ dígitos) no cabía en
     una sola línea dentro de estas cajas angostas y quedaba partido a la
     mitad (ver overflow-wrap más abajo) — más chico entra cómodo. */
  .panel-mini-box .panel-mini-value { font-size: 0.95rem; font-weight: 800; margin-top: 2px; }
  /* El span que envuelve label+valor es un hijo flex sin min-width:0 (el
     default es "auto", que no deja que un hijo flex se achique más allá del
     ancho de su contenido) — con un monto largo tipo "$2.133.326" eso hacía
     que el texto se saliera de la caja en vez de partirse en dos líneas. */
  .panel-mini-box span:not(.panel-mini-icon) { min-width: 0; overflow-wrap: break-word; }

  .panel-divider { border-top: 1px solid var(--loyka-border); margin: 16px 0; }
  .panel-flex-row { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
  .panel-flex-row .panel-hero-label { margin-bottom: 2px; }
  .panel-nota { font-size: 0.7rem; color: var(--loyka-text-muted); }

  .panel-progress-track { background: var(--loyka-border); border-radius: 999px; height: 8px; overflow: hidden; margin: 8px 0 20px; }
  .panel-progress-fill { background: var(--loyka-oliva); height: 100%; border-radius: 999px; transition: width 0.4s ease; }

  .producto-stock-row {
    display: flex; justify-content: space-between; align-items: center;
    padding: 12px 4px; border-bottom: 1px solid var(--loyka-border); cursor: pointer;
  }
  .producto-stock-row:last-child { border-bottom: none; }
  .producto-stock-row .producto-nombre { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 0.85rem; }
  .producto-stock-row .producto-lotes-count { color: var(--loyka-text-muted); font-weight: 400; font-size: 0.75rem; }
  .producto-stock-row .producto-stock-badge { display: flex; align-items: center; gap: 8px; }
  .producto-stock-row svg.chevron { width: 16px; height: 16px; transition: transform 0.2s ease; color: var(--loyka-text-muted); }
  .producto-stock-row.is-open svg.chevron { transform: rotate(180deg); }
  .producto-stock-detalle { display: none; padding: 4px 4px 12px 26px; }
  .producto-stock-detalle.is-open { display: block; }
  .producto-stock-detalle .lote-linea { display: flex; justify-content: space-between; font-size: 0.78rem; color: var(--loyka-text-muted); padding: 3px 0; }

  /* Tarjeta por lote del panel de Stock — más rica que .lote-linea (que
     solo tiene código + unidades, usada en el desglose viejo de Inicio):
     acá entra valor, antigüedad, estimación de días restantes, el botón
     de mermar y el historial de mermas si tiene. */
  .stock-lote-item {
    border: 1px solid var(--loyka-border); border-radius: var(--radius-md);
    padding: 12px 14px; margin: 8px 0;
  }
  .stock-lote-header {
    display: flex; justify-content: space-between; align-items: center;
    gap: 10px; font-size: 0.85rem; margin-bottom: 8px;
  }
  .stock-lote-datos {
    display: flex; gap: 16px; flex-wrap: wrap;
    font-size: 0.78rem; color: var(--loyka-text-muted);
  }
  .stock-lote-mermas { margin-top: 8px; border-top: 1px solid var(--loyka-border); padding-top: 8px; }

  .form-header {
    text-align: center;
    padding-top: 1rem !important;
    margin-bottom: 2rem !important;
  }

/* ==========================================
   VENTA RÁPIDA (public/venta-rapida.html)
   ========================================== */
.vr-topbar {
  display: flex; align-items: center; gap: 12px; padding: 14px 20px;
  border-bottom: 1px solid var(--loyka-border); position: sticky; top: 0;
  background: var(--loyka-bg); z-index: 10;
}
.vr-topbar-title { font-weight: 700; font-size: 1rem; color: var(--loyka-text); flex-grow: 1; }
#vr-root { padding: 20px; max-width: 900px; margin: 0 auto; }
.vr-menu {
  display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 40px;
}
@media (min-width: 600px) {
  .vr-menu { grid-template-columns: repeat(3, 1fr); }
}
.vr-menu .loyka-card { text-align: center; padding: 32px 20px; }
.vr-menu .loyka-card-icon { margin: 0 auto 14px auto; width: 56px; height: 56px; }
.vr-menu .loyka-card-icon svg { width: 28px; height: 28px; }
.vr-producto-row {
  border: 1px solid var(--loyka-border); border-radius: var(--radius-md);
  padding: 12px 14px; margin-bottom: 10px; background: var(--loyka-card-bg);
}
.vr-producto-detalle { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--loyka-border); }
.vr-foto-preview { margin-bottom: 8px; }
.vr-foto-thumb { width: 72px; height: 72px; object-fit: cover; border-radius: var(--radius-md); }
.vr-lista-sesiones { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.vr-lista-sesiones .loyka-card { padding: 16px 18px; }

.vr-pos { display: flex; flex-direction: column; gap: 20px; }
@media (min-width: 900px) {
  .vr-pos { flex-direction: row; align-items: flex-start; }
  .vr-pos-grid { flex: 1 1 60%; }
  .vr-carrito { flex: 1 1 40%; position: sticky; top: 70px; }
}
.vr-pos-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 14px;
}
.vr-tile {
  display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 12px;
  background: var(--loyka-card-bg); border: 1px solid var(--loyka-border); border-radius: var(--radius-md);
  cursor: pointer; text-align: center;
}
.vr-tile:active { transform: scale(0.97); border-color: var(--accent); }
.vr-tile-foto { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--radius-md); }
.vr-tile-nombre { font-weight: 700; font-size: 0.9rem; color: var(--loyka-text); }
.vr-tile-precio { font-size: 0.85rem; color: var(--loyka-text-muted); }

.vr-carrito {
  background: var(--loyka-card-bg); border: 1px solid var(--loyka-border); border-radius: var(--radius-md);
  padding: 16px;
}
.vr-carrito-titulo { font-weight: 700; margin-bottom: 10px; color: var(--loyka-text); }
.vr-carrito-lista { display: flex; flex-direction: column; gap: 8px; max-height: 40vh; overflow-y: auto; }
.vr-carrito-item {
  display: grid; grid-template-columns: 1fr auto; gap: 4px; align-items: center;
  padding: 8px 0; border-bottom: 1px solid var(--loyka-border);
}
.vr-carrito-item-nombre { font-weight: 600; color: var(--loyka-text); grid-column: 1 / 2; }
.vr-carrito-item-subtotal { font-weight: 700; color: var(--loyka-text); grid-column: 2 / 3; text-align: right; }
.vr-carrito-item-controles { grid-column: 1 / 3; display: flex; align-items: center; gap: 8px; }
.vr-carrito-item-cantidad { font-weight: 700; min-width: 20px; text-align: center; }

/* Total en tipografía grande y alto contraste: pensado para mostrárselo
   al cliente, reemplazando el rol de una boleta/pantalla de caja registradora. */
.vr-carrito-total {
  display: flex; justify-content: space-between; align-items: center;
  margin: 16px 0; padding: 16px 0; border-top: 2px solid var(--loyka-border);
  font-size: 1.6rem; font-weight: 800; color: var(--loyka-text);
}
.vr-carrito-total-monto { color: var(--loyka-oliva); }

.vr-historial-titulo { font-weight: 700; font-size: 1.1rem; color: var(--loyka-text); margin-bottom: 4px; }
.vr-historial-total { font-size: 1.2rem; font-weight: 800; color: var(--loyka-oliva); margin-bottom: 16px; }
.vr-historial-lista { display: flex; flex-direction: column; gap: 10px; }
.vr-historial-item {
  background: var(--loyka-card-bg); border: 1px solid var(--loyka-border); border-radius: var(--radius-md);
  padding: 12px 14px;
}
.vr-historial-item-cabecera { display: flex; justify-content: space-between; font-weight: 700; color: var(--loyka-text); margin-bottom: 6px; }
.vr-historial-item-detalle { font-size: 0.8rem; color: var(--loyka-text-muted); }
