/* PepeSoft — sistema de temas (mecanismo de liramar/soft, paleta propia — ver SDD.md § D).
   4 temas conmutables vía [data-theme] en <html>, persistidos en localStorage['pepesoft-theme'].
   "elegante" es el default sin atributo (bloque :root); los otros 3 lo sobreescriben.

   Paleta validada contra WCAG AA (4.5:1) en los 4 temas, cada token contra --bg y
   contra --bg-card. Antes de tocar un color, recalcular: el botón primario llegó a
   estar en 1.92:1 (texto blanco sobre verde) por no hacerlo. */

/* --- Fuentes auto-alojadas (variables, 4 archivos / ~126KB).
   Antes venían del CDN de Google en cada carga de página; se auto-alojan por el
   mismo criterio que public/js/vendor/qrcode.min.js: un sistema financiero
   privado no le avisa a un tercero cada vez que se abre una pantalla. --- */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url('/fonts/dm-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url('/fonts/dm-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/cormorant-garamond-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/cormorant-garamond-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg:            #14171C;
  --bg-card:       rgba(255,255,255,0.03);
  --bg-card-hover: rgba(255,255,255,0.06);
  --bg-row-hover:  rgba(255,255,255,0.04);
  --bg-elevado:       #292C31;
  --bg-elevado-hover: #2C2F34;
  --sombra-elevada:   0 10px 30px rgba(0,0,0,.5);
  --text:          #F2F4F3;
  --text-dim:      #9AA5A0;
  --text-muted:    #969E9A;
  --label:         #9AA5A0;
  --border:        rgba(255,255,255,0.08);
  --border-strong: rgba(255,255,255,0.16);
  --border-focus:  #34D399;
  --accent:        #34D399;
  --accent-hover:  #6EE7B7;
  --on-accent:     #06251A;
  --success:       #34D399;
  --danger:        #F87171;
  --warning:       #FBBF24;
  --overlay:       rgba(0,0,0,0.6);

  /* Barra de navegación: superficie propia y siempre oscura en los 4 temas
     (patrón liramar/soft). --nav-accent existe porque el --accent del tema no
     llega a 4.5:1 sobre la barra en los temas claros (clásico 2.33:1, playa
     2.50:1). Ratios medidos: --nav-text ≥9.78, --nav-accent ≥6.54. */
  --nav-bg:        #0B2A21;
  --nav-text:      #CFE9DD;
  --nav-accent:    #6EE7B7;
  --nav-border:    rgba(110,231,183,0.20);
  --nav-hover-bg:  rgba(255,255,255,0.08);   /* la barra es oscura en todos los temas */

  /* Moneda — se usan como TEXTO: ≥4.5:1 contra --bg y --bg-card (peor caso 4.97).
     Tipo de cuenta — DECORATIVOS (bordes/barras): ≥3:1 (peor caso 4.70).
     --tipo-banco hereda el --accent del tema activo. */
  --pen:           #22D3EE;
  --usd:           #C4B5FD;
  --tipo-banco:    var(--accent);
  --tipo-caja:     #FB923C;
  --tipo-especial: #F472B6;

  --font-display:  'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --font-body:     'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --title-weight:  600;   /* Cormorant a 500 se leía fino: los títulos no destacaban */

  /* Escala de espaciado — densidad alta (dashboard), ver SDD.md § D. */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: .75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;

  /* Área táctil mínima (WCAG 2.5.5 / iOS HIG). */
  --tap: 44px;
}

[data-theme="clasico"] {
  --bg:            #F7F9FC;
  --bg-card:       #FFFFFF;
  --bg-card-hover: #EEF2F8;
  --bg-row-hover:  #F1F5FB;
  --bg-elevado:       #FFFFFF;
  --bg-elevado-hover: #EEF2F8;
  --sombra-elevada:   0 8px 24px rgba(27,36,48,.16);
  --text:          #1B2430;
  --text-dim:      #5B6674;
  --text-muted:    #6B7280;
  --label:         #5B6674;
  --border:        #E2E8F0;
  --border-strong: #CBD5E1;
  --border-focus:  #3B5BDB;
  --accent:        #3B5BDB;
  --accent-hover:  #2F49B0;
  --on-accent:     #FFFFFF;
  --success:       #047857;
  --danger:        #DC2626;
  --warning:       #B45309;
  --overlay:       rgba(27,36,48,0.45);
  --nav-bg:        #1B2F57;
  --nav-text:      #D6DEEF;
  --nav-accent:    #9DB4FF;
  --nav-border:    rgba(157,180,255,0.22);
  --pen:           #0E7490;
  --usd:           #7E22CE;
  --tipo-caja:     #C2410C;
  --tipo-especial: #BE185D;
}

[data-theme="playa"] {
  --bg:            #FBF3E7;
  --bg-card:       #FFFFFF;
  --bg-card-hover: #F5E8D6;
  --bg-row-hover:  #FAF1E3;
  --bg-elevado:       #FFFFFF;
  --bg-elevado-hover: #F5E8D6;
  --sombra-elevada:   0 8px 24px rgba(58,46,34,.18);
  --text:          #3A2E22;
  --text-dim:      #6B5D4C;
  --text-muted:    #77685A;
  --label:         #6B5D4C;
  --border:        #E9D9C0;
  --border-strong: #D8C3A0;
  --border-focus:  #A14F1F;
  --accent:        #A14F1F;
  --accent-hover:  #85401A;
  --on-accent:     #FFFFFF;
  --success:       #15803D;
  --danger:        #B3261E;
  --warning:       #92400E;
  --overlay:       rgba(58,46,34,0.45);
  --nav-bg:        #3B2518;
  --nav-text:      #F3E3D0;
  --nav-accent:    #F4A77A;
  --nav-border:    rgba(244,167,122,0.22);
  --pen:           #0F766E;
  --usd:           #86198F;
  /* Azul y no naranja: el --accent de playa (= --tipo-banco) ya es terracota
     y un caja naranja quedaba a 5° de tono, indistinguible. */
  --tipo-caja:     #1D4ED8;
  --tipo-especial: #9D174D;
}

[data-theme="moderno"] {
  --bg:            #0F172A;
  --bg-card:       rgba(255,255,255,0.04);
  --bg-card-hover: rgba(255,255,255,0.08);
  --bg-row-hover:  rgba(255,255,255,0.05);
  --bg-elevado:       #1F273A;
  --bg-elevado-hover: #222A3D;
  --sombra-elevada:   0 10px 30px rgba(0,0,0,.55);
  --text:          #E2E8F0;
  --text-dim:      #94A3B8;
  --text-muted:    #95A1B4;
  --label:         #94A3B8;
  --border:        rgba(255,255,255,0.08);
  --border-strong: rgba(255,255,255,0.18);
  --border-focus:  #818CF8;
  --accent:        #818CF8;
  --accent-hover:  #A5B4FC;
  --on-accent:     #101A33;
  --success:       #34D399;
  --danger:        #F87171;
  --warning:       #FBBF24;
  --overlay:       rgba(2,6,23,0.65);
  --nav-bg:        #1E1B4B;
  --nav-text:      #E0E7FF;
  --nav-accent:    #A5B4FC;
  --nav-border:    rgba(165,180,252,0.22);
  --pen:           #67E8F9;
  --usd:           #F0ABFC;
  --tipo-caja:     #FB923C;
  --tipo-especial: #F472B6;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
}

a { color: inherit; }

label {
  display: block;
  color: var(--text-dim);
  font-size: .8125rem;
  margin-bottom: .25rem;
}

/* --- Movimiento: 150-300ms, solo color/opacidad/transform (nunca width/height).
   Antes no había ninguna transición: todo cambiaba de estado en 0ms. --- */
.btn, .erp-nav-link, .nav-group-trigger, .nav-group-item, .back-link,
.card, .stat-card, input, select, textarea, tbody tr, summary, .alerta-item {
  transition: background-color .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Accesibilidad --- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--accent);
  color: var(--on-accent);
  padding: .75rem 1.25rem;
  font-size: .875rem;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- Regla global del usuario (aplica a TODAS las tablas de PepeSoft, ver
   SDD.md § D): números alineados a la derecha, encabezado incluido, con
   cifras tabulares. Se aplica poniendo la clase .num en <th>/<td>. Texto,
   fechas y estados no la llevan. --- */
.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-body);
  white-space: nowrap;
}

/* --- Tablas ---
   .tabla-scroll: envoltorio obligatorio de toda <table> — sin él la página
   entera hace scroll horizontal en el celular.
   OJO: crea contexto de recorte, así que nada posicionado en absoluto adentro
   (los popovers de fila son <dialog>, no <details>, justamente por esto). --- */
.tabla-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: .875rem;
}
th {
  text-align: left;
  font-size: .75rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: .6rem .75rem;
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
}
td {
  padding: .6rem .75rem;
  border-bottom: 1px solid var(--border);
}
tbody tr:hover { background: var(--bg-row-hover); }

.td-sub {
  display: block;
  font-size: .8125rem;
  color: var(--text-muted);
}

/* Bajo 640px una tabla de 8 columnas no se lee ni con scroll: cada fila pasa a
   ser una tarjeta, con el encabezado repetido desde data-label en cada celda. */
@media (max-width: 640px) {
  .tabla-cards thead { display: none; }
  .tabla-cards, .tabla-cards tbody, .tabla-cards tr, .tabla-cards td { display: block; width: 100%; }
  .tabla-cards tr {
    border: 1px solid var(--border);
    background: var(--bg-card);
    margin-bottom: .75rem;
    padding: .25rem 0;
  }
  .tabla-cards td {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: .25rem 1rem;
    border-bottom: 1px solid var(--border);
    padding: .5rem .875rem;
    text-align: left;
  }
  .tabla-cards td:last-child { border-bottom: none; }
  .tabla-cards td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-size: .6875rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-dim);
  }
  .tabla-cards td.num { justify-content: space-between; }
  .tabla-cards td:empty { display: none; }
  /* La celda es flex, así que la sub-línea se volvería un ítem más al costado del
     valor: se la fuerza a ocupar su propio renglón, debajo. */
  .tabla-cards .td-sub { flex: 0 0 100%; text-align: right; }
  /* Fila de "sin resultados" (un solo td con colspan): no lleva data-label y
     no debe maquetarse como par etiqueta/valor. */
  .tabla-cards td:not([data-label]) { display: block; text-align: center; }
  .tabla-cards td:not([data-label])::before { content: none; }
}

/* --- Nav ---
   Barra de 3 zonas: marca a la izquierda, navegación de contenido CENTRADA
   respecto de la página (grid 1fr auto 1fr) y preferencias de sesión a la
   derecha (Configuración, Tema, Mi cuenta, Salir). En desktop .erp-nav-links
   es display:contents para que sus dos hijos sean celdas del grid de .erp-nav;
   en móvil vuelve a ser el panel colapsable de la hamburguesa.

   La barra es una superficie propia (--nav-bg), oscura en los 4 temas: nada
   de lo que se dibuja SOBRE ella usa --text/--accent del tema (calibrados
   para --bg). Los desplegables sí: flotan sobre --bg-elevado. --- */
.erp-nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: 1.5rem;
  padding: 0 1.5rem;
  min-height: 56px;
  background: var(--nav-bg);
  border-bottom: 1px solid var(--nav-border);
  position: sticky;
  top: 0;
  z-index: 40;
}
.erp-brand {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  min-height: var(--tap);
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 600;
  text-decoration: none;
  color: #FFFFFF;   /* ≥13.2:1 sobre --nav-bg en los 4 temas */
}
.erp-brand::before {   /* pip con el acento de la barra: identidad de color del tema */
  content: "";
  width: .55rem; height: .55rem; border-radius: 50%;
  background: var(--nav-accent);
}
.erp-nav-links { display: contents; }
.erp-nav-centro, .erp-nav-right { display: flex; align-items: center; }
.erp-nav-centro { justify-self: center; gap: 1.75rem; }
.erp-nav-right  { justify-self: end; gap: 1.25rem; }

.erp-nav-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-size: .875rem;
  letter-spacing: .02em;
  text-decoration: none;
  color: var(--nav-text);
}
.erp-nav-link:hover { color: var(--nav-accent); }
.erp-nav-link.active { color: var(--nav-accent); box-shadow: inset 0 -2px 0 var(--nav-accent); }

.nav-group { position: relative; }
.nav-group-trigger {
  background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: .875rem; letter-spacing: .02em;
  color: var(--nav-text); display: flex; align-items: center; gap: .35rem;
  min-height: var(--tap); padding: 0;
}
.nav-group-trigger:hover, .nav-group.open .nav-group-trigger { color: var(--nav-accent); }
.nav-group.active .nav-group-trigger { color: var(--nav-accent); box-shadow: inset 0 -2px 0 var(--nav-accent); }
.nav-group-arrow { width: .625rem; height: .625rem; flex-shrink: 0; }
.nav-group.open .nav-group-arrow { transform: rotate(180deg); }
.nav-group-dropdown {
  display: none; position: absolute; top: 100%; left: 0; min-width: 200px;
  background: var(--bg-elevado); border: 1px solid var(--border-strong);
  box-shadow: var(--sombra-elevada);
  padding: .35rem; z-index: 20;
}
/* Los grupos de la zona derecha abren hacia adentro: si no, se salen del viewport. */
.erp-nav-right .nav-group-dropdown { left: auto; right: 0; }
.nav-group.open .nav-group-dropdown { display: block; }
.nav-group-item {
  display: flex; align-items: center; min-height: var(--tap);
  padding: .25rem .6rem; font-size: .875rem;
  text-decoration: none; color: var(--text-dim);
}
.nav-group-item:hover, .nav-group-item.active { color: var(--accent); background: var(--bg-elevado-hover); }

.nav-salir { display: inline-flex; margin: 0; }
.erp-nav .link-accion { color: var(--nav-text); font-size: .875rem; }
.erp-nav .link-accion:hover { color: var(--nav-accent); }
/* El anillo de foco global usa --border-focus (acento del tema), que no llega a
   3:1 sobre la barra en clásico/playa. Solo los controles apoyados en la barra. */
.erp-brand:focus-visible, .erp-nav-link:focus-visible, .nav-group-trigger:focus-visible,
.erp-nav-toggle:focus-visible, .erp-nav .link-accion:focus-visible { outline-color: var(--nav-accent); }

/* Selector de tema: un .nav-group más, con una muestra por tema. Los colores
   son literales a propósito — cada muestra enseña OTRO tema (su barra y su
   acento), no el activo. */
.tema-pip { width: .5rem; height: .5rem; border-radius: 50%; background: var(--nav-accent); flex-shrink: 0; }
.tema-opcion {
  display: flex; align-items: center; gap: .65rem; width: 100%;
  min-height: var(--tap); padding: .25rem .6rem;
  background: none; border: none; cursor: pointer; text-align: left;
  font-family: inherit; font-size: .875rem; color: var(--text-dim);
}
.tema-opcion:hover { color: var(--accent); background: var(--bg-elevado-hover); }
.tema-opcion[aria-pressed="true"] { color: var(--text); font-weight: 500; }
.tema-muestra {
  position: relative; flex-shrink: 0;
  width: 1.25rem; height: 1.25rem; border-radius: 50%;
  border: 2px solid var(--border-strong);
}
.tema-muestra::after {
  content: ""; position: absolute; right: -3px; bottom: -3px;
  width: .55rem; height: .55rem; border-radius: 50%;
}
.tema-opcion[aria-pressed="true"] .tema-muestra { border-color: var(--accent); }
.tema-opcion[data-tema="elegante"] .tema-muestra        { background: #0B2A21; }
.tema-opcion[data-tema="elegante"] .tema-muestra::after { background: #34D399; }
.tema-opcion[data-tema="clasico"]  .tema-muestra        { background: #1B2F57; }
.tema-opcion[data-tema="clasico"]  .tema-muestra::after { background: #3B5BDB; }
.tema-opcion[data-tema="playa"]    .tema-muestra        { background: #3B2518; }
.tema-opcion[data-tema="playa"]    .tema-muestra::after { background: #A14F1F; }
.tema-opcion[data-tema="moderno"]  .tema-muestra        { background: #1E1B4B; }
.tema-opcion[data-tema="moderno"]  .tema-muestra::after { background: #818CF8; }

.erp-nav-toggle {
  display: none; background: none; border: none; color: var(--nav-text); cursor: pointer;
  min-width: var(--tap); min-height: var(--tap);
  align-items: center; justify-content: center;
}
@media (max-width: 768px) {
  .erp-nav { display: flex; justify-content: space-between; }
  .erp-nav-toggle { display: flex; }
  .erp-nav-links {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch;
    background: var(--nav-bg); border-bottom: 1px solid var(--nav-border);
    padding: .5rem 1rem 1rem; z-index: 30;
    max-height: calc(100dvh - 56px); overflow-y: auto;
  }
  .erp-nav-links.open { display: flex; }
  .erp-nav-centro, .erp-nav-right { flex-direction: column; align-items: stretch; gap: 0; }
  .erp-nav-right { margin-top: .5rem; padding-top: .5rem; border-top: 1px solid var(--nav-border); }
  /* En el panel móvil los desplegables quedan apoyados en la barra, no flotan:
     pasan a los tokens de la barra. */
  .nav-group-dropdown, .erp-nav-right .nav-group-dropdown {
    position: static; background: transparent; border: none; box-shadow: none;
    padding: 0 0 .25rem 1rem;
  }
  .nav-group-item, .tema-opcion { color: var(--nav-text); }
  .nav-group-item:hover, .nav-group-item.active,
  .tema-opcion:hover, .tema-opcion[aria-pressed="true"] { color: var(--nav-accent); background: var(--nav-hover-bg); }
  .nav-group-item:focus-visible, .tema-opcion:focus-visible { outline-color: var(--nav-accent); }
  .erp-nav-link.active, .nav-group.active .nav-group-trigger { box-shadow: none; }
}

/* --- Botones ---
   Alto mínimo = --tap en todos: los de icono llegaban a ~26px. --- */
.btn {
  font-family: var(--font-body); font-size: .8125rem; letter-spacing: .04em; text-transform: uppercase;
  padding: .55rem 1.25rem; border: 1px solid var(--border-strong); background: transparent; color: var(--accent);
  cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: var(--tap);
}
.btn:hover { background: var(--bg-card-hover); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--on-accent); }
.btn-icon { padding: .5rem; border: none; min-width: var(--tap); }
.btn-icon svg { width: 1.125rem; height: 1.125rem; }
.btn-danger { color: var(--danger); }
.btn-danger:hover { background: var(--bg-card-hover); }
/* 36px es aceptable con mouse; en pantalla táctil vuelve al mínimo de 44px. */
.btn-sm { font-size: .75rem; padding: .35rem .75rem; min-height: 36px; }
@media (max-width: 640px), (pointer: coarse) {
  .btn-sm { min-height: var(--tap); padding: .5rem 1rem; }
}
.btn-block { width: 100%; }

/* Acción secundaria en texto (Editar / Eliminar / volver) — sigue siendo táctil. */
.link-accion {
  display: inline-flex; align-items: center; min-height: var(--tap);
  background: none; border: none; padding: 0;
  font-family: var(--font-body); font-size: .8125rem;
  color: var(--label); text-decoration: none; cursor: pointer;
}
.link-accion:hover { color: var(--accent); }
.link-accion.danger { color: var(--danger); }

.back-link {
  display: inline-flex; align-items: center; gap: .35rem;
  min-height: var(--tap);
  font-size: .8125rem; text-decoration: none; color: var(--label);
}
.back-link:hover { color: var(--accent); }

.row-actions { display: flex; gap: .25rem; align-items: center; white-space: nowrap; }

/* --- Formularios --- */
input, select, textarea {
  width: 100%; box-sizing: border-box; background: var(--bg); border: 1px solid var(--border-strong);
  color: var(--text); font-family: var(--font-body); font-size: .9375rem; padding: .6rem .8rem;
  min-height: var(--tap);
}
input[type="checkbox"], input[type="radio"] {
  width: 1.125rem; height: 1.125rem; min-height: 0; padding: 0; accent-color: var(--accent);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--border-focus); }
input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, a:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}

.form-row { display: grid; gap: 1rem; margin-bottom: 1rem; }
.form-row-2 { grid-template-columns: 1fr 1fr; }
.form-row-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 560px) {
  .form-row-2, .form-row-3 { grid-template-columns: 1fr; }
}
.form-field { margin-bottom: 1rem; }
.hint { display: block; font-size: .8125rem; color: var(--text-muted); margin-top: .25rem; }
.hint-error { color: var(--danger); }

/* --- Badges de estado --- */
.badge {
  display: inline-flex; align-items: center; gap: .25rem;
  padding: .2rem .5rem; font-size: .75rem; letter-spacing: .03em;
  text-transform: uppercase; border: 1px solid; white-space: nowrap;
}
.badge svg { width: .75rem; height: .75rem; flex-shrink: 0; }
.badge-success { color: var(--success); border-color: var(--success); }
.badge-warning { color: var(--warning); border-color: var(--warning); }
.badge-danger  { color: var(--danger);  border-color: var(--danger); }
.badge-muted   { color: var(--text-muted); border-color: var(--border-strong); }

/* --- Contenedor de página --- */
.page { max-width: 1200px; margin: 0 auto; padding: 2rem 1.5rem; }
.page-narrow { max-width: 460px; }

/* Pantallas de sesión (login / totp / setup / códigos) — 100dvh, no 100vh:
   con 100vh la barra de direcciones del móvil corta el contenido. */
.page-centrada {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg); padding: 2rem 1.5rem;
}
.page-centrada > * { width: 100%; max-width: 380px; }

/* Títulos con más presencia: el eyebrow toma el acento del tema (validado a
   4.5:1 contra --bg), el título crece y la cabecera cierra con un tramo de
   acento. Las secciones llevan una barra lateral cuyo color puede fijar la
   vista (--tipo-color; en /bancos, el tipo de cuenta). */
.eyebrow {
  display: block; font-size: .75rem; font-weight: 500; letter-spacing: .18em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .35rem;
}
.page-title { font-family: var(--font-display); font-size: clamp(1.9rem, 4vw, 2.6rem); font-weight: var(--title-weight); margin: 0; line-height: 1.15; }
.section-title {
  display: flex; align-items: center; gap: .6rem;
  font-family: var(--font-display); font-size: 1.5rem; font-weight: var(--title-weight); line-height: 1.2;
  margin: 0 0 1rem; padding-left: .75rem;
  border-left: 4px solid var(--tipo-color, var(--accent));
}
.section-title svg { width: 1.3rem; height: 1.3rem; flex-shrink: 0; color: var(--tipo-color, var(--accent)); }
.section-title .contador { font-family: var(--font-body); font-size: .8125rem; font-weight: 400; color: var(--text-muted); }

.page-header {
  position: relative;
  display: flex; align-items: flex-end; justify-content: space-between;
  margin-bottom: 2rem; padding-bottom: 1.25rem; flex-wrap: wrap; gap: 1rem;
  border-bottom: 1px solid var(--border);
}
.page-header::after {
  content: ""; position: absolute; left: 0; bottom: -1px;
  width: 4rem; height: 3px; background: var(--accent);
}
.toolbar {
  display: flex; gap: 1rem; justify-content: space-between; align-items: center;
  margin-bottom: 1rem; flex-wrap: wrap;
}
.toolbar-grupo { display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap; }

/* Tarjetas con un borde superior de color. Por defecto el acento del tema; la
   vista puede fijar --card-accent (borde) y --card-valor (cifra) — en /bancos
   lo hacen .is-pen / .is-usd. */
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
.stat-card {
  padding: 1rem 1.25rem; border: 1px solid var(--border); background: var(--bg-card);
  border-top: 3px solid var(--card-accent, var(--accent));
}
.stat-card .label {
  display: flex; align-items: center; gap: .45rem;
  font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); margin-bottom: .35rem;
}
/* Las tarjetas de stats llevan .num en el markup, pero la regla de "números a la
   derecha" es de TABLAS (SDD.md § D): acá el valor va bajo una etiqueta alineada
   a la izquierda, así que se alinea con ella. Se conserva tabular-nums. */
.stat-card .value {
  font-family: var(--font-body); font-size: 1.75rem; font-weight: 500;
  font-variant-numeric: tabular-nums; display: block; text-align: left;
  color: var(--card-valor, var(--text));
}

.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
.card {
  padding: 1.25rem; border: 1px solid var(--border); background: var(--bg-card);
  border-top: 3px solid var(--card-accent, var(--accent));
}
.card:hover { background: var(--bg-card-hover); }
.card-header { display: flex; justify-content: space-between; align-items: flex-start; gap: .75rem; margin-bottom: .875rem; }
.card-titulo { font-size: 1.125rem; font-weight: 500; }

/* Moneda: color de TEXTO (≥4.5:1). El significado nunca queda solo en el
   color — el badge dice PEN/USD y la cifra lleva S/ o $. */
.is-pen { --card-accent: var(--pen); --card-valor: var(--pen); }
.is-usd { --card-accent: var(--usd); --card-valor: var(--usd); }
.badge-pen { color: var(--pen); border-color: var(--pen); }
.badge-usd { color: var(--usd); border-color: var(--usd); }
/* Tipo de cuenta: color DECORATIVO (≥3:1) para barras, íconos y pips. */
.tipo-banco    { --tipo-color: var(--tipo-banco); }
.tipo-caja     { --tipo-color: var(--tipo-caja); }
.tipo-especial { --tipo-color: var(--tipo-especial); }
.tipo-pip { width: .5rem; height: .5rem; flex-shrink: 0; background: var(--tipo-color, var(--accent)); }

/* --- Estado vacío: siempre con su acción, es el momento en que más sirve --- */
.empty-state {
  padding: 3rem 1.5rem; text-align: center; border: 1px solid var(--border);
  display: flex; flex-direction: column; align-items: center; gap: 1rem;
}
.empty-state p { color: var(--text-dim); font-size: .9375rem; margin: 0; max-width: 42ch; }

/* --- Popover de cabecera (<details>) — solo fuera de tablas.
   Dentro de .tabla-scroll queda recortado: ahí va <dialog>. --- */
.popover { position: relative; }
.popover > summary {
  display: inline-flex; align-items: center; gap: .3rem;
  min-height: var(--tap);
  cursor: pointer; font-size: .8125rem; color: var(--accent); list-style: none;
}
.popover > summary::-webkit-details-marker { display: none; }
.popover-panel {
  position: absolute; right: 0; top: calc(100% + .25rem); z-index: 25;
  background: var(--bg-elevado); border: 1px solid var(--border-strong);
  box-shadow: var(--sombra-elevada);
  padding: 1.25rem; width: 340px; max-width: calc(100vw - 3rem);
  text-align: left;
}
.popover-panel.w-sm { width: 260px; }
.popover-panel.w-lg { width: 420px; }

/* --- Diálogos --- */
dialog.modal {
  border: 1px solid var(--border-strong);
  background: var(--bg-elevado);
  box-shadow: var(--sombra-elevada);
  color: var(--text);
  padding: 1.5rem;
  max-width: 480px;
  width: min(92vw, 480px);
  max-height: 85dvh;
  overflow-y: auto;
}
dialog.modal::backdrop { background: var(--overlay); }
.modal-titulo { font-family: var(--font-display); font-size: 1.35rem; font-weight: var(--title-weight); margin: 0 0 1.25rem; }
.modal-acciones { display: flex; gap: .5rem; justify-content: flex-end; flex-wrap: wrap; }

/* --- Avisos (flash del servidor y toasts del cliente) ---
   Llevan icono además de color: el color solo no transmite el estado. --- */
.alert {
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .75rem 1rem; border: 1px solid var(--border-strong);
  font-size: .875rem; background: var(--bg-elevado);
}
.alert svg { width: 1.125rem; height: 1.125rem; flex-shrink: 0; margin-top: .1rem; }
.alert-error   { border-color: var(--danger);  color: var(--danger); }
.alert-success { border-color: var(--success); color: var(--success); }
.alert-info    { border-color: var(--accent);  color: var(--accent); }
.alert > span { color: var(--text); }

.alert-host { max-width: 1200px; margin: 1rem auto 0; padding: 0 1.5rem; }

#toast-host .alert { box-shadow: var(--sombra-elevada); }
#toast-host {
  position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 1000;
  display: flex; flex-direction: column; gap: .5rem;
  max-width: min(360px, calc(100vw - 3rem));
}

/* --- Dashboard de Alertas --- */
.alerta-item {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: .85rem 1rem; border: 1px solid var(--border);
  border-left: 3px solid var(--urgencia, var(--border-strong));
  background: var(--bg-card); flex-wrap: wrap;
}
.alerta-item:hover { background: var(--bg-card-hover); }
.alerta-link { text-decoration: none; color: var(--text); flex: 1 1 16rem; min-width: 0; }
.alerta-titulo { display: block; font-size: .9375rem; }
.alerta-contexto { display: block; font-size: .8125rem; color: var(--text-muted); }
.alerta-acciones { display: flex; gap: .4rem; flex-shrink: 0; }
.lista-alertas { display: flex; flex-direction: column; gap: .6rem; margin-bottom: 2rem; }

/* --- Utilidades puntuales --- */
.mb-0 { margin-bottom: 0; }
.mb-2 { margin-bottom: .5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 2rem; }
.mt-4 { margin-top: 1rem; }
.mt-6 { margin-top: 2rem; }
.flex-1 { flex: 1; }
.text-dim { color: var(--text-dim); }
.text-muted { color: var(--text-muted); }
.filtro-input { max-width: 320px; }
/* El form que envuelve un botón "Eliminar"/"Anular" de fila (para poder
   mandar el csrf_token propio) no debe romper el flujo en línea con los
   demás botones de la celda — antes 10 vistas repetían este mismo
   style="display:inline;" (auditoría 2026-09-26, hallazgo Bajo). */
.d-inline { display: inline; }

/* --- Detalle de cuenta bancaria (Módulo 1): tabs, barra de filtros,
   encabezados ordenables, monto con signo --- */
.chip-tabs { gap: .4rem; }
.chip-tab {
  display: inline-flex; align-items: center; min-height: 36px;
  padding: .3rem .8rem; font-size: .75rem; letter-spacing: .04em; text-transform: uppercase;
  text-decoration: none; color: var(--text-dim);
  border: 1px solid var(--border-strong); background: transparent;
}
.chip-tab:hover { color: var(--accent); }
.chip-tab.is-active { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }

.filtros-bar {
  border: 1px solid var(--border); background: var(--bg-card);
  padding: .875rem 1rem; margin-bottom: 1.25rem;
  display: flex; flex-direction: column; gap: .75rem;
}
.filtros-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip-rapido {
  display: inline-flex; align-items: center; min-height: 32px;
  padding: .2rem .65rem; font-size: .75rem;
  text-decoration: none; color: var(--text-muted);
  border: 1px dashed var(--border-strong); background: transparent;
}
.chip-rapido:hover { color: var(--accent); border-style: solid; }
.filtros-grid { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; }
.filtro-campo { flex: 0 0 auto; min-width: 150px; }
.filtro-campo-ancho { flex: 1 1 240px; }
.filtro-campo label {
  display: block; font-size: .6875rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: .25rem;
}
.filtros-acciones { display: flex; align-items: center; gap: .75rem; }
@media (max-width: 560px) {
  .filtro-campo, .filtro-campo-ancho { flex: 1 1 100%; min-width: 0; }
}

.th-sort {
  display: inline-flex; align-items: center; gap: .3rem;
  color: inherit; text-decoration: none;
}
.th-sort:hover { color: var(--accent); }
th[aria-sort="ascending"] .th-sort, th[aria-sort="descending"] .th-sort { color: var(--accent); }
.th-ord { width: .8125rem; height: .8125rem; flex-shrink: 0; opacity: .35; }
.th-ord.is-on { opacity: 1; }
th.num .th-sort { justify-content: flex-end; }

.num-pos { color: var(--success); }
.num-neg { color: var(--danger); }

dialog.modal.modal-ancho { max-width: 760px; width: min(94vw, 760px); }

.chip-tipo {
  width: auto; min-height: 30px; padding: .1rem .5rem;
  font-size: .75rem; text-transform: capitalize;
  border: 1px solid var(--border-strong); background: transparent; color: var(--text);
  cursor: pointer;
}
.chip-tipo:hover { border-color: var(--accent); color: var(--accent); }

/* Preview de importación: resaltar las filas que hay que mirar antes de
   confirmar (posible duplicado / a verificar). El fondo ámbar semitransparente
   lee como "atención" sobre los 4 temas; el selector lleva `tr.` para ganarle
   por especificidad a la regla de `.tabla-cards tr` en móvil. */
tr.imp-fila-dup { background: rgba(234, 179, 8, 0.18); box-shadow: inset 3px 0 0 var(--warning); }
tr.imp-fila-rev { background: rgba(234, 179, 8, 0.09); }
tr.imp-fila-omitida { opacity: .5; }
.imp-al-dup, .imp-al-rev { color: var(--warning); }

/* Tabla de movimientos: Concepto se queda con el espacio libre (sin la
   columna Observaciones) y el resto de las columnas no parte línea. Solo en
   desktop: bajo 640px la fila ya es una tarjeta y un min-width la rompería. */
@media (min-width: 641px) {
  .tabla-movs .col-concepto { min-width: 20rem; }
  .tabla-movs .nw { white-space: nowrap; }
}
/* Pantalla de datos densa (9 columnas): con el contenedor de 1200px la tabla
   desbordaba a 1280px de viewport y Editar/Eliminar quedaban fuera de vista. */
.page-ancha { max-width: 1440px; }
.tabla-movs abbr[title] { text-decoration: none; cursor: help; }
/* Íconos de acción de fila a 36px con mouse — mismo criterio que .btn-sm: con
   puntero fino alcanza, y en táctil o bajo 640px vuelven al mínimo de 44px.
   Cuatro íconos de 44px ocupaban 212px de la tabla. */
@media (min-width: 641px) and (pointer: fine) {
  .tabla-movs .btn-icon, .tabla-movs .btn-icon-hueco { min-width: 36px; min-height: 36px; }
  .tabla-movs .btn-icon { padding: .35rem; }
}
.celda-vacia { text-align: center; color: var(--text-dim); }
.mov-transferencia { display: flex; align-items: center; gap: .3rem; }
.ico-inline { width: .9rem; height: .9rem; flex-shrink: 0; }
.accion-conciliar { color: var(--success); }
.accion-deshacer  { color: var(--warning); }
/* Hueco del mismo ancho que un .btn-icon para que los íconos de acción queden
   alineados en columna aunque la fila no tenga observación. */
.btn-icon-hueco { display: inline-block; min-width: var(--tap); }

/* Tooltip de la observación: flota sobre el contenido → superficie elevada.
   Vive en <body> (no dentro de .tabla-scroll, que lo recortaría). */
.tooltip-flotante {
  position: fixed; z-index: 1100; max-width: min(320px, calc(100vw - 16px));
  padding: .6rem .8rem; font-size: .875rem; line-height: 1.4;
  color: var(--text); background: var(--bg-elevado);
  border: 1px solid var(--border-strong); box-shadow: var(--sombra-elevada);
  white-space: pre-line; overflow-wrap: anywhere; pointer-events: none;
}

/* Filtro de conciliación: dos checkboxes en la barra de filtros. */
.filtro-check { border: 0; margin: 0; padding: 0; min-width: 0; }
.filtro-check legend {
  padding: 0; margin-bottom: .25rem;
  font-size: .6875rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim);
}
.filtro-check-opciones { display: flex; align-items: center; gap: 1rem; min-height: var(--tap); }
.check-inline {
  display: inline-flex; align-items: center; gap: .4rem; margin: 0;
  font-size: .875rem; color: var(--text); cursor: pointer;
}

/* Vista previa del monto que entra en la cuenta destino (transferencia). */
.trf-preview {
  display: flex; align-items: center; justify-content: flex-end; min-height: var(--tap);
  font-size: 1.125rem; font-weight: 500; color: var(--text);
}

/* --- /bancos: tarjetas de cuenta --- */
.seccion-cuentas { margin-bottom: 2.25rem; }
.cuenta-numero { display: block; margin: -.5rem 0 .875rem; font-size: .8125rem; color: var(--text-muted); }
.cuenta-pie { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; }
.cuenta-pie .label {
  display: block; margin-bottom: .15rem;
  font-size: .75rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim);
}
.saldo-cuenta {
  display: block; font-size: 1.6rem; font-weight: 500; font-variant-numeric: tabular-nums;
  color: var(--card-valor, var(--text));
}
/* Cifra con signo negativo (cuenta sobregirada o préstamo): el rojo manda sobre
   el color de la moneda, y el signo "-" ya lo dice sin depender del color. */
.saldo-cuenta.es-negativo, .stat-card .value.es-negativo { color: var(--danger); }
