/* ============================================================================
   CLAYMORPHISM — FacturaO
   Capa de rediseño visual. Se carga DESPUÉS de base/tailwind/dashboard/modules,
   por lo que sobrescribe sin tocar esos archivos. Revertir = quitar el <link>.

   Estructura:
     1. Tokens (paleta clay + radios + sombras) — tema claro y oscuro
     2. Scrollbar
     3. Primitivas (botones, paneles, KPIs, tabs, inputs, badges, tablas)
     4. Chrome (sidebar, topbar)
     5. Paleta de acentos (categorías/datos)

   Intensidad MEDIDA: arcilla plena en cards/KPIs/botones/nav; contenida en
   tablas e inputs. El morado de marca se conserva.
   ============================================================================ */

/* ============ 1. TOKENS — TEMA CLARO ============ */
:root {
  /* Suelo lavanda-gris de tono medio (que el relieve se lea) + superficies */
  --color-background: #e4deef;
  --color-surface: #f4f1fc;
  --color-surface-container-lowest: #f7f4fd;
  --color-surface-container-low: #efeaf8;
  --color-surface-container: #ebe5f4;
  --color-surface-container-high: #e6e0f1;
  --color-surface-container-highest: #e0d9ec;
  --color-surface-bright: #f8f5fd;
  --color-surface-dim: #d8d1e6;

  /* Radios generosos y graduados */
  --radius-sm: 12px;
  --radius-md: 16px;
  --radius-lg: 22px;
  --radius-xl: 28px;

  /* Ingredientes de sombra (tintados, nunca negros) */
  --clay-dark: 183,173,204;
  --clay-light: 255,255,255;
  --clay-hi-a: .75;
  --clay-sh-a: .5;

  /* ─── SISTEMA DE TALLAS DE INPUT (por tipo de contenido) ───
     Un solo sitio para todas las anchuras de campo. "texto" y "texto-lg"
     son TOPES: crecen hasta ahí y no más. */
  --clay-w-cod:     5.5rem;   /* código / nº corto (3-5 dígitos) */
  --clay-w-num:     7.5rem;   /* número (importes, cantidades, %) */
  --clay-w-date:    10.5rem;  /* fecha */
  --clay-w-select:  13rem;    /* desplegable */
  --clay-w-text:    22rem;    /* texto normal (nombre, población…) — TOPE */
  --clay-w-text-lg: 36rem;    /* texto largo (domicilio, email…) — TOPE */

  /* Escala de radios clay (uso directo) */
  --clay-r-sm: 14px;
  --clay-r-md: 20px;
  --clay-r-lg: 26px;
  --clay-r-xl: 34px;
  --clay-r-pill: 999px;

  /* Sombras clay */
  --clay-raised:
     6px 6px 14px rgba(var(--clay-dark), var(--clay-sh-a)),
    -6px -6px 11px rgba(var(--clay-light), var(--clay-hi-a));
  --clay-raised-sm:
     3px 3px 8px rgba(var(--clay-dark), var(--clay-sh-a)),
    -3px -3px 7px rgba(var(--clay-light), var(--clay-hi-a));
  --clay-raised-hover:
     9px 9px 19px rgba(var(--clay-dark), var(--clay-sh-a)),
    -8px -8px 15px rgba(var(--clay-light), var(--clay-hi-a));
  --clay-inset:
    inset 3px 3px 7px rgba(var(--clay-dark), var(--clay-sh-a)),
    inset -3px -3px 7px rgba(var(--clay-light), var(--clay-hi-a));
  --clay-flat:
     2px 2px 6px rgba(var(--clay-dark), var(--clay-sh-a)),
    -2px -2px 5px rgba(var(--clay-light), var(--clay-hi-a));
  --clay-primary-glow:
     5px 5px 13px rgba(130,49,167,.30),
    -5px -5px 10px rgba(var(--clay-light), .5);

  /* Tokens de sombra que la app ya referencia (estaban indefinidos → planos) */
  --shadow-1: var(--clay-raised);
  --shadow-2: var(--clay-raised-hover);

  --clay-line: rgba(130,49,167,.12);

  /* Acentos (ver bloque 5) */
  --c-amber:#d98a12; --c-amber-bg:rgba(217,138,18,.15);
  --c-green:#2e9e5b; --c-green-bg:rgba(46,158,91,.15);
  --c-blue:#3f6fe3;  --c-blue-bg:rgba(63,111,227,.15);
  --c-teal:#12968a;  --c-teal-bg:rgba(18,150,138,.15);
  --c-pink:#d54a8c;  --c-pink-bg:rgba(213,74,140,.15);

  /* Blobs decorativos del fondo (formas suaves tras las tarjetas) */
  --clay-blob-a: rgba(130,49,167,.16);
  --clay-blob-b: rgba(18,150,138,.13);
  --clay-blob-c: rgba(213,74,140,.13);
  --clay-blob-d: rgba(217,138,18,.10);
}

/* ============ TOKENS — TEMA OSCURO ============ */
/* La app fija data-theme="dark" en <html> (app/functions.php). Definimos aquí
   una paleta oscura completa (antes estaba incompleta). */
:root[data-theme="dark"] {
  --color-background: #1b1826;
  --color-surface: #241f31;
  --color-surface-container-lowest: #201c2c;
  --color-surface-container-low: #232030;
  --color-surface-container: #2a2439;
  --color-surface-container-high: #2f2840;
  --color-surface-container-highest: #362e49;
  --color-surface-bright: #2c2640;
  --color-surface-dim: #16131f;

  --color-on-surface: #ece8f6;
  --color-on-surface-variant: #b6adca;
  --color-on-background: #ece8f6;
  --color-outline: #8f86a6;
  --color-outline-variant: #3c3552;

  --color-primary: #b46fd6;
  --color-primary-container: #9d4ec4;
  --color-on-primary: #ffffff;
  --color-on-primary-fixed-variant: #eab2ff;
  --color-primary-fixed-dim: #6a4780;

  --clay-dark: 9,7,14;
  --clay-light: 255,255,255;
  --clay-hi-a: .05;
  --clay-sh-a: .55;
  --clay-primary-glow:
     5px 5px 14px rgba(0,0,0,.5),
    -5px -5px 11px rgba(var(--clay-light), .05);
  --clay-line: rgba(234,178,255,.14);

  --clay-blob-a: rgba(180,111,214,.17);
  --clay-blob-b: rgba(18,150,138,.13);
  --clay-blob-c: rgba(213,74,140,.12);
  --clay-blob-d: rgba(217,138,18,.09);
}

/* Fallback por preferencia del SO cuando el usuario no ha elegido tema */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-background: #1b1826;
    --color-surface: #241f31;
    --color-surface-container-lowest: #201c2c;
    --color-surface-container-low: #232030;
    --color-surface-container: #2a2439;
    --color-surface-container-high: #2f2840;
    --color-surface-container-highest: #362e49;
    --color-on-surface: #ece8f6;
    --color-on-surface-variant: #b6adca;
    --color-outline: #8f86a6;
    --color-outline-variant: #3c3552;
    --color-primary: #b46fd6;
    --color-primary-container: #9d4ec4;
    --clay-dark: 9,7,14; --clay-light: 255,255,255; --clay-hi-a: .05; --clay-sh-a: .55;
    --clay-primary-glow: 5px 5px 14px rgba(0,0,0,.5), -5px -5px 11px rgba(var(--clay-light), .05);
    --clay-line: rgba(234,178,255,.14);
    --clay-blob-a: rgba(180,111,214,.17);
    --clay-blob-b: rgba(18,150,138,.13);
    --clay-blob-c: rgba(213,74,140,.12);
    --clay-blob-d: rgba(217,138,18,.09);
  }
}

/* Sin anclaje de scroll en el lienzo: al recargar, el navegador restauraba el
   scroll y el anclaje compensaba el crecimiento tardío del contenido
   (textareas auto-alto, fuentes…) sumando desplazamiento — la página
   aparecía cada vez más abajo con cada recarga. */
.dash-canvas { overflow-anchor: none; }

/* El lienzo usa el SUELO (más oscuro) para que las superficies elevadas resalten,
   con blobs radiales suaves para que el fondo no sea un color plano. */
body,
.dash-canvas {
  background:
    radial-gradient(52rem 44rem at 8% -10%, var(--clay-blob-a), transparent 60%),
    radial-gradient(40rem 36rem at 104% 15%, var(--clay-blob-b), transparent 62%),
    radial-gradient(44rem 40rem at 60% 115%, var(--clay-blob-c), transparent 60%),
    radial-gradient(26rem 26rem at 88% 78%, var(--clay-blob-d), transparent 65%),
    radial-gradient(20rem 20rem at 35% 45%, var(--clay-blob-a), transparent 70%),
    radial-gradient(16rem 16rem at -4% 70%, var(--clay-blob-b), transparent 68%),
    var(--color-background);
}

/* ============ 2. SCROLLBAR CLAYMORPHISM ============ */
* { scrollbar-width: thin; scrollbar-color: var(--color-primary) transparent; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  border-radius: var(--clay-r-pill);
  border: 3px solid var(--color-background);
  background: linear-gradient(145deg, var(--color-primary-container), var(--color-primary));
  box-shadow: var(--clay-raised-sm);
}
::-webkit-scrollbar-thumb:hover { filter: brightness(1.08); }
::-webkit-scrollbar-corner { background: transparent; }

/* ============ 3. PRIMITIVAS ============ */

/* Botones */
.btn-primary {
  border-radius: var(--clay-r-md);
  background: linear-gradient(145deg, var(--color-primary-container), var(--color-primary));
  box-shadow: var(--clay-primary-glow);
  transition: box-shadow .15s ease, transform .1s ease, filter .15s ease;
}
.btn-primary:hover { transform: translateY(-1px); opacity: 1; filter: brightness(1.07); box-shadow: var(--clay-raised-hover); }
.btn-primary:active { transform: translateY(1px); box-shadow: var(--clay-inset); }

/* Emitir factura: mismo acabado de arcilla pero en azul, para que no se confunda con
   Guardar (morado) ni con Anular (rojo). Antes iba en rojo por un style en línea. */
.btn-primary.btn-emitir {
  background: linear-gradient(145deg,
    color-mix(in srgb, var(--c-blue) 62%, white),
    var(--c-blue));
  color: #fff;
  box-shadow:
     5px 5px 13px color-mix(in srgb, var(--c-blue) 34%, transparent),
    -5px -5px 10px rgba(var(--clay-light), .5);
}
.btn-primary.btn-emitir:hover { background: linear-gradient(145deg, color-mix(in srgb, var(--c-blue) 62%, white), var(--c-blue)); }

.btn-secondary {
  border-radius: var(--clay-r-md);
  background: var(--color-surface);
  color: var(--color-primary);
  box-shadow: var(--clay-raised-sm);
  transition: box-shadow .15s ease, transform .1s ease;
}
.btn-secondary:hover { transform: translateY(-1px); background: var(--color-surface); box-shadow: var(--clay-raised-hover); }
.btn-secondary:active { transform: translateY(1px); box-shadow: var(--clay-inset); }

.btn-sm { border-radius: var(--clay-r-sm); box-shadow: var(--clay-raised-sm); }
.btn-sm:active { box-shadow: var(--clay-inset); }

/* Paneles / cards — con un velo diagonal de marca que les da vida */
.pre-panel {
  border: none;
  border-radius: var(--clay-r-lg);
  background:
    linear-gradient(160deg, color-mix(in srgb, var(--color-primary) 5%, transparent), transparent 45%),
    var(--color-surface);
  box-shadow: var(--clay-raised);
}
/* El mismo velo en las tarjetas de pestaña de las fichas antiguas */
.cli-tab-panel:has(> .cli-form-grid) {
  background:
    linear-gradient(160deg, color-mix(in srgb, var(--color-primary) 5%, transparent), transparent 45%),
    var(--color-surface);
}

/* KPI cards del dashboard */
.dash-kpi-card { border-radius: var(--clay-r-lg); box-shadow: var(--clay-raised); border: none; }
.dash-kpi-card:hover { box-shadow: var(--clay-raised-hover); }
.dash-kpi-card--default {
  background:
    linear-gradient(160deg, color-mix(in srgb, var(--color-primary) 5%, transparent), transparent 45%),
    var(--color-surface);
  border: none;
  box-shadow: var(--clay-raised);
}
.dash-kpi-card--hero {
  background: linear-gradient(150deg, var(--color-primary-container), var(--color-primary));
  box-shadow: var(--clay-primary-glow);
}
.dash-kpi-card--hero, .dash-kpi-card--hero .dash-kpi-card__value,
.dash-kpi-card--hero .dash-kpi-card__label, .dash-kpi-card--hero .dash-kpi-card__delta,
.dash-kpi-card--hero .hi { color: var(--color-on-primary); }

.dash-table-container { border-radius: var(--clay-r-lg); background: var(--color-surface); box-shadow: var(--clay-raised); border: none; }

/* Tabs → canal hundido con píldoras (como el preview aprobado) */
.cli-tabs {
  display: inline-flex;
  border-bottom: none;
  gap: .3rem;
  padding: .35rem;
  border-radius: var(--clay-r-pill);
  background: var(--color-background);
  box-shadow: var(--clay-inset);
  max-width: 100%;
}
.cli-tab { border-bottom: none; border-radius: var(--clay-r-pill); padding: .55rem 1.1rem; color: var(--color-on-surface-variant); }
.cli-tab:hover { background: var(--color-surface); box-shadow: var(--clay-raised-sm); }
.cli-tab.active { border-bottom-color: transparent; color: var(--color-primary); background: var(--color-surface); box-shadow: var(--clay-raised-sm); }

/* Píldora deslizante (creada por base.js): el fondo de la activa se desliza */
.cli-tabs { position: relative; }
.cli-tab-pill {
  position: absolute;
  left: 0; top: 0;
  border-radius: var(--clay-r-pill);
  background: var(--color-surface);
  box-shadow: var(--clay-raised-sm);
  opacity: 0;
  pointer-events: none;
  transform-origin: center;
  transition:
    left .28s cubic-bezier(.25, 1.2, .35, 1),
    width .28s cubic-bezier(.25, 1.2, .35, 1),
    top .28s ease, height .28s ease,
    transform .18s ease, opacity .15s ease;
}
/* Amago en hover: la píldora se estira hacia la pestaña apuntada y se
   aplasta un pelín, "como que quiere ir"; respuesta rápida, sin rebote */
.cli-tab-pill.is-tease {
  transform: scaleY(.93);
  transition:
    left .18s ease, width .18s ease,
    top .18s ease, height .18s ease,
    transform .18s ease, opacity .15s ease;
}
.cli-tabs.has-pill .cli-tab { position: relative; z-index: 1; }
/* Con píldora, ni la activa ni el hover pintan fondo propio:
   el fondito deslizante ES el hover (sigue al cursor y vuelve a la activa) */
.cli-tabs.has-pill .cli-tab.active,
.cli-tabs.has-pill .cli-tab:hover {
  background: transparent;
  box-shadow: none;
}
.cli-tabs.has-pill .cli-tab:hover { color: var(--color-primary); }

/* Inputs → hueco hundido (arcilla contenida) */
.pre-input,
.pre-form-group input:not([type="checkbox"]):not([type="radio"]),
.pre-form-group select,
.pre-form-group textarea,
.pre-form-grid input:not([type="checkbox"]):not([type="radio"]),
.pre-form-grid select,
.pre-form-grid textarea,
.cli-dialog__content input:not([type="checkbox"]):not([type="radio"]),
.cli-dialog__content select,
.cli-dialog__content textarea {
  border: none;
  border-radius: var(--clay-r-sm);
  box-shadow: var(--clay-inset);
}
.pre-input:hover { border: none; }
.pre-input:focus,
.pre-form-group input:focus,
.pre-form-group select:focus,
.pre-form-group textarea:focus,
.pre-form-grid input:focus,
.pre-form-grid select:focus,
.pre-form-grid textarea:focus,
/* hover = misma animación de anillo que el focus (salvo readonly/disabled) */
.pre-input:hover:not([readonly]):not(:disabled),
.pre-form-group input:hover:not([readonly]):not(:disabled),
.pre-form-group select:hover:not(:disabled),
.pre-form-group textarea:hover:not([readonly]):not(:disabled),
.pre-form-grid input:hover:not([readonly]):not(:disabled),
.pre-form-grid select:hover:not(:disabled),
.pre-form-grid textarea:hover:not([readonly]):not(:disabled) {
  border: none;
  box-shadow: var(--clay-inset), 0 0 0 2px var(--color-primary);
}
/* Textarea que crece con el contenido, sin JS (fallback: atributo rows) */
.pre-form-group textarea, .pre-form-grid textarea, .cli-dialog__content textarea {
  field-sizing: content;
  min-height: 2.7rem;
  max-height: 12rem;
}

/* REFUERZO: la regla universal de modules.css (especificidad ~0,9,1) pisa mi
   border/border-radius, dejando los inputs con un borde de caja de 1px y radio
   8px. Con !important, TODOS los inputs (formulario Y líneas de detalle) quedan
   con el hueco de arcilla completo: sin borde, radio clay, mismo componente. */
.pre-input,
.pre-form-group input:not([type="checkbox"]):not([type="radio"]),
.pre-form-group select, .pre-form-group textarea,
.pre-form-grid input:not([type="checkbox"]):not([type="radio"]),
.pre-form-grid select, .pre-form-grid textarea,
.cli-form-group input:not([type="checkbox"]):not([type="radio"]),
.cli-form-group select, .cli-form-group textarea,
.cli-dialog__content input:not([type="checkbox"]):not([type="radio"]),
.cli-dialog__content select, .cli-dialog__content textarea {
  border: none !important;
  border-radius: var(--clay-r-sm) !important;
  background-color: var(--color-surface-container-lowest) !important;
}
/* Inputs de las líneas de detalle: radio algo menor por la densidad de la tabla
   (pre-lineas-tbody lo comparten presupuesto, pedido y albarán) */
#pre-lineas-tbody .pre-input,
#fac-lineas-tbody .pre-input {
  border-radius: 10px !important;
}
/* Descuentos de línea (D1/D2/D3%): eran demasiado estrechos (49px) y cortaban
   el "0.00". Se les da tamaño de número como Cantidad/Precio/Total. */
#pre-lineas-tbody .pre-input-dto, #pre-lineas-tbody .pre-input-dto2, #pre-lineas-tbody .pre-input-dto3,
#fac-lineas-tbody .pre-input-dto, #fac-lineas-tbody .pre-input-dto2, #fac-lineas-tbody .pre-input-dto3 {
  min-width: 4.5rem;
}

/* Referencia (cabecera): más estrecha para que quepan más campos en la fila
   (p. ej. Transportista en factura). */
.pre-form-group:has(> input[id^="field-REF"]) {
  flex: 0 1 12rem;
  max-width: 12rem;
}

/* Badges de estado → píldora con relieve suave + punto de color (preview) */
.badge-status {
  border-radius: var(--clay-r-pill);
  box-shadow: var(--clay-flat);
  font-weight: 700;
  padding: 0.3rem 0.75rem;
  gap: 0.35rem;
}
.badge-status::before {
  content: "";
  width: .45rem;
  height: .45rem;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}

/* Iconos de KPI → chip de arcilla con degradado del color del icono */
.dash-kpi-card__icon {
  width: 44px;
  height: 44px;
  padding: 10px;
  opacity: 1;
  border-radius: var(--clay-r-sm);
  background: linear-gradient(145deg,
    color-mix(in srgb, currentColor 18%, var(--color-surface)),
    color-mix(in srgb, currentColor 6%, var(--color-surface)));
  box-shadow: var(--clay-flat);
}
.dash-kpi-card--hero .dash-kpi-card__icon {
  background: rgba(255,255,255,.18);
  box-shadow: inset 2px 2px 5px rgba(0,0,0,.15), inset -2px -2px 5px rgba(255,255,255,.15);
}

/* Icono de título de sección → chip de arcilla con degradado suave */
.pre-form-section-title > .hi {
  width: 38px;
  height: 38px;
  padding: 8px;
  flex: 0 0 auto;
  border-radius: 12px;
  color: var(--color-primary);
  background: linear-gradient(145deg,
    color-mix(in srgb, var(--color-primary) 18%, var(--color-surface)),
    color-mix(in srgb, var(--color-primary) 6%, var(--color-surface)));
  box-shadow: var(--clay-flat);
}

/* Tarjeta de totales → arcilla (preview) */
.pre-totales-grid {
  border: none;
  border-radius: var(--clay-r-lg);
  background: var(--color-surface);
  box-shadow: var(--clay-raised);
}

/* TODOS los selects = MISMO componente: apariencia customizable (opciones con
   arcilla) + UNA sola flecha. `background-image:none` mata el triángulo que
   modules.css pinta en .cli-form-group/.cli-filters select (causaba 2 flechas).
   El :not(.no-bg) respeta los que se excluyen a propósito. */
select:not(.no-bg) {
  appearance: base-select;
  background-image: none !important;
  padding-right: 2.2rem;
}
select:not(.no-bg)::picker-icon {
  color: var(--color-on-surface-variant);
  transition: transform .2s ease;
}
select:not(.no-bg):open::picker-icon {
  color: var(--color-primary);
  transform: rotate(180deg);
}

/* Popup de opciones con estilo claymorphism */
::picker(select) {
  appearance: base-select;
  border: none;
  background: var(--color-surface);
  box-shadow: var(--clay-raised);
  border-radius: var(--clay-r-md);
  padding: .35rem;
  margin-top: .4rem;
}
::picker(select) option {
  border-radius: var(--clay-r-sm);
  padding: .5rem .8rem;
  color: var(--color-on-surface);
  transition: background .12s ease;
  cursor: pointer;
}
::picker(select) option:hover,
::picker(select) option:focus {
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  outline: none;
}
::picker(select) option:checked {
  color: var(--color-primary);
  font-weight: 700;
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
}
::picker(select) option::checkmark {
  color: var(--color-primary);
  order: 1;
  margin-left: auto;
}

/* ============ 4. CHROME (sidebar / topbar) ============ */
/* El velo morado (transparente a la izquierda, morado a la derecha) vive en el
   PANEL, no en todo el sidebar: el rail lleva su propio tinte para que la
   lengüeta del departamento abierto tenga con qué contrastar al pegarse.
   El velo arranca transparente justo en la junta, así que ahí el panel es
   exactamente --dash-panel-bg y la lengüeta funde sin costura.
   Base y velo van en la misma propiedad: el gradiente translúcido necesita algo
   debajo que teñir. */
.dash-sidebar {
  background: var(--color-surface-container-lowest);
  border-right: none;
  box-shadow: var(--clay-flat);
}
.dash-panel {
  background:
    linear-gradient(90deg,
      transparent 0%,
      color-mix(in srgb, var(--color-primary) 7%, transparent) 45%,
      color-mix(in srgb, var(--color-primary) 20%, transparent) 100%),
    var(--dash-panel-bg);
}
.dash-nav-link { border-radius: var(--clay-r-sm); }
.dash-nav-link:hover { background: var(--color-surface); box-shadow: var(--clay-raised-sm); }
.dash-nav-link.active {
  background: linear-gradient(145deg, var(--color-primary-container), var(--color-primary));
  color: var(--color-on-primary);
  border-right: none;
  box-shadow: var(--clay-primary-glow);
}
.dash-nav-link.active .hi { color: var(--color-on-primary); }

/* Rail de departamentos. El tinte morado suave lo separa del panel (más claro):
   ese contraste es lo que hace legible que la lengüeta activa se despega del
   rail y se pega al panel. */
:root {
  --dash-rail-bg: color-mix(in srgb, var(--color-primary) 9%, var(--color-surface-container-lowest));
}
.dash-rail { border-right: none; }
.dash-rail__btn:hover { background-color: color-mix(in srgb, var(--color-surface) 70%, transparent); }

/* Departamento abierto: la lengüeta es una prolongación del panel, así que NO
   lleva sombra de arcilla propia — una pieza pegada no proyecta sombra contra
   aquello a lo que está pegada. Solo el icono y el texto se tiñen de morado. */
body:not(.sidebar-collapsed) .dash-rail__btn.active {
  box-shadow: none;
  color: var(--color-primary);
}

/* Contraído no hay panel: el departamento de la página actual vuelve a ser una
   pastilla morada suelta */
/* El borde derecho transparente ya lo separa del borde; no hace falta margen */
body.sidebar-collapsed .dash-rail__btn.aqui {
  background-image: linear-gradient(145deg, var(--color-primary-container), var(--color-primary));
  color: var(--color-on-primary);
  box-shadow: var(--clay-primary-glow);
  border-radius: var(--clay-r-md);
}
.dash-panel { border-right: none; }
.dash-rail__flyout {
  border: none;
  border-radius: var(--clay-r-lg);
  background: var(--color-surface);
  box-shadow: var(--clay-raised);
}

.dash-topbar {
  background: color-mix(in srgb, var(--color-background) 82%, transparent);
  border-bottom: 1px solid var(--clay-line);
}
.dash-topbar__search input {
  border: none;
  border-radius: var(--clay-r-pill);
  background: var(--color-surface-container-lowest);
  box-shadow: var(--clay-inset);
}

/* ============ 5. ACENTOS (categorías / datos) ============ */
/* Disponibles como utilidades para iconos de tarjeta, avatares, etc. */
.clay-ic--amber { background: var(--c-amber-bg); color: var(--c-amber); }
.clay-ic--green { background: var(--c-green-bg); color: var(--c-green); }
.clay-ic--blue  { background: var(--c-blue-bg);  color: var(--c-blue); }
.clay-ic--teal  { background: var(--c-teal-bg);  color: var(--c-teal); }
.clay-ic--pink  { background: var(--c-pink-bg);  color: var(--c-pink); }

/* ============ 6. MODALES / DIÁLOGOS ============ */
.cli-dialog-overlay { background: rgba(20, 10, 32, .45); }
.cli-dialog {
  background: var(--color-surface);
  border-radius: var(--clay-r-xl);
  box-shadow: var(--clay-raised);
}
.cli-dialog__header { border-bottom: 1px solid var(--clay-line); }
.cli-dialog__icon { box-shadow: var(--clay-inset); }
.cli-dialog__btn-danger {
  border-radius: var(--clay-r-md);
  background: linear-gradient(145deg, #d64545, var(--color-error));
  box-shadow: 5px 5px 13px rgba(186,26,26,.30), -5px -5px 10px rgba(var(--clay-light), var(--clay-hi-a));
  transition: box-shadow .15s ease, transform .1s ease, filter .15s ease;
}
.cli-dialog__btn-danger:hover { transform: translateY(-1px); filter: brightness(1.06); background: linear-gradient(145deg, #d64545, var(--color-error)); box-shadow: 7px 7px 16px rgba(186,26,26,.36), -6px -6px 12px rgba(var(--clay-light), var(--clay-hi-a)); }
.cli-dialog__btn-danger:active { transform: translateY(1px); box-shadow: var(--clay-inset); }

/* ============ 7. TOPBAR (botones / perfil / avatar) ============ */
.dash-topbar__icon-btn {
  width: 42px; height: 42px; padding: 0; opacity: 1;
  border-radius: var(--clay-r-md);
  background: var(--color-surface);
  box-shadow: var(--clay-raised-sm);
  display: grid; place-items: center;
  transition: box-shadow .15s ease, transform .1s ease, color .15s ease;
}
.dash-topbar__icon-btn:hover { transform: translateY(-1px); color: var(--color-primary); box-shadow: var(--clay-raised); }
.dash-topbar__icon-btn:active { transform: translateY(1px); box-shadow: var(--clay-inset); }
.dash-topbar__profile {
  border-left: none;
  background: var(--color-surface);
  box-shadow: var(--clay-raised-sm);
  border-radius: var(--clay-r-pill);
  padding: .3rem .45rem .3rem 1rem;
  transition: box-shadow .2s ease, transform .2s ease;
}
/* Es un enlace a "Mi Perfil": se comporta como el resto de piezas de arcilla pulsables */
a.dash-topbar__profile { text-decoration: none; color: inherit; }
a.dash-topbar__profile:hover { transform: translateY(-1px); box-shadow: var(--clay-raised); }
a.dash-topbar__profile:active { transform: translateY(1px); box-shadow: var(--clay-inset); }
a.dash-topbar__profile.active { box-shadow: var(--clay-inset); }
a.dash-topbar__profile:hover .dash-topbar__profile-name { color: var(--color-primary); }
.dash-topbar__avatar {
  border: none;
  background: linear-gradient(145deg, var(--color-primary-container), var(--color-primary));
  box-shadow: var(--clay-primary-glow);
}

/* ============ 8. SIDEBAR (buscador / toggle) ============ */
/* Eclipse: un halo difuso que orbita despacio detrás del buscador.
   - `overflow:hidden` + el radio de píldora lo recortan a la forma del campo: al rotar, un
     rectángulo ancho barre un área del tamaño de su diagonal y el halo invadía el menú.
   - El pseudo es cuadrado (aspect-ratio 1) para que su caja no crezca al girar.
   - `isolation` mantiene el z-index:-1 dentro del buscador; si no, se colaría tras el sidebar.
   El input es semitransparente, así que el halo se translucе como una aurora bajo el cristal. */
.dash-sidebar__search {
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--clay-r-pill);
}

.dash-sidebar__search::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 118%;
  aspect-ratio: 1;
  translate: -50% -50%;
  z-index: -1;
  /* Dos focos opuestos que orbitan el centro. Un conic-gradient no valía: de él solo se ve la
     banda central —donde convergen todos los tonos— y al girar apenas hay movimiento.
     Con focos desplazados, cada uno cruza el campo y se oculta por arriba y abajo: el eclipse. */
  background:
    radial-gradient(circle at 50% 20%, color-mix(in srgb, var(--color-primary) 95%, transparent) 0 4%, transparent 40%),
    radial-gradient(circle at 50% 80%, color-mix(in srgb, var(--c-teal) 85%, transparent) 0 4%, transparent 40%),
    radial-gradient(circle at 18% 50%, color-mix(in srgb, var(--c-pink) 70%, transparent) 0 3%, transparent 34%);
  filter: blur(11px);
  opacity: .55;
  pointer-events: none;
  animation: eclipseOrbita 22s linear infinite;
  transition: opacity .35s ease;
}

/* Al escribir o enfocar, el halo se aviva un poco */
.dash-sidebar__search:focus-within::before,
.dash-sidebar__search.has-text::before {
  opacity: .62;
}

/* `rotate` como propiedad independiente: no pisa el `translate` del centrado */
@keyframes eclipseOrbita {
  to { rotate: 360deg; }
}

/* El input lleva la clase 'no-bg', que lo saca de la regla universal de inputs de
   modules.css (su especificidad (0,9,1) aplastaba a este selector (0,2,0) aunque
   clay cargue después). Por eso aquí ya no hace falta ningún !important. */
.dash-sidebar__search input {
  border: none;
  border-radius: var(--clay-r-pill);
  box-shadow: var(--clay-inset);
  /* Semitransparente para que el eclipse se translucza. */
  background: color-mix(in srgb, var(--color-surface) 62%, transparent);
}

/* El foco se marca por dentro: el buscador recorta a su forma con overflow:hidden
   y el input lo llena entero, así que un anillo por fuera quedaría cortado. */
.dash-sidebar__search input:focus {
  background: color-mix(in srgb, var(--color-surface) 72%, transparent);
  box-shadow: var(--clay-inset), inset 0 0 0 2px var(--color-primary);
}
.dash-sidebar__toggle {
  border: none;
  background: var(--color-surface);
  box-shadow: var(--clay-raised-sm);
}
.dash-sidebar__toggle:hover { box-shadow: var(--clay-raised); }
.dash-sidebar__search-kbd { box-shadow: var(--clay-flat); border-radius: 8px; }

/* ============ 9. TABLAS DE LISTADOS ============ */
.dash-table__client-avatar { border-radius: var(--clay-r-sm); box-shadow: var(--clay-flat); }
.dash-table__more { border-radius: var(--clay-r-sm); }
.dash-table__more:hover { background: var(--color-surface-container); box-shadow: var(--clay-inset); }

/* Paginación */
.cli-pag-btn {
  border: none;
  border-radius: var(--clay-r-sm);
  background: var(--color-surface);
  box-shadow: var(--clay-raised-sm);
  transition: box-shadow .15s ease, transform .1s ease;
}
.cli-pag-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: var(--clay-raised); }
.cli-pag-btn:active:not(:disabled) { box-shadow: var(--clay-inset); }
.cli-pag-btn:disabled { opacity: .5; }

/* ============ 10. TABLAS DE LÍNEAS (documentos) ============ */
.pre-table-container { border: none; border-radius: var(--clay-r-lg); box-shadow: var(--clay-flat); }
.pre-table th { background: var(--color-surface-container-low); }

/* ============ 11. AJUSTES / TARJETAS ENLACE ============ */
.ajuste-card {
  border: none;
  border-radius: var(--clay-r-lg);
  background: var(--color-surface);
  box-shadow: var(--clay-raised);
  transition: box-shadow .15s ease, transform .12s ease;
}
.ajuste-card:hover { transform: translateY(-2px); box-shadow: var(--clay-raised-hover); }

/* ============ 12. TOASTS / NOTIFICACIONES ============ */
#notificacion {
  border: none;
  border-radius: var(--clay-r-md);
  box-shadow: var(--clay-raised);
}

/* ============ 12b. TRANSICIONES ENTRE PÁGINAS ============
   La app ya emitía `@view-transition { navigation: none }` cuando el perfil activa "reducir
   efectos de movimiento", pero nunca llegó a declarar la transición: el ajuste apagaba algo que
   no existía. Aquí se declara; el <style> inline de crear_head() la anula cuando toca.
   Solo navegaciones del mismo origen y solo en navegadores que lo soporten (mejora progresiva). */
@view-transition { navigation: auto; }

@keyframes vtSale { to { opacity: 0; transform: translateY(-8px); } }
@keyframes vtEntra { from { opacity: 0; transform: translateY(10px); } }

::view-transition-old(root) {
  animation: vtSale .18s cubic-bezier(.4, 0, 1, 1) both;
}

::view-transition-new(root) {
  animation: vtEntra .3s cubic-bezier(.22, 1, .36, 1) both;
}

/* El menú y la barra superior no se mueven con la página: se quedan fijos entre navegaciones */
.dash-sidebar { view-transition-name: sidebar; }
.dash-topbar { view-transition-name: topbar; }
::view-transition-group(sidebar),
::view-transition-group(topbar) { animation: none; }
::view-transition-old(sidebar),
::view-transition-new(sidebar),
::view-transition-old(topbar),
::view-transition-new(topbar) { animation: none; mix-blend-mode: normal; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ============ 13. ENTRADA DE PRESENTACIÓN (al cargar página) ============ */
@keyframes clayInUp { 0% { opacity: 0; transform: translateY(16px); } 100% { opacity: 1; transform: none; } }
@keyframes clayPuffIn { 0% { opacity: 0; transform: scale(.9); } 100% { opacity: 1; transform: scale(1); } }
@keyframes clayFadeIn { 0% { opacity: 0; } 100% { opacity: 1; } }
@media (prefers-reduced-motion: no-preference) {
  /* El header anima SOLO opacidad: contiene el FAB fijo de Guardar, y un
     ancestro con transform lo captura (aparecía arriba y saltaba abajo). */
  .dash-page-header { animation: clayFadeIn .5s ease both .05s; }
  .dash-kpi-card { animation: clayPuffIn .5s cubic-bezier(.22,1,.36,1) both; }
  .dash-kpi-card:nth-child(1) { animation-delay: .12s; }
  .dash-kpi-card:nth-child(2) { animation-delay: .20s; }
  .dash-kpi-card:nth-child(3) { animation-delay: .28s; }
  .dash-table-container, .pre-panel { animation: clayInUp .55s ease both .22s; }
  /* Fichas de documento: pestañas y paneles entran también */
  .cli-tabs { animation: clayInUp .5s ease both .08s; }
  .cli-form-section-title { animation: clayFadeIn .5s ease both .3s; }
}
body.clay-anim-done .cli-tabs,
body.clay-anim-done .cli-form-section-title { animation: none; }
/* Tras el arranque (base.js marca el body), estas animaciones NO se
   re-disparan al cambiar de pestaña — evita el efecto "recarga". */
body.clay-anim-done .dash-page-header,
body.clay-anim-done .dash-kpi-card,
body.clay-anim-done .dash-table-container,
body.clay-anim-done .pre-panel { animation: none; }

/* Cambio de panel de pestañas: el contenido se mantiene quieto (sin fundidos
   ni re-entradas — cualquier animación aquí lee como "refresco"); el único
   movimiento es la píldora deslizándose entre pestañas. */
body.clay-anim-done .cli-tab-panel { animation: none; }

/* ============ 15. ICONO DE TEMA (luna en claro / sol en oscuro) ============ */
#btn-tema .ico-sol { display: none; }
:root[data-theme="dark"] #btn-tema .ico-luna { display: none; }
:root[data-theme="dark"] #btn-tema .ico-sol { display: block; }

/* ============ 16. MENÚ MÓVIL (drawer) ============ */
.dash-topbar__hamburger { display: none; }
@media (max-width: 768px) {
  .dash-topbar__hamburger { display: grid; flex: 0 0 auto; }
  /* dashboard.css oculta el sidebar en móvil; lo convertimos en drawer off-canvas */
  .dash-sidebar {
    display: flex;
    position: fixed;
    left: 0; top: 0;
    transform: translateX(-110%);
    transition: transform .25s cubic-bezier(.22,1,.36,1);
    z-index: 80;
    box-shadow: var(--clay-raised);
  }
  body.menu-movil-abierto .dash-sidebar { transform: translateX(0); }
  /* En móvil el drawer siempre abre con rail + panel, aunque el usuario
     tuviera el menú contraído a solo rail en escritorio */
  body.sidebar-collapsed { --dash-panel-w: 13.75rem; }
  body.sidebar-collapsed .dash-panel { display: flex; }
  body.sidebar-collapsed .dash-rail { border-right: 1px solid var(--clay-line); }
  /* Overlay oscuro tras el drawer */
  body.menu-movil-abierto::before {
    content: "";
    position: fixed; inset: 0;
    background: rgba(20, 10, 32, .45);
    z-index: 70;
  }
}
@media (prefers-reduced-motion: reduce) {
  .dash-sidebar { transition: none; }
}

/* ============ 17. LOGIN ============ */
/* El login define <style> propio DESPUÉS de los <link>; usamos html + selector
   para ganar en especificidad sin !important. */
html .login-card {
  border: none;
  border-radius: var(--clay-r-xl);
  background: var(--color-surface);
  box-shadow: var(--clay-raised);
}
html .login-form .form-input {
  border: none;
  border-radius: var(--clay-r-sm);
  background: var(--color-surface-container-lowest);
  box-shadow: var(--clay-inset);
}
html .login-form .form-input:focus {
  box-shadow: var(--clay-inset), 0 0 0 2px var(--color-primary);
}
html .login-card .submit-btn {
  border-radius: var(--clay-r-md);
  background: linear-gradient(145deg, var(--color-primary-container), var(--color-primary));
  box-shadow: var(--clay-primary-glow);
}
html .login-card .submit-btn:hover { transform: translateY(-1px); filter: brightness(1.07); }
html .login-card .submit-btn:active { transform: translateY(1px); box-shadow: var(--clay-inset); }
html .login-card .error-alert {
  border-left: none;
  border-radius: var(--clay-r-md);
  box-shadow: var(--clay-flat);
}

/* ============ 22. BOTÓN GUARDAR FLOTANTE (FAB) ============ */
/* Solo los "Guardar" de página (en el header de las fichas); los de los
   modales no se ven afectados. */
.dash-page-header__actions .btn-primary[id^="btn-guardar-"] {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 90;
  padding: .95rem 1.6rem;
  font-size: .95rem;
  border-radius: var(--clay-r-pill);
  box-shadow:
    6px 6px 16px rgba(130,49,167,.35),
    -4px -4px 12px rgba(var(--clay-light), var(--clay-hi-a)),
    0 8px 28px rgba(0,0,0,.16);
}
.dash-page-header__actions .btn-primary[id^="btn-guardar-"]:hover { transform: translateY(-2px); }
.dash-page-header__actions .btn-primary[id^="btn-guardar-"]:active { transform: translateY(1px); box-shadow: var(--clay-inset); }
/* Hueco al final de la página para que el FAB no tape contenido */
.dash-canvas:has(.dash-page-header__actions .btn-primary[id^="btn-guardar-"]) {
  padding-bottom: 7rem;
}
@media (max-width: 768px) {
  .dash-page-header__actions .btn-primary[id^="btn-guardar-"] { right: 1rem; bottom: 1rem; }
}

/* ============ TARJETA DE TOTALES — STICKY CONSISTENTE ============ */
/* Antes: position:sticky dentro de #panel-lineas → su posición dependía del
   alto de la cabecera/tabla de cada ficha (factura 2 filas vs presupuesto 1),
   por eso no cuadraban. Ahora: fija a una esquina del viewport (MISMA posición
   en factura/presupuesto/pedido/albarán) pero SOLO visible mientras la tabla de
   líneas está a la vista (base.js la muestra/oculta con IntersectionObserver).
   Resultado: se comporta como sticky (pegada abajo, ligada a las líneas) pero
   consistente entre fichas, y ya no tapa las columnas. */
.pre-totales-wrapper {
  position: fixed;
  right: 16rem;          /* a la izquierda del botón Guardar (misma línea) */
  bottom: 1.5rem;        /* alineado abajo con el botón Guardar */
  margin: 0;
  width: auto;
  min-height: 0;
  z-index: 45;
}
/* Sin JS: el total está dentro del panel de la pestaña de líneas; al cambiar de
   pestaña ese panel pasa a display:none y oculta también este elemento fixed.
   Así aparece fijo desde la carga y se oculta solo fuera de las líneas. */
.pre-totales-grid { width: 300px; }
/* El total es position:fixed. Cualquier ancestro con `transform` lo posiciona
   respecto a ese ancestro en vez del viewport → aparecería en el centro y
   saltaría a la esquina al acabar la animación. Los ancestros que animan con
   transform (el panel de líneas y su tab-panel, con fadeSlideUp) se desactivan
   para que el total salga YA posicionado desde el primer frame. */
/* El panel/tab-panel de líneas NO puede usar transform (rompe el total fixed),
   pero SÍ puede entrar con un fade (opacity) — así anima sin descolocar el total. */
#panel-lineas { animation: none !important; }
.cli-tab-panel:has(.pre-totales-wrapper) {
  transform: none !important;
  animation: clayFadeIn .5s ease both .2s !important;
  /* Colchón inferior: la tarjeta de totales es fixed y sin esto tapa las últimas
     líneas de detalle al llegar al final del scroll (visible sobre todo en
     facturas emitidas, donde el contenido acaba antes) */
  padding-bottom: 9rem;
}
body.clay-anim-done .cli-tab-panel:has(.pre-totales-wrapper) { animation: none !important; }
@media (max-width: 768px) {
  .pre-totales-wrapper { right: 1rem; bottom: 5.5rem; }
  .pre-totales-grid { width: min(300px, calc(100vw - 2rem)); }
}

/* ============ 20. SIN MIGAS DE PAN ============ */
/* La navegación va por el sidebar; las migas sobran en esta app. */
.cli-ficha-breadcrumb { display: none; }

/* ============ 21. INPUTS EN MODO OSCURO ============ */
/* base.css fuerza fondo claro (#fbfbfd) con un selector muy específico, y el
   override oscuro de modules.css está anidado en @media (prefers-color-scheme)
   → solo aplicaba si el SO estaba en oscuro. Aquí manda data-theme. */
:root[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="file"]):not([type="image"]):not([type="reset"]):not(.no-bg),
:root[data-theme="dark"] textarea:not(.no-bg),
:root[data-theme="dark"] select:not(.no-bg) {
  background-color: var(--color-surface-container-lowest);
  color: var(--color-on-surface);
}
:root[data-theme="dark"] input::placeholder,
:root[data-theme="dark"] textarea::placeholder {
  color: var(--color-on-surface-variant);
  opacity: .7;
}

/* ============ 19. CAMPOS CON BUSCADOR EN COLUMNA ============ */
/* Los campos con buscador (Cliente, Forma de Pago, Agente, Almacén,
   Transportista, Banco…) venían como fila (label+lupa y "Cód." en línea),
   gastando ancho. Se pasan a columna como el resto de campos.
   El wrapper lleva estilo inline (align-items/gap), de ahí los !important. */
/* Generalizado: CUALQUIER envoltorio fila (label + input en línea) dentro de
   un grupo pasa a columna — buscadores, Tarifa, Tipo de Cliente, etc. */
.pre-form-group > div:has(> label):has(> input),
.cli-form-group > div:has(> label):has(> input) {
  display: flex;
  flex-direction: column;
  align-items: stretch !important;
  gap: .25rem !important; /* mismo gap label↔input que .pre-form-group */
}
.pre-form-group > div:has(> label):has(> input) > input,
.cli-form-group > div:has(> label):has(> input) > input {
  width: var(--clay-w-cod) !important;   /* pisa anchos inline (60px…) */
  text-align: left !important;
  padding: .35rem .55rem !important;     /* pisa el padding estrecho inline */
  align-self: flex-start;
}
.pre-form-group > div:has(> label[id^="btn-search-"]) > input,
.cli-form-group > div:has(> label[id^="btn-search-"]) > input {
  width: var(--clay-w-cod) !important;     /* !important: pisa anchos inline (p. ej. 60px en cliente) */
  max-width: var(--clay-w-cod) !important; /* y el tope 4rem de input-narrow-xs (Agente) */
  align-self: flex-start;
  text-align: left !important;
}
/* Estándar de códigos: todas las variantes estrechas al mismo ancho */
.input-narrow, input.input-narrow,
.input-narrow-xs, input.input-narrow-xs {
  width: var(--clay-w-cod);
  max-width: var(--clay-w-cod);
}
/* El grupo se ciñe a su contenido (label o input, el más ancho) en vez de
   reservar el mínimo de --sm (7.5rem) que dejaba huecos vacíos alrededor
   de códigos cortos como el de Agente. */
.pre-form-group:has(> div > label[id^="btn-search-"]) {
  min-width: 0;
  flex: 0 1 auto;
}
/* Ídem para grupos cuyo input es estrecho (Número, códigos, CP…): sin el
   mínimo de 7.5rem desaparece el aire muerto entre campos (p. ej. Número→Fecha). */
.pre-form-group:has(> .input-narrow),
.pre-form-group:has(> .input-narrow-xs) {
  min-width: 0;
  flex: 0 1 auto;
}
/* .hi fuerza 24px pisando el atributo width/height de los SVG, y los iconos
   pequeños de los labels (lupa 14, candado 12…) agrandaban el label y
   descolgaban su input ~4px. Con width/height:auto el SVG recupera el tamaño
   declarado en sus atributos. Aplica a todos los labels de formulario. */
.pre-form-group label[id^="btn-search-"],
.cli-form-group label[id^="btn-search-"] { line-height: 1.5; }
.pre-form-group label .hi,
.cli-form-group label .hi {
  width: auto;
  height: auto;
}

/* ============ 23. FORMULARIOS cli-* IGUALADOS A FACTURAS ============ */
/* Cliente, agente, forma de pago y remesa usan el sistema cli-form-* (grid
   rígido de columnas iguales, tope 64rem). Se convierte al MISMO layout que
   facturas: flex fluido donde cada campo ocupa lo que su contenido pide. */
.cli-form-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  align-items: flex-start;
  max-width: none;
}
/* Mapeo de variantes al comportamiento de pre-form-group */
.cli-form-group { gap: 0.25rem; flex: 1 1 200px; min-width: 0; justify-content: flex-start; }
.cli-form-group--sm  { flex: 0 1 auto; min-width: 7.5rem; max-width: none; }
.cli-form-group--xs  { flex: 0 1 auto; min-width: 5rem;  max-width: none; }
.cli-form-group--xxs { flex: 0 0 auto; max-width: none; }
.cli-form-group--xxs input { width: var(--clay-w-cod); }
.cli-form-group--code { flex: 0 0 auto; max-width: none; }
.cli-form-group--code input { width: 9rem; }
.cli-form-group--lg  { flex: 1 1 320px; }
.cli-form-group--xl  { flex: 1 1 480px; }
.cli-form-group--full { flex: 1 1 100%; }
.cli-form-group label {
  font-size: 0.8125rem;
  text-transform: none;
  letter-spacing: normal;
}
.cli-required { color: var(--color-error); }
.cli-form-group input:not([type="checkbox"]):not([type="radio"]),
.cli-form-group select,
.cli-form-group textarea {
  border: none;
  border-radius: var(--clay-r-sm);
  box-shadow: var(--clay-inset);
}
.cli-form-group input:not([type="checkbox"]):not([type="radio"]):focus,
.cli-form-group select:focus,
.cli-form-group textarea:focus,
.cli-form-group input:not([type="checkbox"]):not([type="radio"]):hover:not([readonly]):not(:disabled),
.cli-form-group select:hover:not(:disabled),
.cli-form-group textarea:hover:not([readonly]):not(:disabled) {
  border: none;
  box-shadow: var(--clay-inset), 0 0 0 2px var(--color-primary);
}
.cli-form-group textarea {
  field-sizing: content;
  min-height: 2.7rem;
  max-height: 12rem;
}

/* Panel de arcilla: en cliente (y fichas antiguas) el contenido cuelga
   directamente del panel de pestaña, sin la tarjeta que facturas monta con
   .pre-panel. Se la damos al panel que contenga una rejilla cli- directa
   (los de facturas contienen .pre-panel, no rejillas → no les afecta). */
.cli-tab-panel:has(> .cli-form-grid) {
  background: var(--color-surface);
  border-radius: var(--clay-r-lg);
  box-shadow: var(--clay-raised);
  padding: 1.5rem;
}

/* Fila de Dirección SIEMPRE en una línea con repartos propios:
   Domicilio crece sin imponer los 480px de --xl (que expulsaba al resto),
   CP fijo corto, Población/Provincia medianos y País compacto. */
.cli-form-grid--dir { flex-wrap: nowrap; }
.cli-form-grid--dir > .cli-form-group { min-width: 0; } /* pueden encoger */
.cli-form-grid--dir > .cli-form-group--xl { flex: 2.2 1 10rem; }   /* Domicilio */
.cli-form-grid--dir > .cli-form-group--xs { flex: 0 0 6.5rem; }    /* Código Postal */
.cli-form-grid--dir > .cli-form-group:nth-child(n+3) { flex: 1 1 7rem; } /* Población / Provincia */
.cli-form-grid--dir > .cli-form-group:last-child { flex: .7 1 6rem; }    /* País */
@media (max-width: 900px) {
  .cli-form-grid--dir { flex-wrap: wrap; } /* en móvil sí puede envolver */
}

/* Rejillas --inline (descuentos, IVA…): etiqueta ENCIMA del input, como en
   facturas (el CSS antiguo las ponía en fila etiqueta|input). */
.cli-form-grid--inline .cli-form-group {
  flex-direction: column;
  align-items: flex-start;
  gap: .25rem;
}
.cli-form-grid--inline .cli-form-group input,
.cli-form-grid--inline .cli-form-group select {
  width: var(--clay-w-cod);
  text-align: left;
  padding: .35rem .55rem; /* padding estándar (el inline lo estrechaba) */
}

/* Fila C.C.C. (Entidad · Oficina · DC · Nº de Cuenta): tallas propias con
   separación normal (antes DC tenía un max-width inline que apretaba). */
.cli-form-grid--ccc > .cli-form-group { flex: 0 0 auto; }
.cli-form-grid--ccc .cli-form-group--cuenta { flex: 0 1 auto; }
.cli-form-grid--ccc .cli-form-group--cuenta > input { width: var(--clay-w-num) !important; max-width: var(--clay-w-num) !important; }

/* Datos bancarios: Banco e IBAN ajustados a su contenido real (llevan --lg,
   que es la talla grande de 36rem — demasiado para un nombre de banco o IBAN). */
.cli-form-group:has(> #field-BANCLI) { flex: 0 1 15rem; max-width: 15rem; }
.cli-form-group:has(> #field-IBACLI) { flex: 0 1 17rem; max-width: 17rem; }

/* Desplegables de cliente IDÉNTICOS a los de facturas (refuerzo explícito:
   modules.css define .cli-form-group select con triángulo gris y borde
   antiguos; esta regla, más específica, los iguala al pre-*). */
.cli-tab-panel .cli-form-group select,
.cli-form-grid .cli-form-group select {
  appearance: base-select;
  border: none;
  border-radius: var(--clay-r-sm);
  background-color: var(--color-surface-container-lowest);
  box-shadow: var(--clay-inset);
  padding: .5rem 2.2rem .5rem .7rem;
  cursor: pointer;
}
.cli-tab-panel .cli-form-group select:hover,
.cli-tab-panel .cli-form-group select:focus {
  border: none;
  box-shadow: var(--clay-inset), 0 0 0 2px var(--color-primary);
}

/* ── Componentes antiguos del sistema cli-* ── */

/* Sub-pestañas (Direcciones/Contactos/…) → canal hundido con píldoras */
.cli-subtabs {
  background: var(--color-background);
  border-radius: var(--clay-r-pill);
  padding: .35rem;
  box-shadow: var(--clay-inset);
}
.cli-subtab { border-radius: var(--clay-r-pill); }
.cli-subtab.active { background: var(--color-surface); box-shadow: var(--clay-raised-sm); }

/* Tarjetas de sublistas (direcciones, contactos, recurrentes…) */
.cli-sublist-card {
  border: none;
  border-radius: var(--clay-r-md);
  box-shadow: var(--clay-raised-sm);
}
.cli-sublist-card:hover { border: none; box-shadow: var(--clay-raised); }

/* Formulario inline de alta rápida (mantiene el punteado de "zona editable") */
.cli-inline-form { border-radius: var(--clay-r-md); }

/* Chips de estadísticas */
.cli-stat-chip { background: var(--color-surface); box-shadow: var(--clay-flat); }

/* Botones de icono (imprimir, editar, eliminar en tarjetas…) */
.btn-icon {
  border: none;
  border-radius: var(--clay-r-sm);
  background: var(--color-surface);
  box-shadow: var(--clay-raised-sm);
  transition: box-shadow .15s ease, transform .1s ease, color .15s ease;
}
.btn-icon:hover {
  border: none;
  background: var(--color-surface);
  transform: translateY(-1px);
  box-shadow: var(--clay-raised);
}
.btn-icon:active { transform: translateY(1px); box-shadow: var(--clay-inset); }

/* Estado vacío ("no hay direcciones…") → hueco hundido */
.cli-empty-state-inline {
  border-radius: var(--clay-r-md);
  background: var(--color-background);
  box-shadow: var(--clay-inset);
}

/* Buscador de filtros de las sublistas */
.cli-filters__search input {
  border: none;
  border-radius: var(--clay-r-pill);
  box-shadow: var(--clay-inset);
}
.cli-filters__search input:focus {
  box-shadow: var(--clay-inset), 0 0 0 2px var(--color-primary);
}

/* Títulos de sección de cliente igualados a los de facturas
   (tamaño 1.125rem, color primario, icono en chip de arcilla) */
.cli-form-section-title {
  font-size: 1.125rem;
  gap: 0.5rem;
  color: var(--color-primary);
}
.cli-form-section-title .hi {
  width: 38px;
  height: 38px;
  padding: 8px;
  flex: 0 0 auto;
  border-radius: 12px;
  color: var(--color-primary);
  background: linear-gradient(145deg,
    color-mix(in srgb, var(--color-primary) 18%, var(--color-surface)),
    color-mix(in srgb, var(--color-primary) 6%, var(--color-surface)));
  box-shadow: var(--clay-flat);
}
/* Alineación por ARRIBA en las rejillas de formulario: todos los labels a la
   misma altura y los inputs alineados. Los grupos con líneas extra debajo
   (nombre del cliente, "Personalizar") cuelgan sin desalinear a los vecinos.
   (Antes: align-items center → el grupo más alto descentraba su input.) */
.pre-form-grid { align-items: flex-start; }
.pre-form-group { justify-content: flex-start; }

/* ============ 25. SISTEMA DE TALLAS DE INPUT (por tipo) ============ */
/* Regla: cada GRUPO se dimensiona según el TIPO de su campo, con topes fijos.
   El input llena su grupo (width:100%) salvo los códigos, que van a ancho fijo.
   Orden de la cascada (de genérico a específico): texto → select/fecha/número
   → código. Los más específicos ganan. */

/* 1) Base: TEXTO. Crece hasta el tope --clay-w-text y NO más. */
.pre-form-group,
.cli-form-group { flex: 1 1 var(--clay-w-text); max-width: var(--clay-w-text); min-width: 0; }
/* Texto largo (variantes grandes) → tope mayor; full → ancho completo */
.pre-form-group--lg, .pre-form-group--xl,
.cli-form-group--lg, .cli-form-group--xl { flex: 1 1 var(--clay-w-text-lg); max-width: var(--clay-w-text-lg); }
.pre-form-group--full, .cli-form-group--full { flex: 1 1 100%; max-width: none; }

/* 2) SELECT → se ajusta a su contenido (base-select), entre un mínimo y el
   tope de talla select. "No/Sí" quedan pequeños; opciones largas hasta 13rem. */
.pre-form-group:has(> select),
.cli-form-group:has(> select) { flex: 0 0 auto; max-width: var(--clay-w-select); min-width: 0; }
.pre-form-group:has(> select) > select,
.cli-form-group:has(> select) > select {
  width: auto;
  min-width: 6.5rem;
  max-width: var(--clay-w-select);
}

/* 3) FECHA → talla fecha */
.pre-form-group:has(> input[type="date"]),
.cli-form-group:has(> input[type="date"]) { flex: 0 1 var(--clay-w-date); max-width: var(--clay-w-date); }

/* 4) NÚMERO genérico (importes, cantidades, %) → talla número */
.pre-form-group:has(> input[type="number"]),
.cli-form-group:has(> input[type="number"]) { flex: 0 1 var(--clay-w-num); max-width: var(--clay-w-num); }

/* 5) CÓDIGO (gana sobre número/texto): input a ancho fijo, grupo ceñido.
   Cubre field-COD*, input-narrow y maxlength 1-5. */
.pre-form-group > input[id^="field-COD"],
.cli-form-group > input[id^="field-COD"],
.input-narrow, .input-narrow-xs,
input[maxlength="1"]:not(.no-bg), input[maxlength="2"]:not(.no-bg),
input[maxlength="3"]:not(.no-bg), input[maxlength="4"]:not(.no-bg),
input[maxlength="5"]:not(.no-bg) { width: var(--clay-w-cod) !important; max-width: var(--clay-w-cod) !important; }
.pre-form-group:has(> input[id^="field-COD"]),
.cli-form-group:has(> input[id^="field-COD"]),
.pre-form-group:has(> .input-narrow), .pre-form-group:has(> .input-narrow-xs),
.cli-form-group:has(> .input-narrow), .cli-form-group:has(> .input-narrow-xs),
.pre-form-group:has(> input[maxlength="1"]), .pre-form-group:has(> input[maxlength="2"]),
.pre-form-group:has(> input[maxlength="3"]), .pre-form-group:has(> input[maxlength="4"]),
.pre-form-group:has(> input[maxlength="5"]),
.cli-form-group:has(> input[maxlength="1"]), .cli-form-group:has(> input[maxlength="2"]),
.cli-form-group:has(> input[maxlength="3"]), .cli-form-group:has(> input[maxlength="4"]),
.cli-form-group:has(> input[maxlength="5"]) { flex: 0 0 auto; max-width: none; }

/* ============ 13a. TOGGLE DEL RESUMEN (KPIs) ============
   Botón que acompaña al subtítulo de la página; pieza pequeña de arcilla. */
.dash-resumen-toggle {
  border: none;
  background: var(--color-surface);
  box-shadow: var(--clay-flat);
  border-radius: var(--clay-r-pill);
  padding: .3rem .8rem;
  transition: box-shadow .18s ease, color .18s ease;
}

.dash-resumen-toggle:hover {
  background: var(--color-surface);
  border-color: transparent;
  box-shadow: var(--clay-raised-sm);
  color: var(--color-primary);
}

.dash-resumen-toggle:active { box-shadow: var(--clay-inset); }
.dash-resumen-toggle[aria-expanded="false"] { box-shadow: var(--clay-inset); color: var(--color-primary); }

/* ============ 13b. OPCIONES DE PANTALLA ============
   Panel desplegable de los listados. La lengüeta cuelga del panel como una pieza continua
   (sin hueco entre ambos) y al abrirse queda hundida para leerse como la misma arcilla.
   Los chips se ajustan a su texto: con ~20 columnas una rejilla de celdas fijas dejaba
   demasiado aire muerto. */
.cli-screen-options-panel {
  background: var(--color-surface);
  border: none;
  /* Esquina inferior derecha recta: de ahí cuelga la lengüeta */
  border-radius: var(--clay-r-lg) var(--clay-r-lg) 0 var(--clay-r-lg);
  box-shadow: var(--clay-raised);
  padding: 0 1.5rem;
}

/* La altura la calcula screen-options.js (scrollHeight); aquí solo el ritmo de la animación.
   Salida rápida y entrada con rebote suave: `all .4s` animaba también sombras y colores,
   y hacía el cierre pastoso. */
.cli-screen-options-panel {
  transition:
    max-height .32s cubic-bezier(.4, 0, .2, 1),
    padding .32s cubic-bezier(.4, 0, .2, 1),
    opacity .22s ease;
  will-change: max-height;
}

.cli-screen-options-panel.open {
  padding: 1.5rem;
  /* El hueco que despegaba la lengüeta del panel (modules.css la separaba 1.5rem) */
  margin-bottom: 0;
  transition:
    max-height .4s cubic-bezier(.22, 1, .36, 1),
    padding .4s cubic-bezier(.22, 1, .36, 1),
    opacity .28s ease;
}

/* Los chips entran escalonados al abrir; al cerrar se van con el panel sin animación propia */
@media (prefers-reduced-motion: no-preference) {
  .cli-screen-options-panel.open .cli-screen-options-cols label {
    animation: clayPuffIn .32s cubic-bezier(.22, 1, .36, 1) both;
  }
  .cli-screen-options-panel.open .cli-screen-options-cols label:nth-child(n+6) { animation-delay: .04s; }
  .cli-screen-options-panel.open .cli-screen-options-cols label:nth-child(n+12) { animation-delay: .08s; }
  .cli-screen-options-panel.open .cli-screen-options-group:nth-child(2) { animation: clayFadeIn .4s ease both .1s; }
}

/* Las columnas mandan; la paginación solo ocupa lo que necesita */
.cli-screen-options-content {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1.5rem 2.5rem;
  align-items: start;
}

.cli-screen-options-group { min-width: 0; }

.cli-screen-options-group h5 {
  display: flex;
  align-items: center;
  gap: .75rem;
  color: var(--color-on-surface-variant);
  letter-spacing: .09em;
  font-size: .6875rem;
  margin-bottom: .85rem;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--clay-line);
}

/* Atajos "Todas / Ninguna" (los inyecta screen-options.js) */
.cli-screen-options-acciones {
  display: inline-flex;
  gap: .35rem;
  margin-left: auto;
}

.cli-screen-options-acciones button {
  border: none;
  background: transparent;
  padding: .1rem .45rem;
  border-radius: var(--clay-r-pill);
  color: var(--color-primary);
  font-family: 'Inter', sans-serif;
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .15s ease, box-shadow .15s ease;
}

.cli-screen-options-acciones button:hover {
  background: var(--color-surface-container-low);
  box-shadow: var(--clay-flat);
}

/* Chips que se ajustan a su texto, no celdas de ancho fijo */
.cli-screen-options-cols {
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
}

/* Cada opción es un chip de arcilla; marcado, se hunde y toma el morado de marca */
.cli-screen-options-cols label {
  background: var(--color-surface-container-low);
  border-radius: var(--clay-r-pill);
  box-shadow: var(--clay-flat);
  padding: .35rem .8rem .35rem .5rem;
  gap: .45rem;
  font-size: .8125rem;
  line-height: 1.3;
  white-space: nowrap;
  transition: box-shadow .18s ease, color .18s ease, background .18s ease;
  user-select: none;
}

.cli-screen-options-cols label:hover {
  box-shadow: var(--clay-raised-sm);
  color: var(--color-on-surface);
}

.cli-screen-options-cols label:has(> input:checked) {
  background: color-mix(in srgb, var(--color-primary) 10%, var(--color-surface-container-low));
  box-shadow: var(--clay-inset);
  color: var(--color-primary);
  font-weight: 600;
}

/* Casilla propia: un disco de arcilla con el check dibujado en ::after */
.cli-screen-options-cols input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 1.05rem;
  height: 1.05rem;
  margin: 0;
  border: none;
  border-radius: 7px;
  background: var(--color-surface);
  box-shadow: var(--clay-flat);
  cursor: pointer;
  position: relative;
  transition: background .18s ease, box-shadow .18s ease;
}

.cli-screen-options-cols input[type="checkbox"]:checked {
  background: linear-gradient(145deg, var(--color-primary-container), var(--color-primary));
  box-shadow: var(--clay-primary-glow);
}

.cli-screen-options-cols input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: .3rem;
  height: .55rem;
  border: solid var(--color-on-primary);
  border-width: 0 2px 2px 0;
  transform: translate(-50%, -50%) rotate(45deg);
}

.cli-screen-options-cols input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Selector de paginación: hueco excavado, coherente con los inputs clay */
.cli-screen-options-pag label { gap: .6rem; font-size: .8125rem; }

.cli-input-sm {
  border: none !important;
  border-radius: var(--clay-r-sm);
  background: var(--color-surface-container-low);
  box-shadow: var(--clay-inset);
  color: var(--color-on-surface);
  padding: .4rem .7rem !important;
  font-family: 'Inter', sans-serif;
  outline: none;
}

/* Lengüeta: cuelga del panel, sin separación ni desalineación con su borde derecho */
.cli-screen-options-tab-container {
  margin-right: 0;
  justify-content: flex-end;
}

.cli-screen-options-tab {
  background: var(--color-surface);
  border: none;
  border-radius: 0 0 var(--clay-r-md) var(--clay-r-md);
  box-shadow: var(--clay-raised-sm);
  padding: .45rem 1rem;
  font-weight: 600;
  transition: box-shadow .2s ease, color .2s ease, background .2s ease;
}

.cli-screen-options-tab:hover {
  background: var(--color-surface);
  box-shadow: var(--clay-raised-hover);
  color: var(--color-primary);
}

/* Abierta: se solapa hacia arriba para tapar la sombra que el panel proyecta sobre ella;
   si no, esa franja oscura se lee como un hueco aunque estén pegados (hueco real = 0).
   La sombra propia se limita a los lados y abajo para no re-dibujar esa línea. */
.cli-screen-options-tab.open,
.cli-screen-options-tab.open:hover {
  margin-top: -10px;
  padding-top: calc(.45rem + 10px);
  border-top-color: transparent;
  border-radius: 0 0 var(--clay-r-md) var(--clay-r-md);
  box-shadow:
     4px 6px 10px -2px rgba(var(--clay-dark), var(--clay-sh-a)),
    -4px 2px 8px -2px rgba(var(--clay-light), var(--clay-hi-a));
  color: var(--color-primary);
  z-index: 3;
}

/* La lengüeta cerrada se redondea entera: no cuelga de nada */
.cli-screen-options-tab:not(.open) {
  border-radius: var(--clay-r-md);
}

/* ============ 14. RESPONSIVE / MÓVIL ============ */
@media (max-width: 768px) {
  /* Los flex-items no pueden encoger por debajo de su contenido (min-width:auto):
     los botones del page-header forzaban ~460px y cortaban toda la página. */
  .dash-main, .dash-canvas { min-width: 0; }
  .dash-page-header__actions { flex-wrap: wrap; }
  .dash-page-header h2 { font-size: 1.4rem; }
  .dash-canvas { padding: 1.25rem 1rem 2rem; }
  .dash-topbar { gap: .5rem; padding: 0 .75rem; }
  .dash-topbar__search { width: auto; flex: 1 1 auto; min-width: 0; }
  .cli-screen-options-cols { grid-template-columns: 1fr; }
  .cli-screen-options-panel.open { padding: 1.25rem 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ============ Ilustraciones del menú lateral (Favoritos / Búsqueda) ============
   Últimas hijas de .dash-panel, FUERA del scroll de #sidebar-nav: dentro del
   scroll no pueden pegarse al borde real del panel. Cada una se ve solo cuando
   su sección está a la vista. */
.dash-fav-ilustracion, .dash-buscar-ilustracion { display: none; }
.dash-panel:has(.dash-panel__section[data-dept="dept-busqueda"]:not([hidden])) > .dash-buscar-ilustracion,
.dash-panel:has(.dash-panel__section[data-dept="dept-favoritos"]:not([hidden])) > .dash-fav-ilustracion {
  display: block;
  flex: 0 0 auto;
  /* Ancho completo del panel, de borde a borde: el ancho suma los dos paddings
     laterales (0.75rem) que los márgenes negativos se comen.
     max-width:none anula el img{max-width:100%} del reset de tailwind.css,
     que capaba el calc() y dejaba aire a los lados. */
  width: calc(100% + 1.5rem);
  max-width: none;
  margin: 0 -0.75rem -1rem;
  padding-top: 0.5rem;
  pointer-events: none;
  user-select: none;
  /* El PNG trae margen transparente alrededor del dibujo: se escala desde la base
     para que el DIBUJO (no el fichero) llegue a los bordes. El sobrante lo recorta
     el overflow:hidden del panel. */
  transform-origin: bottom center;
}
/* Escala calculada para que el DIBUJO (los PNG traen aire transparente distinto
   cada uno) quede al ancho interior del panel, con el mismo margen a ambos lados */
.dash-fav-ilustracion { transform: scale(0.98); }
.dash-buscar-ilustracion { transform: scale(0.82); }

/* ============ MODO OSCURO: readonly y focus de inputs ============
   modules.css fija fondos CLAROS a pelo (#f3f3f6 !important en readonly, #ffffff
   en focus) y sus overrides oscuros viven dentro de @media (prefers-color-scheme),
   así que con el tema oscuro elegido a mano sobre un SO claro no se aplicaban:
   el Total de cada línea (readonly) y cualquier campo enfocado salían blancos. */
:root[data-theme="dark"] input[readonly]:not(.no-bg),
:root[data-theme="dark"] textarea[readonly]:not(.no-bg) {
  background-color: rgba(255, 255, 255, 0.06) !important;
  color: var(--color-on-surface);
}
:root[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not(.no-bg):focus,
:root[data-theme="dark"] textarea:not(.no-bg):focus,
:root[data-theme="dark"] select:not(.no-bg):focus {
  background-color: rgba(255, 255, 255, 0.08);
}
/* Mismo arreglo cuando el oscuro viene del SO (sin tema elegido a mano) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) input[readonly]:not(.no-bg),
  :root:not([data-theme="light"]) textarea[readonly]:not(.no-bg) {
    background-color: rgba(255, 255, 255, 0.06) !important;
    color: var(--color-on-surface);
  }
  :root:not([data-theme="light"]) input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not(.no-bg):focus,
  :root:not([data-theme="light"]) textarea:not(.no-bg):focus,
  :root:not([data-theme="light"]) select:not(.no-bg):focus {
    background-color: rgba(255, 255, 255, 0.08);
  }
}
