/* ============================================================================
 * LEXIS · css/components.css
 * Componentes reutilizables: botones, inputs, tarjetas, KPIs, chips, tablas,
 * toasts, modales, barras de progreso, spinner, feedback y gráficos.
 * ==========================================================================*/

/* ====================================================== SCROLLBAR TEMÁTICA = */
/* Barra de desplazamiento integrada con las variables CSS del tema activo. */
:root {
  --scrollbar-size: 12px;
  --scrollbar-thumb: var(--border-strong);
  --scrollbar-thumb-hover: var(--accent);
  --scrollbar-track: transparent;
}

* {
  scrollbar-width: thin;                              /* Firefox */
  scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
}

::-webkit-scrollbar { width: var(--scrollbar-size); height: var(--scrollbar-size); }

::-webkit-scrollbar-track {
  background: var(--scrollbar-track);
  border-radius: var(--radius-pill);
}

::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border: 3px solid transparent;
  background-clip: content-box;                       /* deja aire alrededor */
  border-radius: var(--radius-pill);
  transition: background var(--transition);
}
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); background-clip: content-box; }
::-webkit-scrollbar-thumb:active { background: var(--accent); background-clip: content-box; }

::-webkit-scrollbar-corner { background: transparent; }

/* Las áreas con scroll interno mantienen la misma barra */
.view-container,
.sidebar,
.chat__log,
.modal__body,
.table-wrap,
.table-wrap--preview,
.textarea {
  scrollbar-gutter: stable;
}

/* =============================================================== BOTONES == */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 9px var(--sp-4);
  font-size: var(--fs-sm);
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition), color var(--transition),
              border-color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

.btn--primary {
  color: var(--accent-contrast);
  background: var(--accent);
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover:not(:disabled) { background: var(--accent-strong); }

.btn--ghost {
  color: var(--text-dim);
  background: var(--surface-2);
  border-color: var(--border);
}
.btn--ghost:hover:not(:disabled) { color: var(--text); background: var(--surface-3); border-color: var(--border-strong); }

.btn--danger {
  color: #fff;
  background: var(--danger);
}
.btn--danger:hover:not(:disabled) { filter: brightness(1.08); }

.btn--danger-text { color: var(--danger); }
.btn--danger-text:hover:not(:disabled) { background: var(--danger-soft); border-color: var(--danger); }

.btn--sm { padding: 6px var(--sp-3); font-size: var(--fs-xs); }
.btn--block { width: 100%; }

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 36px; height: 36px;
  font-size: var(--fs-base);
  color: var(--text-dim);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.icon-btn:hover { color: var(--text); background: var(--surface-2); border-color: var(--border); }
.icon-btn--danger:hover { color: var(--danger); background: var(--danger-soft); border-color: var(--danger); }
.icon-btn--speak.is-playing { color: var(--accent); animation: pulse 900ms ease; }

@keyframes pulse {
  0% { transform: scale(1); }
  45% { transform: scale(1.16); }
  100% { transform: scale(1); }
}

.ico { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ico--lg { width: 26px; height: 26px; }

.link-word {
  color: var(--text);
  font-weight: 650;
  font-size: var(--fs-base);
  text-align: left;
  border-bottom: 1px dashed transparent;
  transition: color var(--transition), border-color var(--transition);
}
.link-word:hover { color: var(--accent); border-bottom-color: var(--accent); }

.mini-btn {
  padding: 1px 6px;
  font-size: var(--fs-xs);
  color: var(--text-faint);
  border-radius: 6px;
  transition: color var(--transition), background var(--transition);
}
.mini-btn:hover { color: var(--accent); background: var(--accent-soft); }

/* ============================================================== INPUTS ==== */
.input {
  width: 100%;
  padding: 9px var(--sp-3);
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
}
.input::placeholder { color: var(--text-faint); }
.input:hover { border-color: var(--border-strong); }
.input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--ring);
}
.input:disabled { opacity: .6; }

.input--search { padding-left: 34px; }
.input--select { cursor: pointer; appearance: none; padding-right: 30px;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-dim) 50%), linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-position: calc(100% - 16px) 52%, calc(100% - 11px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.input--number { max-width: 140px; }
.input--sm { padding: 6px var(--sp-3); font-size: var(--fs-sm); max-width: 220px; }

.textarea { resize: vertical; min-height: 92px; line-height: 1.6; }
.textarea--chat { min-height: 46px; max-height: 180px; resize: none; }
/* Fases de escritura (Fase 4 Contextualización y Fase 5 Narrativa): SOLO los
   cuadros de texto donde se redacta. El resto de la interfaz mantiene su escala
   compacta.
   21,6px = 18px + 20 % (el aumento de legibilidad pedido al escribir).
   Se fija en píxeles (y no en rem) para que no dependa del tamaño de fuente raíz:
   `body` usa --fs-base (14px) y el textarea hereda de ahí, así que un valor
   relativo daría un resultado distinto según el punto de herencia.
   La altura NO se controla aquí: la marca el atributo `rows` del HTML (2 filas en
   contextualización), reducido a la mitad. El `min-height` es solo un suelo por si
   el atributo faltara; con box-sizing:border-box incluye el relleno. */
.textarea--sentence {
  font-size: 21.6px;
  line-height: 1.6;
  min-height: 62px;
}

.input-group { display: flex; gap: var(--sp-2); align-items: stretch; }
.input-group .input { flex: 1; }

.field { display: grid; gap: var(--sp-2); }
.field__label { font-size: var(--fs-sm); font-weight: 600; color: var(--text-dim); }
.field__hint { font-size: var(--fs-xs); color: var(--text-faint); }
.field__value { float: right; font-family: var(--font-mono); color: var(--accent); }

.check {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-dim);
  cursor: pointer;
}
.check input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }

input[type="range"] {
  width: 100%;
  height: 22px;
  accent-color: var(--accent);
  cursor: pointer;
}

.form-grid { display: grid; gap: var(--sp-4); }
.form-note { font-size: var(--fs-xs); color: var(--text-faint); }

/* =============================================================== CHIPS ==== */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 7px;
  font-size: var(--fs-xs);
  font-weight: 550;
  line-height: 1.45;
  color: var(--text-dim);
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}
.chip--action {
  padding: 7px 12px;
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.chip--action:hover { color: var(--text); background: var(--accent-soft); border-color: var(--accent); }
.chip--warn { color: var(--warn); background: var(--warn-soft); border-color: transparent; }
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.tag {
  display: inline-block;
  padding: 2px 9px;
  font-size: var(--fs-xs);
  color: var(--text-dim);
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

/* COMPACTADO: las píldoras de estado de la barra superior («En línea», «IA activa»,
   «Guardado local») ocupaban mucho alto y ancho. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px;
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.45;
  color: var(--text-dim);
  background: var(--surface-3);
  border-radius: var(--radius-pill);
}
.pill--soft { background: var(--surface-2); border: 1px solid var(--border); }
.pill--ok { color: var(--ok); background: var(--ok-soft); }
.pill--warn { color: var(--warn); background: var(--warn-soft); }
.pill--danger { color: var(--danger); background: var(--danger-soft); }

.connection__dot, .keypill__dot {
  width: 7px; height: 7px;
  background: var(--ok);
  border-radius: 50%;
  box-shadow: 0 0 0 3px var(--ok-soft);
}
.keypill__dot { background: var(--text-faint); box-shadow: 0 0 0 3px var(--surface-3); }
#key-pill.is-ok .keypill__dot { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
#connection-pill.is-offline .connection__dot { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }

/* Indicador del modo de persistencia: SQLite local o respaldo en el navegador */
.dbpill__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--text-faint);
  box-shadow: 0 0 0 3px var(--surface-3);
}
#db-pill[data-state="sqlite"] .dbpill__dot { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); }
#db-pill[data-state="checking"] .dbpill__dot { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-soft); }
#db-pill[data-state="local"] .dbpill__dot { background: var(--text-faint); box-shadow: 0 0 0 3px var(--surface-3); }
#db-pill[data-state="sqlite"] { border-color: var(--ok); }

/* ========================================================== BADGES/BOXES = */
.box-badge {
  display: inline-grid;
  place-items: center;
  min-width: 30px;
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--box-color, var(--accent));
  background: color-mix(in srgb, var(--box-color, var(--accent)) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--box-color, var(--accent)) 40%, transparent);
  border-radius: var(--radius-sm);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 9px;
  font-size: var(--fs-xs);
  font-weight: 650;
  border-radius: var(--radius-pill);
}
.badge--soft { color: var(--text-dim); background: var(--surface-3); }
.badge--ai { color: var(--accent); background: var(--accent-soft); }

.level {
  display: inline-block;
  padding: 2px 9px;
  font-size: var(--fs-xs);
  font-weight: 650;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.level--new { color: var(--text-dim); background: var(--surface-3); }
.level--weak { color: var(--danger); background: var(--danger-soft); }
.level--learning { color: var(--warn); background: var(--warn-soft); }
.level--mastered { color: var(--ok); background: var(--ok-soft); }

.bad {
  display: inline-block;
  padding: 1px 8px;
  font-size: var(--fs-xs);
  font-weight: 650;
  border-radius: var(--radius-pill);
}
.bad--wrong { color: var(--danger); background: var(--danger-soft); }
.bad--ok { color: var(--ok); background: var(--ok-soft); }

.acc { font-weight: 700; }
.acc--ok { color: var(--ok); }
.acc--warn { color: var(--warn); }
.acc--bad { color: var(--danger); }

/* =============================================================== CARDS ==== */
.card {
  padding: var(--sp-4);
  width: 100%;              /* ocupa todo el ancho de su columna de la rejilla */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
/* `span 2` solo ocupaba dos columnas de las que hubiera: en un contenedor de una
   sola columna no hacía nada y en uno de tres se quedaba a dos tercios. `1 / -1`
   abarca SIEMPRE todas las columnas, así que la tarjeta queda al 100 % del ancho
   disponible y alineada con el bloque de métricas de arriba. */
.card--wide { grid-column: 1 / -1; }
.card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.card__title { font-size: var(--fs-md); }
.card__sub { font-size: var(--fs-xs); color: var(--text-faint); }
.card__note { margin-top: var(--sp-3); font-size: var(--fs-sm); color: var(--text-dim); }

/* ================================================================= KPI ==== */
/* Las 6 tarjetas van SIEMPRE en UNA sola fila, de forma estricta.
   · `repeat(6, 1fr)` sin `auto-fit` ni `min-width`: el reparto es fijo y no depende
     del ancho, así que nunca se parte en dos filas.
   · `minmax(0, 1fr)` y `min-width: 0` permiten que las tarjetas encojan por debajo
     del tamaño de su contenido en lugar de desbordar en horizontal.
   Ojo: en portátiles de 1366px cada tarjeta queda en ~180px y las etiquetas largas
   parten en dos líneas. Es el precio de la fila estricta; si se prefiere, hay que
   reintroducir un punto de ruptura. */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 6px;
  margin-bottom: var(--sp-2);
}
.kpi-grid--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.kpi {
  display: flex;
  align-items: center;
  gap: 6px;
  /* Relleno interno de 8px como máximo, pedido para que la franja sea baja. */
  padding: 6px 8px;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.kpi--accent { border-left-color: var(--accent); }
.kpi--ok { border-left-color: var(--ok); }
.kpi--warn { border-left-color: var(--warn); }
.kpi--danger { border-left-color: var(--danger); }
.kpi--info { border-left-color: var(--info); }

.kpi__icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 24px; height: 24px;
  font-size: 12px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}
.kpi__body { display: grid; min-width: 0; }
/* Las etiquetas largas («Palabras en el mazo», «Dominadas (caja 5)») parten en dos
   líneas: es preferible a que la tarjeta crezca de ancho y descuadre la fila. */
.kpi__label { font-size: var(--fs-xs); line-height: 1.2; color: var(--text-faint); text-transform: uppercase; letter-spacing: .04em; }
/* Cifra más pequeña que la escala de títulos: la franja entera debe ocupar poco alto. */
.kpi__value { font-size: var(--fs-md); font-weight: 750; line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi__hint { font-size: var(--fs-xs); line-height: 1.2; color: var(--text-dim); }

/* ============================================================ PROGRESS ==== */
.progress {
  height: 6px;
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.progress--sm { height: 6px; }
.progress--lg { height: 12px; }
.progress__fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-strong));
  border-radius: inherit;
  transition: width var(--transition-slow);
}

/* =============================================================== TABLES === */
.table-wrap {
  overflow-x: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.table-wrap--preview { max-height: 300px; overflow-y: auto; }

.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-xs);
  font-weight: 650;
  text-align: left;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-faint);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table td {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background var(--transition); }
.table tbody tr:hover { background: var(--surface-2); }
/* COMPACTADO: filas más bajas para ver más bloques a la vez. */
.table--compact th, .table--compact td { padding: 4px var(--sp-2); }

/* Nombre del bloque: en UNA sola línea. Se ensancha la celda para que quepa el
   texto completo («Libro 1 - Palabras 001 a 100») y se impide el salto, que era lo
   que hacía que cada fila midiera tres renglones de alto.
   Se acota a #blocks-breakdown para NO alterar la primera columna de las demás
   tablas de la aplicación (el listado de palabras del Mazo, la vista previa de
   importación…), donde el texto sí debe poder partirse. */
#blocks-breakdown .table td:first-child,
#blocks-breakdown .table th:first-child { white-space: nowrap; }
#blocks-breakdown .table th:first-child { width: 100%; }

.cell-word__main { display: flex; align-items: center; gap: var(--sp-2); }
.cell-word__pron { margin-top: 2px; }
.cell-es { color: var(--text-dim); }
.cell-pron { white-space: nowrap; }
.cell-level__box { display: flex; align-items: center; gap: var(--sp-2); margin-top: 4px; }
.cell-actions { display: flex; gap: 2px; justify-content: flex-end; }
.cell-actions .icon-btn { width: 30px; height: 30px; font-size: var(--fs-sm); }

.row-weak td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
.row-mastered td:first-child { box-shadow: inset 3px 0 0 var(--ok); }

.flag-trouble { font-size: var(--fs-xs); }

/* =============================================================== TOASTS === */
.toast-host {
  position: fixed;
  bottom: var(--sp-5);
  left: 50%;
  transform: translateX(-50%);
  z-index: 4000;
  display: grid;
  gap: var(--sp-2);
  width: min(520px, calc(100vw - 32px));
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text);
  background: var(--elevated);
  border: 1px solid var(--border-strong);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  animation: toastIn var(--transition) both;
}
.toast.is-leaving { animation: toastOut var(--transition) both; }
.toast__icon {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  font-size: var(--fs-xs);
  font-weight: 800;
  color: var(--accent-contrast);
  background: var(--accent);
  border-radius: 50%;
}
.toast--ok { border-left-color: var(--ok); }
.toast--ok .toast__icon { background: var(--ok); }
.toast--warn { border-left-color: var(--warn); }
.toast--warn .toast__icon { background: var(--warn); color: #241a05; }
.toast--error { border-left-color: var(--danger); }
.toast--error .toast__icon { background: var(--danger); }
.toast--info { border-left-color: var(--info); }
.toast--info .toast__icon { background: var(--info); color: #04141f; }

@keyframes toastIn {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to { opacity: 1; transform: none; }
}
@keyframes toastOut {
  to { opacity: 0; transform: translateY(8px) scale(.98); }
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* =============================================================== MODAL ==== */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: grid;
  place-items: center;
  padding: var(--sp-5);
  background: rgba(3, 6, 12, .62);
  backdrop-filter: blur(4px);
  animation: fadeIn var(--transition) both;
}
.modal {
  display: flex;
  flex-direction: column;
  width: min(560px, 100%);
  max-height: min(88vh, 900px);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: modalIn var(--transition-slow) both;
  overflow: hidden;
}
.modal--wide { width: min(860px, 100%); }

@keyframes modalIn {
  from { opacity: 0; transform: translateY(16px) scale(.98); }
  to { opacity: 1; transform: none; }
}

.modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.modal__title { font-size: var(--fs-md); }
.modal__subtitle { font-size: var(--fs-xs); color: var(--text-faint); }
.modal__body { padding: var(--sp-5); overflow-y: auto; display: grid; gap: var(--sp-4); align-content: start; }
.modal__text { color: var(--text-dim); }
.modal__footer {
  padding: var(--sp-3) var(--sp-5);
  background: var(--surface-2);
  border-top: 1px solid var(--border);
}

/* ================================================================ MISC ==== */
.empty {
  display: grid;
  justify-items: center;
  gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-4);
  text-align: center;
}
.empty__icon { font-size: 34px; opacity: .85; }
.empty__title { font-size: var(--fs-md); }
.empty__text { max-width: 46ch; font-size: var(--fs-sm); color: var(--text-dim); }

.loading {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-dim);
}
.spinner {
  width: 18px; height: 18px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.skeleton { display: grid; gap: var(--sp-2); padding: var(--sp-3); }
.skeleton__line {
  height: 12px;
  background: linear-gradient(90deg, var(--surface-2), var(--surface-3), var(--surface-2));
  border-radius: var(--radius-pill);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
}
@keyframes shimmer { to { background-position: -200% 0; } }

.alert {
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--accent);
  background: var(--surface-2);
  color: var(--text-dim);
}
.alert--ok { border-left-color: var(--ok); color: var(--ok); background: var(--ok-soft); }
.alert--warn { border-left-color: var(--warn); color: var(--warn); background: var(--warn-soft); }
.alert--error { border-left-color: var(--danger); color: var(--danger); background: var(--danger-soft); }

.callout {
  margin-top: var(--sp-6);
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.callout__title { margin-bottom: var(--sp-3); font-size: var(--fs-md); }

.dropdown { position: relative; }
.dropdown__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 20;
  display: grid;
  min-width: 170px;
  padding: var(--sp-1);
  background: var(--elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--transition), transform var(--transition), visibility var(--transition);
}
.dropdown:hover .dropdown__menu,
.dropdown:focus-within .dropdown__menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.dropdown__menu button {
  padding: 8px var(--sp-3);
  font-size: var(--fs-sm);
  text-align: left;
  color: var(--text-dim);
  border-radius: 6px;
}
.dropdown__menu button:hover { color: var(--text); background: var(--surface-2); }

.segmented {
  display: inline-flex;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.segmented__btn {
  padding: 6px var(--sp-3);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--text-dim);
  border-radius: 6px;
  transition: background var(--transition), color var(--transition);
}
.segmented__btn:hover { color: var(--text); }
.segmented__btn.is-active { color: var(--accent-contrast); background: var(--accent); }

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.toolbar__group { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.toolbar__group--grow { flex: 1; min-width: 220px; }

.table-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}

.shortcut-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--sp-3); }
.shortcut {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--text-dim);
}
.shortcut kbd { flex-shrink: 0; }

/* Anillo de foco consistente en elementos interactivos */
.btn:focus-visible,
.icon-btn:focus-visible,
.nav-item:focus-visible,
.option:focus-visible,
.chip--action:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
