@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

/* Universal, no scoped a #dcs-root: los modales (.dcs-modal-bg) viven como
   hermanos de #dcs-root, no como hijos -- si esto quedara scoped a
   "#dcs-root *", los inputs/selects dentro de un modal caerían en
   content-box (default del navegador) y su padding/border se sumaría por
   fuera del ancho de la celda del grid, invadiendo la columna vecina (bug
   real encontrado probando en navegador: -12px de overlap medido con
   getBoundingClientRect entre "Precio lista" y "Precio contado"). */
*, *::before, *::after { box-sizing: border-box; }

/* Variables en :root (no en #dcs-root): los modales (.dcs-modal-bg) viven
   como hermanos de #dcs-root, no como hijos -- si las variables quedaran
   scoped a #dcs-root, todo lo que use var(--qhawa-color-primary) etc. dentro
   de un modal resolvería a nada (ej. un botón "Guardar" con background
   transparente e invisible sobre fondo blanco, bug real encontrado probando
   en navegador). */
:root {
  --bg: #EEF0F3;
  --surface: #FFFFFF;
  --surface-2: #F4F6F8;
  --ink: #16233A;
  --ink-soft: #57677C;
  /* #8D97A6 original daba ~2.95:1 contra --surface (#FFFFFF), por debajo
     de 4.5:1 WCAG AA (QD-03, auditoría de diseño, 2026-08-04) -- oscurecido
     manteniendo el mismo matiz/saturación (mismo método que
     ensureAccessibleContrast en contrast.js: empujar la luminancia HSL
     hacia el extremo que sube el contraste) hasta 4.66:1. Ver test real en
     theme/__tests__/contrast.test.js. */
  --ink-faint: #6a7587;
  --line: #DEE3E7;
  /* --brand/--brand-ink/--brand-soft (fijos, #B8360C/#10192B/#F7E1D6) ya no
     se usan: identidad de marca migrada al motor de paletas dinámicas
     (theme/apply-theme.js) -- ver issue "Motor de Branding: conectar dcs.css".
     --qhawa-color-primary/--qhawa-color-on-primary/--qhawa-color-primary-on-surface
     los fija ese motor en document.documentElement antes de que la SPA
     renderice (bootstrap en index.html); theme.css define el fallback de la
     paleta Marino para cualquier contexto que cargue dcs.css sin ese boot
     (ej. una prueba visual aislada).
     --qhawa-color-primary-soft/--qhawa-color-primary-strong son tintes/sombras
     derivados de primary en tiempo real vía color-mix() -- decorativos
     (fondos suaves, estado hover), no llevan texto encima que dependa de
     ellos para cumplir contraste, así que no requieren pasar por contrast.js. */
  --qhawa-color-primary-soft: color-mix(in srgb, var(--qhawa-color-primary) 16%, white);
  --qhawa-color-primary-strong: color-mix(in srgb, var(--qhawa-color-primary) 82%, black);
  /* --qhawa-color-surface-brand/--qhawa-color-accent-soft (auditoría de
     diseño QD-01, 2026-08-04): de las 3 claves de cada paleta (background,
     primary, accent) la interfaz solo consumía primary -- background y
     accent quedaban definidos en theme.css pero sin ninguna regla que los
     leyera, así que dos tenants con paletas distintas se veían casi
     idénticos salvo la pastilla del menú activo, el número de las cards y
     el logo. Mismo patrón de derivación que primary-soft/-strong, mismo
     criterio de no requerir contrast.js (decorativos, sin texto propio).
     10% (no 16% como primary-soft) es el techo real, no una elección
     arbitraria: --ink-soft (texto real de .dcs-nav button, no decorativo)
     cae por debajo de 4.5:1 WCAG AA contra el resultado a partir de ~11.5%
     de peso en la paleta más oscura (Obsidian, #08090a) -- medido con la
     fórmula de contraste de WCAG contra las 7 paletas reales de palettes.js.
     Por eso el sidebar NO se apoya solo en este tinte de fondo para
     distinguirse por tenant: ver el border-left sólido en .dcs-sidebar,
     que usa --qhawa-color-background directo (sin diluir) y no compite
     con ningún texto, así que no tiene techo de contraste. */
  --qhawa-color-surface-brand: color-mix(in srgb, var(--qhawa-color-background) 10%, var(--surface));
  --qhawa-color-accent-soft: color-mix(in srgb, var(--qhawa-color-accent) 14%, white);
  --amber: #D97706;
  --amber-soft: #FBEAD2;
  --entrada: #2F7D5B;
  --entrada-soft: #E4F3EA;
  --salida: #A6291F;
  --salida-soft: #F8DEDB;
  --danger: #8C1F17;
  /* --danger-soft ya no copia --salida-soft (QD-07, auditoría de diseño,
     2026-08-04): eran el mismo valor literal (#F8DEDB) pese a ser dos
     conceptos distintos (error de sistema/formulario vs. dirección de
     movimiento "salida" de Almacén) -- coincidencia, no una decisión.
     Ahora se deriva de --danger con el mismo patrón color-mix() que ya
     usan --qhawa-color-primary-soft/-accent-soft. */
  --danger-soft: color-mix(in srgb, var(--danger) 16%, white);
  /* Vocabulario de ESTADO DE PROCESO (pendiente/en proceso/cerrada/anulada
     -- QD-07): deliberadamente separado del vocabulario de DIRECCIÓN DE
     FLUJO de Almacén (--entrada/--salida, entrada/salida de stock) y del
     acento --amber (usado para "corrección" de un movimiento). Antes,
     estadoTag() en ordenes-trabajo.view.js pedía prestados esos 3 tokens
     para un concepto ajeno -- "pendiente" y "en proceso" salían con el
     mismo color porque ninguno de los dos era realmente una "corrección".
     4 tonos con hue distinto entre sí a propósito (ámbar=espera,
     azul=en curso, verde=cerrado, gris=anulado), mismo patrón
     color-mix() para las variantes "soft". */
  --estado-pendiente: #B45309;
  --estado-pendiente-soft: color-mix(in srgb, var(--estado-pendiente) 16%, white);
  --estado-proceso: #1D4ED8;
  --estado-proceso-soft: color-mix(in srgb, var(--estado-proceso) 16%, white);
  --estado-cerrada: #15803D;
  --estado-cerrada-soft: color-mix(in srgb, var(--estado-cerrada) 16%, white);
  --estado-anulada: #57677C;
  --estado-anulada-soft: color-mix(in srgb, var(--estado-anulada) 16%, white);
  --radius: 10px;
  /* Escalas de tipografía/radio/espaciado (QD-12, auditoría de diseño,
     2026-08-04): antes había 14 tamaños de texto, 8 radios y ningún token
     de espaciado (paddings literales sueltos en cada regla). Reducidos a 5
     tamaños de texto, 3 radios (sumando --radius, ya existente) y 6 pasos
     de espaciado -- valores elegidos para minimizar el corrimiento visual
     de los valores que reemplazan (ej. --space-2 usa 9px, el valor
     individual más repetido del archivo, en vez de redondear a un 8/10
     "más prolijo"). --radius-full (50%) cubre tanto círculos reales (chip
     de paleta, ícono de login) como la pastilla de .dcs-tag (antes 20px
     literal): a la altura real de esas piezas, ambos valores topan igual
     en el redondeo máximo del navegador -- visualmente idénticos. */
  --radius-sm: 7px;
  --radius-full: 50%;
  --text-sm: 12px;
  --text-base: 14px;
  --text-lg: 17px;
  --text-xl: 25px;
  --text-2xl: 36px;
  --space-1: 4px;
  --space-2: 9px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 28px;
  --font-display: 'Space Grotesk', sans-serif;
  --font-body: 'IBM Plex Sans', sans-serif;
  --font-mono: 'IBM Plex Mono', monospace;
}

#dcs-root {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--bg);
  min-height: 100vh;
  width: 100%;
  position: relative;
  font-size: var(--text-base);
  line-height: 1.45;
  overflow-x: hidden;
}

#dcs-root button { font-family: var(--font-body); cursor: pointer; }
#dcs-root input, #dcs-root select, #dcs-root textarea { font-family: var(--font-body); }

/* ---------- Layout ---------- */
.dcs-shell { display: flex; min-height: 100vh; }

.dcs-sidebar {
  width: 220px;
  flex-shrink: 0;
  background: var(--qhawa-color-surface-brand);
  /* border-left con el background de marca SIN diluir (no color-mix): a
     diferencia del tinte de fondo de arriba, acá no hay texto encima que
     dependa de contraste, así que no tiene el techo del 10% -- es el
     diferenciador fuerte entre tenants que QD-01 pedía (garantizado
     distinto entre cualquier par de paletas, no solo perceptible en
     algunas combinaciones). */
  border-left: 4px solid var(--qhawa-color-background);
  border-right: 1px solid var(--line);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  padding: var(--space-4) 0;
}
.dcs-brand {
  padding: 0 var(--space-4) var(--space-4) var(--space-4);
  border-bottom: 1px solid var(--line);
  margin-bottom: 12px;
}
.dcs-brand .mark {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-lg); color: var(--ink);
}
.dcs-brand .mark img { flex-shrink: 0; width: 56px; height: auto; }
.dcs-brand-icon {
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: var(--radius-sm);
  background: var(--qhawa-color-primary-soft);
}
/* --ink-faint (no --ink-soft) rompe WCAG AA acá: estos 2 selectores viven
   dentro de .dcs-sidebar, cuyo fondo real es var(--qhawa-color-surface-brand)
   (QD-01), no --surface blanco puro -- --ink-faint da ~3.7-3.9:1 contra ese
   fondo en las 7 paletas de palettes.js (P2 real, ClauBotTI, 2026-08-04),
   mientras --ink-soft sí cumple (4.63:1-4.79:1). Ver test real en
   contrast.test.js. */
.dcs-brand .sub { font-size: var(--text-sm); color: var(--ink-soft); margin-top: 4px; letter-spacing: 0.04em; text-transform: uppercase; }
.dcs-brand-info { margin-top: 8px; font-size: var(--text-sm); color: var(--ink-soft); line-height: 1.5; }

.dcs-nav { display: flex; flex-direction: column; gap: 2px; padding: 0 var(--space-2); flex: 1; }
.dcs-nav button {
  display: flex; align-items: center; gap: 10px;
  background: transparent; border: none; color: var(--ink-soft);
  padding: var(--space-3) var(--space-3); border-radius: var(--radius-sm); font-size: var(--text-sm); font-weight: 500;
  text-align: left; transition: background .12s ease, color .12s ease;
}
.dcs-nav button svg { flex-shrink: 0; opacity: 0.85; }
.dcs-nav button:hover { background: var(--surface-2); color: var(--ink); }
.dcs-nav button.active { background: var(--qhawa-color-primary); color: var(--qhawa-color-on-primary); }
.dcs-nav button.back { color: var(--ink-soft); font-size: var(--text-sm); margin-bottom: 6px; padding-bottom: var(--space-3); border-bottom: 1px solid var(--line); }
.dcs-nav a { text-decoration: none; display: block; }

.dcs-sidebar-foot { padding: var(--space-2); border-top: 1px solid var(--line); margin-top: 8px; }
.dcs-sidebar-foot button {
  width: 100%; display: flex; align-items: center; gap: 10px;
  background: transparent; border: none; color: var(--ink-soft);
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); font-size: var(--text-sm); font-weight: 500; text-align: left;
}
.dcs-sidebar-foot button:hover { background: var(--surface-2); color: var(--ink); }

.dcs-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.dcs-topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-4) var(--space-6); border-bottom: 1px solid var(--line); background: var(--surface);
}
.dcs-topbar h1 { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 700; margin: 0; }
.dcs-topbar .stamp {
  font-family: var(--font-mono); font-size: var(--text-sm); color: var(--ink-faint);
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--space-1) var(--space-2);
}
.dcs-content { padding: var(--space-5) var(--space-6) calc(var(--space-6) * 2 + var(--space-1)) var(--space-6); flex: 1; overflow-y: auto; overflow-x: hidden; max-width: 100%; }

/* ---------- Cards / grid ---------- */
.dcs-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin-bottom: 22px; }
.dcs-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--space-4); position: relative; overflow: hidden;
}
.dcs-card .lbl { font-size: var(--text-sm); text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); font-weight: 600; }
.dcs-card .val { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 600; margin-top: 6px; color: var(--qhawa-color-primary-on-surface); }
.dcs-card .val.warn { color: var(--salida); }
.dcs-card .val.home-icon { color: var(--qhawa-color-primary); }
.dcs-card .val.home-icon svg { width: 30px; height: 30px; }
.dcs-card .sub { font-size: var(--text-sm); color: var(--ink-faint); margin-top: 3px; }
.dcs-card .stripe { position: absolute; top:0; left:0; width: 4px; height: 100%; background: var(--qhawa-color-primary); }
.dcs-card .stripe.amber { background: var(--amber); }
.dcs-card .stripe.salida { background: var(--salida); }
.dcs-card .stripe.entrada { background: var(--entrada); }
.dcs-card .stripe.estado-pendiente { background: var(--estado-pendiente); }
.dcs-card .stripe.estado-proceso { background: var(--estado-proceso); }
.dcs-card .stripe.estado-cerrada { background: var(--estado-cerrada); }
.dcs-card .stripe.estado-anulada { background: var(--estado-anulada); }
.dcs-card.clickable { cursor: pointer; transition: background .12s ease; }
.dcs-card.clickable:hover { background: var(--surface-2); }

/* Tarjeta "hero" del total (QD-09): mismo componente .dcs-card, pero con
   tipografía más grande y su propia fila -- para que el total se
   distinga del desglose por estructura, no solo por color (a diferencia
   de teñir el fondo de las tarjetas de desglose con --estado-*-soft, que
   se descartó: baja --ink-faint de .sub por debajo de WCAG AA contra esos
   tonos, ~3.6-3.75:1, medido con la misma fórmula de contrast.js). */
.dcs-card-hero { margin-bottom: 14px; }
.dcs-card-hero .val { font-size: var(--text-2xl); }

.dcs-panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  margin-bottom: 20px; overflow: hidden;
}
.dcs-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--line); background: var(--qhawa-color-accent-soft);
}
.dcs-panel-head h3 { font-family: var(--font-display); font-size: var(--text-base); margin: 0; font-weight: 700; }
.dcs-panel-body { padding: var(--space-1) 0; max-width: 100%; overflow-x: auto; }

/* Step G4 (issue #73): pestañas Resumen/Preciario/Materiales de
   Liquidación -- primer uso de tabs en el proyecto, mismo criterio de
   "botón activo" que .dcs-nav button.active (fondo sólido con
   --qhawa-color-primary en vez de un subrayado, para no introducir un
   segundo lenguaje visual de "seleccionado"). */
.dcs-tabs { display: flex; gap: 4px; padding: var(--space-2) var(--space-4) 0 var(--space-4); border-bottom: 1px solid var(--line); }
.dcs-tab {
  border: none; background: transparent; color: var(--ink-soft); font-size: var(--text-sm); font-weight: 600;
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm) var(--radius-sm) 0 0; cursor: pointer;
}
.dcs-tab:hover { background: var(--surface-2); color: var(--ink); }
.dcs-tab.active { background: var(--qhawa-color-primary); color: var(--qhawa-color-on-primary); }
.dcs-tab-panel { display: none; }
.dcs-tab-panel.active { display: block; }

/* ---------- Table ---------- */
table.dcs-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
table.dcs-table th {
  text-align: left; padding: var(--space-2) var(--space-4); font-size: var(--text-sm); text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-soft); border-bottom: 1px solid var(--line); font-weight: 600;
  white-space: nowrap;
}
table.dcs-table td { padding: var(--space-2) var(--space-4); border-bottom: 1px solid var(--line); vertical-align: middle; }
table.dcs-table tr:last-child td { border-bottom: none; }
table.dcs-table tr:hover td { background: var(--surface-2); }
table.dcs-table tr.dcs-row-clickable { cursor: pointer; }
table.dcs-table tr.dcs-row-clickable:hover td { background: var(--qhawa-color-primary-soft); }
.mono { font-family: var(--font-mono); }
.num { font-family: var(--font-mono); text-align: right; }
.dcs-empty { padding: var(--space-6) var(--space-5); text-align: center; color: var(--ink-faint); font-size: var(--text-sm); }

.dcs-tag {
  display: inline-flex; align-items: center; gap: 5px; font-size: var(--text-sm); font-weight: 600;
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-full); font-family: var(--font-mono);
}
.dcs-tag.entrada { background: var(--entrada-soft); color: var(--entrada); }
.dcs-tag.salida { background: var(--salida-soft); color: var(--salida); }
.dcs-tag.low { background: var(--salida-soft); color: var(--salida); }
.dcs-tag.ok { background: var(--entrada-soft); color: var(--entrada); }
.dcs-tag.baja { background: #E4E6EA; color: #57677C; }
.dcs-tag.corregido { background: var(--amber-soft); color: var(--amber); }
/* Estado de proceso de Órdenes de Trabajo (QD-07) -- ver comentario junto
   a los tokens en :root. No reusan --entrada, --salida ni --amber. */
.dcs-tag.estado-pendiente { background: var(--estado-pendiente-soft); color: var(--estado-pendiente); }
.dcs-tag.estado-proceso { background: var(--estado-proceso-soft); color: var(--estado-proceso); }
.dcs-tag.estado-cerrada { background: var(--estado-cerrada-soft); color: var(--estado-cerrada); }
.dcs-tag.estado-anulada { background: var(--estado-anulada-soft); color: var(--estado-anulada); }

/* ---------- Forms / buttons ---------- */
.dcs-btn {
  display: inline-flex; align-items: center; gap: 7px; border-radius: var(--radius-sm); border: 1px solid transparent;
  padding: var(--space-2) var(--space-4); font-size: var(--text-sm); font-weight: 600; background: var(--qhawa-color-primary); color: var(--qhawa-color-on-primary);
}
.dcs-btn:hover { background: var(--qhawa-color-primary-strong); }
.dcs-btn.secondary { background: var(--surface); color: var(--ink); border-color: var(--line); }
.dcs-btn.secondary:hover { background: var(--surface-2); }
.dcs-btn.danger { background: var(--danger); color: #fff; }
.dcs-btn.danger:hover { background: #7d1d16; }
.dcs-btn.amber { background: var(--amber); color: #fff; }
.dcs-btn.ghost { background: transparent; color: var(--ink-soft); border: none; padding: var(--space-1) var(--space-2); }
.dcs-btn.ghost:hover { color: var(--ink); background: var(--surface-2); }
.dcs-btn:disabled { opacity: .5; cursor: not-allowed; }
.dcs-btn.sm { padding: var(--space-1) var(--space-2); font-size: var(--text-sm); }
.dcs-btn.block { width: 100%; justify-content: center; }

.dcs-field { margin-bottom: 13px; }
.dcs-field label { display: block; font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft); margin-bottom: 5px; }
.dcs-field input, .dcs-field select, .dcs-field textarea {
  width: 100%; min-height: 44px; box-sizing: border-box; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm); color: var(--ink); background: #fff;
}
.dcs-field input:focus, .dcs-field select:focus, .dcs-field textarea:focus {
  outline: none; border-color: var(--qhawa-color-primary); box-shadow: 0 0 0 3px var(--qhawa-color-primary-soft);
}
.dcs-field .hint { font-size: var(--text-sm); color: var(--ink-faint); margin-top: 4px; }
/* repeat(auto-fit, minmax(150px, 1fr)) en vez de 1fr fijo (QD-06, auditoría
   de diseño, 2026-08-04): a 390px, "1fr 1fr 1fr" partía el ancho en 3 sin
   piso mínimo -- el campo "Cantidad" de Movimientos quedaba en ~30px y
   "Fecha" se cortaba contra el borde. Con auto-fit, cuando no entran 2 (o
   3) columnas de al menos 150px, colapsan a 1 columna sola sin necesitar
   media query; a escritorio, al haber solo 2 (o 3) elementos reales, las
   pistas de más colapsan a 0 y las reales se estiran a ocupar el ancho
   disponible -- sigue viéndose como 2 (o 3) columnas, no más.

   Efecto colateral real, revisado y aceptado (ClauBotTI, misma ronda):
   dentro de un .dcs-modal angosto (max-width 480px, ej. "Nuevo equipo" de
   Equipos) a ~390px de viewport, .dcs-row2 pasa de 2 columnas de ~149px
   (ya por debajo del piso de 150px que este mismo hallazgo exige) a 1 sola
   columna cómoda. Es el mismo mecanismo de seguridad funcionando de forma
   consistente en todos lados, no una regresión puntual -- decisión: se
   acepta, no se ajusta el mínimo. Cubierto por
   e2e/tests/visual/equipos-mobile.visual.spec.ts. */
.dcs-row2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.dcs-row3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }

.dcs-toolbar { display: flex; align-items: center; gap: 10px; padding: var(--space-3) var(--space-4); flex-wrap: wrap; }
.dcs-search { position: relative; flex: 1; min-width: 220px; }
.dcs-search input { width: 100%; padding: var(--space-2) var(--space-3) var(--space-2) calc(var(--space-6) + var(--space-1)); border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: var(--text-sm); }
.dcs-search svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); opacity: .5; }
.dcs-toolbar select { min-height: 44px; box-sizing: border-box; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); font-size: var(--text-sm); color: var(--ink); background: #fff; }
/* Inputs sueltos de una toolbar de filtros (issue #156, ordenes-trabajo.view.js)
   -- NO ".dcs-toolbar input" a propósito: esa clase de descendiente tendría la
   misma especificidad que ".dcs-search input" (line 359) y, al venir después
   en el archivo, le pisaría el padding-left reservado para el ícono de lupa en
   TODOS los buscadores del sitio (.dcs-search vive anidado dentro de
   .dcs-toolbar en cada módulo). Clase propia aplicada solo a estos inputs,
   sin tocar el resto. */
.dcs-toolbar-input { min-height: 44px; box-sizing: border-box; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); font-size: var(--text-sm); color: var(--ink); background: #fff; }
.dcs-toolbar-input:focus { outline: none; border-color: var(--qhawa-color-primary); box-shadow: 0 0 0 3px var(--qhawa-color-primary-soft); }
.dcs-table-input { min-height: 36px; box-sizing: border-box; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 6px 10px; color: var(--ink); background: #fff; }
.dcs-table-input:focus { outline: none; border-color: var(--qhawa-color-primary); box-shadow: 0 0 0 3px var(--qhawa-color-primary-soft); }

.dcs-pager { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-4); border-top: 1px solid var(--line); font-size: var(--text-sm); color: var(--ink-soft); }
.dcs-pager .grp { display: flex; gap: 6px; align-items: center; }

/* ---------- Modal ---------- */
.dcs-modal-bg {
  position: fixed; inset: 0; background: rgba(14,20,18,.5); display: flex; align-items: center; justify-content: center;
  z-index: 50; padding: var(--space-5);
}
.dcs-modal {
  background: #fff; border-radius: var(--radius); width: 100%; max-width: 480px; max-height: 88vh; overflow-y: auto;
  box-shadow: 0 20px 50px rgba(0,0,0,.25);
}
.dcs-modal.wide { max-width: 720px; }
.dcs-modal-head { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--line); }
.dcs-modal-head h3 { font-family: var(--font-display); font-size: var(--text-lg); margin: 0; }
.dcs-modal-body { padding: var(--space-4) var(--space-5); }
.dcs-modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: var(--space-4) var(--space-5); border-top: 1px solid var(--line); }

/* ---------- Login ---------- */
.dcs-lock-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--qhawa-color-background); padding: var(--space-5); }
.dcs-lock-card { background: #fff; border-radius: var(--radius); width: 100%; max-width: 380px; padding: var(--space-6) var(--space-6); box-shadow: 0 25px 60px rgba(0,0,0,.35); }

.dcs-lock-mark { display:flex; flex-direction:column; align-items:center; margin-bottom: 20px; text-align:center; }
.dcs-lock-mark .lock-logo { width: 92px; height: auto; margin-bottom: 14px; }
.dcs-lock-mark .icon { width: 52px; height: 52px; border-radius: var(--radius-full); background: var(--qhawa-color-primary-soft); display:flex; align-items:center; justify-content:center; margin-bottom: 12px; }
.dcs-lock-mark h2 { font-family: var(--font-display); font-size: var(--text-lg); margin: 0; }
.dcs-lock-mark p { font-size: var(--text-sm); color: var(--ink-soft); margin: 4px 0 0 0; }
.dcs-error { background: var(--danger-soft); color: var(--danger); font-size: var(--text-sm); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); margin-bottom: 12px; }
.dcs-error p { margin: 0 0 8px 0; }

/* Estados de carga (QD-08, auditoría de diseño, 2026-08-04): skeleton con
   la forma real del contenido que va a reemplazar (cards de KPI o filas
   de tabla), no un spinner genérico -- reduce el salto de layout cuando
   llega la respuesta real. Ver app/view-states.js. */
.dcs-skeleton-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin-bottom: 22px; }
.dcs-skeleton-card,
.dcs-skeleton-bar {
  border-radius: var(--radius);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--line) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: dcs-skeleton-pulse 1.4s ease-in-out infinite;
}
.dcs-skeleton-card { height: 88px; }
.dcs-skeleton-bar { height: 16px; border-radius: var(--radius-sm); }
.dcs-skeleton-row td { padding: var(--space-3) var(--space-4); }
@keyframes dcs-skeleton-pulse {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.dcs-link { background: none; border: none; color: var(--qhawa-color-primary-on-surface); font-size: var(--text-sm); font-weight: 600; padding: var(--space-1) 0; text-decoration: underline; }

/* ---------- Toast ---------- */
#dcs-toast-wrap { position: fixed; bottom: 18px; right: 18px; z-index: 100; display: flex; flex-direction: column; gap: 8px; }
.dcs-toast {
  background: var(--qhawa-color-background); color: var(--qhawa-color-text); padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); font-size: var(--text-sm);
  box-shadow: 0 8px 20px rgba(0,0,0,.25); display: flex; align-items: center; gap: 9px; min-width: 220px;
  animation: dcsIn .18s ease;
}
.dcs-toast.err { background: var(--danger); }
@keyframes dcsIn { from { opacity:0; transform: translateY(6px);} to {opacity:1; transform:translateY(0);} }

.dcs-fade-note { font-size: var(--text-sm); color: var(--ink-faint); line-height: 1.5; }
.dcs-section-title { font-family: var(--font-display); font-weight: 700; font-size: var(--text-lg); margin: 0 0 4px 0; }
.dcs-section-desc { font-size: var(--text-sm); color: var(--ink-soft); margin: 0 0 16px 0; }
.checkbox-row { display: flex; align-items: center; gap: 8px; }

/* ---------- Selector de Paleta (Step 3, FE001 Configuración de Empresa) ---------- */
.dcs-palette-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.dcs-palette-swatch {
  display: flex; align-items: center; gap: 6px; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
  border: 2px solid transparent; background: var(--surface-2); cursor: pointer; font-family: var(--font-body);
}
.dcs-palette-swatch.selected { background: var(--qhawa-color-primary-soft); }
.dcs-palette-swatch .chip { width: 14px; height: 14px; border-radius: var(--radius-full); display: inline-block; border: 1px solid rgba(0,0,0,.1); }
.dcs-palette-swatch .label { font-size: var(--text-sm); color: var(--ink); margin-left: 4px; }
.checkbox-row input { width: auto; }

/* ---------- Informe Técnico estructurado (Step G3, Paridad GLP, issue #72) ----------
   Secciones colapsables via <details>/<summary> nativo (sin JS de más para
   abrir/cerrar) -- mismo criterio que el resto del proyecto de no traer una
   librería de componentes para algo que el navegador ya resuelve. */
.inf-seccion { border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 12px; background: var(--surface); }
.inf-seccion > summary {
  cursor: pointer; padding: var(--space-3) var(--space-4); font-weight: 700; font-family: var(--font-display);
  font-size: var(--text-md); list-style: none; display: flex; align-items: center; justify-content: space-between;
}
.inf-seccion > summary::-webkit-details-marker { display: none; }
.inf-seccion > summary::after { content: "+"; font-weight: 400; }
.inf-seccion[open] > summary::after { content: "−"; }
.inf-seccion-body { padding: 0 var(--space-4) var(--space-4) var(--space-4); }

.inf-tanque, .inf-actividad {
  border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 10px; background: var(--surface-2);
}
.inf-tanque > summary, .inf-actividad > summary {
  cursor: pointer; padding: var(--space-2) var(--space-3); font-weight: 600; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.inf-tanque > summary::-webkit-details-marker, .inf-actividad > summary::-webkit-details-marker { display: none; }
.inf-tanque-body, .inf-actividad-body { padding: 0 var(--space-3) var(--space-3) var(--space-3); }

.inf-subseccion-title {
  font-size: var(--text-sm); font-weight: 700; color: var(--ink-soft); text-transform: uppercase;
  letter-spacing: .4px; margin: 14px 0 8px 0;
}
.inf-valvula-row { border: 1px dashed var(--line); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); margin-bottom: 8px; }
.inf-valvula-nombre { font-weight: 600; margin-bottom: 6px; }

.inf-checkbox { display: flex; align-items: center; gap: 8px; font-size: var(--text-sm); font-weight: 600; margin-bottom: 8px; cursor: pointer; }
.inf-checkbox input { width: auto; min-height: auto; }
.inf-instal-extra { padding: var(--space-3); background: var(--surface-2); border-radius: var(--radius-sm); margin: 0 0 14px 0; }

.inf-foto-group, .inf-foto-single {
  display: flex; align-items: center; gap: 10px; margin: 8px 0 14px 0; padding: var(--space-2) var(--space-3);
  background: var(--surface-2); border-radius: var(--radius-sm); border: 1px dashed var(--line);
}
.inf-foto-count { font-size: var(--text-sm); color: var(--ink-soft); }
