/* Design system — tema "Azul Documento", elegido por el cliente
   (2026-08-07). El azul es el mismo #1A3A5C que ya llevan las facturas
   impresas: la pantalla y el papel que emite se leen como el mismo objeto.

   Espejo exacto de COLORS en gui/components.py. Si cambia uno, cambian los
   dos: test_web_static_assets.py compara clave por clave.

   Los grises llevan una leve inclinación azul a propósito — un gris neutro
   puro junto a este azul se ve sucio.

   El color semántico (ok / aviso / error) es independiente del acento: son
   dos lenguajes distintos y mezclarlos hace que un estado deje de avisar. */

:root {
  --bg: #ffffff;
  --bg-surface: #f4f7fa;
  --bg-overlay: #e6eef6;
  --bg-muted: #eef3f8;
  --border: #dbe3ec;
  --border-strong: #c9d6e3;
  --border-focus: #1a3a5c;
  --fg: #16202b;
  --fg-muted: #5c6b7a;
  --fg-subtle: #8b9aa8;

  --accent: #1a3a5c;
  --accent-deep: #16304d;
  --accent-fg: #ffffff;
  --accent-wash: #e6eef6;

  /* La barra lateral es oscura en este tema: separa la navegación del área
     de trabajo de un vistazo. Lleva tokens propios porque no puede colgar
     de --bg-surface, que aquí es un azul casi blanco. */
  --side-bg: #1f4368;
  --side-fg: #cfdeed;
  --side-muted: #8fadc9;
  --side-rule: #2b5480;
  --side-active-bg: #16304d;
  --side-active-fg: #ffffff;

  /* Encabezado de tabla en azul sólido, como el de la factura impresa. */
  --th-bg: #1a3a5c;
  --th-fg: #dce7f2;
  --zebra: #f8fafc;

  --success: #1c5e35;
  --success-bg: #dbeade;
  --warning: #7a5410;
  --warning-bg: #fbf0da;
  --error: #8d241f;
  --error-bg: #f9dcda;
  --info: #1a5c86;
  --info-bg: #e2eef5;

  --btn-primary-bg: #1a3a5c;
  --btn-primary-fg: #ffffff;
  --btn-secondary-bg: #ffffff;
  --btn-secondary-fg: #22303f;
  --btn-danger-bg: #f9dcda;
  --btn-danger-fg: #8d241f;
  --btn-confirm-bg: #1a3a5c;
  --btn-confirm-fg: #ffffff;
  --btn-save-bg: #ffffff;
  --btn-save-fg: #22303f;
  --row-selected: #e6eef6;
  --font-stack: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono-stack: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

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

a { color: var(--info); }

h1, h2, h3 { font-weight: 600; margin: 0 0 12px; }
h1 { font-size: 22px; }
h2 { font-size: 17px; margin-top: 24px; }

/* ---------- Layout shell ---------- */

.app-shell {
  min-height: 100vh;
  background: var(--bg);
}

.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 56px;
  background: var(--accent-deep);
  color: var(--accent-fg);
  border-bottom: 1px solid var(--accent-deep);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  z-index: 10;
}

.topbar__brand { font-weight: 650; color: var(--accent-fg); }
.topbar__user {
  color: rgba(255, 255, 255, .82);
  font-size: 14px; display: flex; align-items: center; gap: 12px;
}
/* Los botones de la barra superior van sobre verde, así que no pueden usar
   los tokens neutros de .btn-ghost — quedarían texto gris sobre verde. */
.topbar .btn-ghost { color: rgba(255, 255, 255, .82); }
.topbar .btn-ghost:hover { color: #ffffff; filter: none; }

.sidebar {
  display: none;
  position: fixed;
  top: 56px; left: 0; bottom: 0;
  width: 180px;
  background: var(--side-bg);
  color: var(--side-fg);
  border-right: 1px solid var(--side-bg);
  padding: 16px 0;
  flex-direction: column;
  gap: 2px;
}

.has-sidebar .sidebar {
  display: flex;
}

.sidebar__company {
  padding: 0 16px 12px;
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--side-muted);
  border-bottom: 1px solid var(--side-rule);
  margin-bottom: 8px;
}

.sidebar a {
  padding: 10px 16px;
  color: var(--side-fg);
  text-decoration: none;
  border-left: 3px solid transparent;
}

.sidebar a:hover {
  background: var(--side-active-bg);
  color: var(--side-active-fg);
}

/* La página actual se marca con la barra de acento además del fondo: el
   color solo no basta para quien no distingue verde. */
.sidebar a[aria-current="page"] {
  background: var(--side-active-bg);
  border-left-color: #ffffff;
  color: var(--side-active-fg);
  font-weight: 650;
}

/* Sin max-width: la app es sobre todo tablas anchas (historial, artículos de
   una factura), así que en una pantalla grande el ancho sobrante se aprovecha
   en vez de dejar la mitad en blanco. Los formularios traen su propio
   max-width, que es donde un ancho fluido sí perjudicaría la lectura. */
.main-content {
  margin-top: 56px;
  padding: 22px 26px 32px;
  max-width: none;
  min-height: calc(100vh - 56px);
  background: var(--bg);
  /* El desbordamiento se contiene acá y nunca en el body. La barra superior
     y la lateral son `position: fixed`: si la página entera scrollea en
     horizontal, esas dos se quedan quietas mientras el contenido se corre
     debajo, y la barra verde aparece cortada. Con una tabla ancha el que
     scrollea es este contenedor. */
  overflow-x: auto;
}

/* Refuerzo por si algún contenido futuro desborda igual: el cuerpo de la
   página nunca debe scrollear en horizontal. */
body { overflow-x: hidden; }

.has-sidebar .main-content {
  margin-left: 180px;
}

.bottom-nav {
  display: none;
}

/* ---------- Flash messages ---------- */

.flash-messages { list-style: none; margin: 0 0 16px; padding: 0; }
.flash-messages li {
  background: var(--warning-bg);
  color: var(--fg);
  border: 1px solid var(--warning);
  border-radius: 4px;
  padding: 10px 14px;
  margin-bottom: 8px;
}

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

.btn {
  display: inline-block;
  border: none;
  border-radius: 4px;
  padding: 8px 16px;
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
}
.btn-primary   { background: var(--btn-primary-bg);   color: var(--btn-primary-fg); }
.btn-secondary { background: var(--btn-secondary-bg); color: var(--btn-secondary-fg); }
.btn-danger    { background: var(--btn-danger-bg);    color: var(--btn-danger-fg); }
.btn-confirm   { background: var(--btn-confirm-bg);   color: var(--btn-confirm-fg); }
.btn-save      { background: var(--btn-save-bg);      color: var(--btn-save-fg); }
.btn-ghost     { background: transparent; color: var(--fg-muted); }
.btn-secondary, .btn-save { border: 1px solid var(--border-strong); }
.btn-danger { border: 1px solid #efc0be; }
.btn { font-weight: 600; }
.btn:hover { filter: brightness(0.95); }
.btn-primary:hover, .btn-confirm:hover { background: var(--accent-deep); filter: none; }
.btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

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

.form-container {
  max-width: 480px;
}
.form-container label {
  display: block;
  margin: 14px 0 4px;
  font-size: 13px;
  color: var(--fg-muted);
}
.form-container input[type="text"],
.form-container input[type="password"],
.form-container input[type="email"],
.form-container input[type="date"],
.form-container input[type="file"],
.form-container select {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 14px;
  font-family: inherit;
  background: var(--bg);
  color: var(--fg);
}
.form-container .field-hint {
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--fg-subtle);
}
.form-container .field-hint code {
  font-size: 11px;
  background: var(--bg-muted);
  padding: 1px 4px;
  border-radius: 3px;
}
.form-container input:focus, .form-container select:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.form-container .password-field {
  position: relative;
}
.form-container .password-field input {
  padding-right: 40px;
}
.form-container .password-toggle {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 4px 6px;
}
.form-container .checkbox-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0 4px;
}
.form-container .checkbox-row input[type="checkbox"] { width: auto; }

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

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 12px;
}
.items-table {
  table-layout: fixed;
}
.items-table td input {
  width: 100%;
  box-sizing: border-box;
}
.item-name-input {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 14px;
  font-family: inherit;
  background: var(--bg);
  color: var(--fg);
  resize: none;
  overflow: hidden;
  line-height: 1.4;
  min-height: 36px;
}
.item-name-input:focus {
  outline: none;
  border-color: var(--border-focus);
}
th, td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}
/* Sólo los encabezados de COLUMNA llevan el azul sólido. Un `th` suelto
   dentro de tbody es la etiqueta de una fila ("TOTAL A PAGAR", "Importe
   exento"): con el fondo azul quedaba texto azulado sobre azul. */
thead th {
  background: var(--th-bg);
  font-size: 11px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--th-fg);
  font-weight: 700;
  white-space: nowrap;
  border-bottom: 2px solid var(--accent-deep);
}
th {
  background: transparent;
  color: var(--fg);
  font-weight: 600;
}
/* Bandas alternas: en una tabla ancha ayudan a no saltar de fila al recorrer
   una línea con la vista. */
tbody tr:nth-child(even) { background: var(--zebra); }
tr:hover { background: var(--row-selected); }

/* Cifras y números de documento: ancho fijo por dígito para que una columna
   de importes se pueda comparar de un vistazo. */
.num, td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.doc {
  font-family: var(--mono-stack);
  font-size: 13px;
  letter-spacing: -.02em;
  white-space: nowrap;
}
/* Las fechas ISO también se parten por el guion si la columna se estrecha. */
td[data-label="Fecha"] { white-space: nowrap; }
.company-row { cursor: pointer; }
.company-row--active { background: var(--bg-overlay); font-weight: 600; }

/* ---------- Search/filter bars ---------- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-end;
  margin-bottom: 12px;
}
.filter-bar label {
  display: block;
  font-size: 12px;
  color: var(--fg-muted);
  margin-bottom: 4px;
}
.filter-bar input, .filter-bar select {
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-family: inherit;
  font-size: 14px;
}

/* ---------- Responsive: phone ---------- */

@media (max-width: 767px) {
  .has-sidebar .sidebar { display: none; }
  .has-sidebar .main-content { margin-left: 0; }
  .main-content { padding: 12px 12px 76px; }

  .has-sidebar .bottom-nav {
    display: flex;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: 60px;
    background: var(--bg-surface);
    border-top: 1px solid var(--border);
    z-index: 10;
  }
  .bottom-nav a {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    color: var(--fg-muted);
    text-decoration: none;
    gap: 2px;
  }
  .bottom-nav .icon { font-size: 18px; }

  table.responsive-cards thead, .items-table thead { display: none; }
  table.responsive-cards, table.responsive-cards tbody,
  table.responsive-cards tr, table.responsive-cards td,
  .items-table, .items-table tbody, .items-table tr, .items-table td {
    display: block;
    width: 100%;
  }
  table.responsive-cards tr, .items-table tr {
    border: 1px solid var(--border);
    border-radius: 4px;
    margin-bottom: 12px;
    padding: 8px 10px;
  }
  table.responsive-cards td, .items-table td {
    border: none;
    padding: 4px 0;
  }
  table.responsive-cards td[data-label]::before,
  .items-table td[data-label]::before {
    content: attr(data-label) ": ";
    font-weight: 600;
    color: var(--fg-muted);
  }
  .items-table td:last-child {
    padding-top: 8px;
  }
  .items-table td:last-child .remove-row {
    width: 100%;
  }
}

/* ---------- Utilities ----------
   These replace inline style="..." attributes. A CSP nonce does not cover
   inline style ATTRIBUTES (only <style> elements), so the only way to run
   style-src 'self' without 'unsafe-inline' is to have no style= attributes. */

.mt-8  { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }
.mt-20 { margin-top: 20px; }
.mb-12 { margin-bottom: 12px; }
.m-0   { margin: 0; }
.ml-0  { margin-left: 0; }
.d-inline { display: inline; }

.text-warning { color: var(--warning); }

.action-bar {
  margin-top: 16px;
  display: flex;
  gap: 10px;
}

.form-container--wide { max-width: 820px; }

.client-dropdown {
  display: none;
  border: 1px solid var(--border);
  background: var(--bg);
  position: relative;
  z-index: 5;
}
.client-dropdown.is-open { display: block; }

/* Item table column widths (were inline <col style="width:..."> attributes) */
.items-table col.col-desc  { width: 32%; }
.items-table col.col-qty   { width: 11%; }
.items-table col.col-price { width: 15%; }
.items-table col.col-disc  { width: 13%; }
.items-table col.col-isv   { width: 20%; }
.items-table col.col-act   { width: 9%; }
.items-table td select {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-family: inherit;
  font-size: 14px;
  background: var(--bg);
  color: var(--fg);
}

.provisional-number {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 8px 12px;
  font-size: 14px;
  color: var(--fg-muted);
}
.provisional-number strong {
  font-family: 'Courier New', Courier, monospace;
  color: var(--fg);
}
.provisional-number span { color: var(--warning); }

.rate-row { display: flex; gap: 8px; align-items: center; }
.rate-row input { flex: 1; }
.rate-hint { font-size: 12px; color: var(--fg-muted); margin-top: 4px; }
#rate-source { font-size: 13px; white-space: nowrap; }

/* Vista de factura: nota de moneda y panel de desglose (CSP estricta: sin
   atributos style=, todo el estilo vive aquí). */
.currency-note {
  font-size: 13px;
  color: var(--fg-muted);
  margin: 4px 0 12px;
}
.totals-table { max-width: 420px; }
.totals-table th {
  text-align: left;
  font-weight: 500;
  color: var(--fg-muted);
  background: transparent;
  text-transform: none;
  letter-spacing: normal;
  font-size: inherit;
}
.totals-table td {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.totals-table__grand th,
.totals-table__grand td {
  font-weight: 700;
  color: var(--fg);
  border-top: 2px solid var(--border);
}

/* ---------- Login ---------- */
/* El login es la única pantalla sin contraparte en el escritorio, así que
   lleva tokens propios en vez de colgar de COLORS. Aun así usa el mismo azul
   del tema: es la primera pantalla que se ve y debe anticipar el resto. */

.login-page {
  --login-900: #0b1f33;
  --login-800: #16304d;
  --login-700: #1a3a5c;
  --login-500: #2a5a8c;
  --login-300: #9dc4e8;

  position: fixed;
  inset: 0;
  overflow-y: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  background:
    radial-gradient(ellipse 120% 80% at 50% -10%,
                    var(--login-700) 0%, transparent 60%),
    linear-gradient(160deg, var(--login-800) 0%, var(--login-900) 100%);
}

.is-bare .main-content {
  margin: 0;
  padding: 0;
  max-width: none;
}

/* Flash messages sit outside .login-page (base.html renders them ahead of the
   content block), so they get their own float-over-the-gradient treatment. */
.is-bare .flash-messages {
  position: fixed;
  top: 20px; left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  width: min(420px, calc(100vw - 40px));
  margin: 0;
}
.is-bare .flash-messages li {
  background: #ffffff;
  border: 1px solid var(--error);
  border-left-width: 4px;
  color: var(--fg);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
  margin-bottom: 0;
}

.login-card {
  width: min(440px, 100%);
  background: var(--bg);
  border-radius: 14px;
  padding: 40px 36px 28px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}

.login-head {
  text-align: center;
  padding-bottom: 26px;
  border-bottom: 1px solid var(--border);
}
.login-eyebrow {
  display: block;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--login-500);
  font-weight: 600;
}
.login-title {
  margin: 6px 0 0;
  font-size: clamp(30px, 8vw, 42px);
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--login-800);
}
.login-sub {
  margin: 10px 0 0;
  font-size: 12.5px;
  color: var(--fg-muted);
}

.login-form { margin-top: 24px; }
.login-form label {
  display: block;
  margin: 16px 0 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.login-form input[type="text"],
.login-form input[type="password"] {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: 7px;
  font-size: 15px;
  font-family: inherit;
  background: var(--bg-surface);
  color: var(--fg);
}
.login-form input:focus {
  outline: none;
  background: var(--bg);
  border-color: var(--login-500);
  box-shadow: 0 0 0 3px rgba(42, 90, 140, 0.18);
}
.login-form .password-field { position: relative; }
.login-form .password-field input { padding-right: 42px; }
.login-form .password-toggle {
  position: absolute;
  top: 50%; right: 6px;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  font-size: 15px;
  padding: 6px;
  line-height: 1;
}

.login-submit {
  width: 100%;
  margin-top: 26px;
  padding: 12px 16px;
  border: none;
  border-radius: 7px;
  background: var(--login-700);
  color: #ffffff;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.login-submit:hover { background: var(--login-800); }
.login-submit:focus-visible {
  outline: 3px solid var(--login-300);
  outline-offset: 2px;
}

.login-brands {
  margin-top: 30px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  text-align: center;
}
.login-brands__label {
  display: block;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-subtle);
  margin-bottom: 16px;
}
.login-brands__row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px 22px;
}
.login-brands__row img {
  display: block;
  height: 30px;
  width: auto;
  max-width: 110px;
  object-fit: contain;
  opacity: 0.62;
  filter: grayscale(1);
}
.login-brands__row li:hover img {
  opacity: 1;
  filter: none;
}

@media (max-width: 480px) {
  .login-card { padding: 30px 22px 22px; border-radius: 12px; }
  .login-brands__row { gap: 12px 16px; }
  .login-brands__row img { height: 24px; max-width: 88px; }
}


/* ---------- Estado de la factura ---------- */
/* El estado se codifica en forma además de color (borde y peso propios), para
   que siga leyéndose en una impresión en blanco y negro o por alguien que no
   distingue verde y rojo. El texto va en español; el valor crudo de la
   columna (DRAFT/FINAL/VOID/CANCELLED) es de la base de datos, no del
   usuario. */
.pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid transparent;
}
.pill--final     { background: var(--success-bg); color: var(--success); border-color: #b6dcc7; }
.pill--draft     { background: var(--warning-bg); color: var(--warning); border-color: #ecd8ab; }
.pill--void      { background: var(--error-bg);   color: var(--error);   border-color: #efc0be; }
.pill--cancelled { background: var(--bg-muted);   color: var(--fg-muted); border-color: var(--border-strong); }
