/* GENERADO — no editar a mano. Origen: software/web/design-system/app/app.css
   Se rehace con: node scripts/tomar-app.js (vigila pruebas/sonda-tokens.mjs § g). */
/* Componentes de aplicación del design system de Musho (1.1, 26/09/2026; la 1.2 añade § 22-23; la 1.3, § 25-28;
   la 1.4, 27/09: anatomía de la fila, grupo de botones, vacío a la izquierda y § 33 página;
   la 1.5, 27/09: primario, foco, interruptor y pestaña neutros; el coral, solo peligro).
   Los usa el CRM desde la fase 0b de CRM 2 (software/crm/SPEC-CRM2-0B.md).
   Reglas de la casa:
   · Prefijo .ds- en todo: el CRM ya tiene .tarjeta, .fila, .etiqueta con
     otro estilo y las pantallas se migran una a una; sin prefijo se pisan.
     Modificadores con --, partes con __, activo con .es-activo o el ARIA.
   · Solo tokens de app/tokens.css. Lo que no tiene token se declara UNA vez
     aquí abajo como --ds-app-*, con su porqué. Lo vigila app/sonda-app.js.
   · Sin JS se ve bien: el activo lo pinta el servidor con la clase o el
     ARIA; app.js solo anima y abre/cierra.
   · Móvil primero: base < 720 · ≥ 720 tablet · ≥ 1056 PC; tope 1584
     (reglas.md § 33: SOLO esos breakpoints; lo mide sonda-app.js).
   Lo copia el CRM: node app/scripts/tomar-app.js (vigila pruebas/app-css.js). */

:root {
  /* Fuente: el token trae solo «Geist»; si la página no la carga, cae a
     la del sistema en vez de a Times. */
  --ds-app-fuente: var(--ds-typography-family-sans), system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* Medio paso (4 px): la escala de espacio empieza en 8 y los huecos
     entre icono y texto pequeño piden la mitad. */
  --ds-app-paso-medio: calc(var(--ds-spacing-2xs) / 2);
  /* Paso y medio (12 px): relleno lateral de chips y etiquetas densas. */
  --ds-app-paso-12: calc(var(--ds-spacing-2xs) * 1.5);
  /* Línea fina de bordes y separadores. */
  --ds-app-linea: 1px;
  /* Grosor del contorno de foco y del subrayado activo de pestañas. */
  --ds-app-foco: 2px;
  /* Color del foco (1.5, reglas.md § 0.7): neutro, como el primario. El
     coral en una app es peligro o marca quieta; un anillo coral en cada
     tabulación decía «peligro» en todas partes. */
  --ds-app-foco-color: var(--ds-color-bg-inverse);
  /* Acción primaria neutra (1.5, § 0.7 y § 30.8, Carbon: rojo = error, el
     primario es neutro; Untitled en oscuro y Apple hacen lo mismo): el
     inverso del fondo. En oscuro, claro sobre oscuro; en el tema claro del
     CRM los inversos ya son oscuros. El hover mezcla hacia el fondo. */
  --ds-app-primario-fondo: var(--ds-color-bg-inverse);
  --ds-app-primario-texto: var(--ds-color-text-inverse);
  --ds-app-primario-hover: color-mix(in srgb, var(--ds-color-bg-inverse) 88%, var(--ds-color-bg));
  /* Alto del chip de filtro (App Store / MLS): más bajo que un control. */
  --ds-app-chip: 32px;
  /* Relleno interior del segmentado: el indicador «flota» 3 px dentro. */
  --ds-app-segmentado-relleno: 3px;
  /* Punto de color delante de la etiqueta de estado. */
  --ds-app-punto: 6px;
  /* Barra inferior del móvil y botón flotante: 56 px, la medida de
     Material/iOS para la zona del pulgar. */
  --ds-app-barra: 56px;
  --ds-app-fab: 56px;
  /* Anchos máximos de hoja (en tablet/PC) y diálogo. */
  --ds-app-hoja-max: 480px;
  --ds-app-dialogo-max: 400px;
  /* Alto máximo de la hoja en móvil: deja ver que debajo sigue la página. */
  --ds-app-hoja-alto: 85vh;
  /* Mínimo de cada métrica en la rejilla auto-fit. */
  --ds-app-metrica-min: 160px;
  /* Avatar normal (32); el grande usa --ds-spacing-control (40). */
  --ds-app-avatar: 32px;
  /* Icono del estado vacío: 40, más grande que cualquier icono de UI. */
  --ds-app-icono-vacio: 40px;
  /* Capas: barra y FAB sobre el contenido; los <dialog> van en la capa
     superior del navegador y no necesitan z-index. */
  --ds-app-capa-barra: 30;
  --ds-app-capa-fab: 31;
  /* Saltar al contenido (§ 27): por encima de la barra y del FAB al recibir foco. */
  --ds-app-capa-saltar: 40;

  /* 1.2 · piezas de documento y de vista de datos (§ 22-23). Medidas de
     notion/huecos.md, tablas A y B. Son geometría de UNA pieza, no tokens:
     en @theme serían 37 variables de ruido para Yaz y para Figma (Ari,
     26/09). La línea de 1 px es la --ds-app-linea de arriba. */
  /* Cita: raya de 3 px en tinta (tabla A). */
  --ds-app-raya: 3px;
  /* Chip: 20 px de alto; 18 dentro de tarjeta (regla 6). */
  --ds-app-chip-bd: 20px;
  --ds-app-chip-bd-tarjeta: 18px;
  /* Relleno lateral del chip: 6 px (regla 6, medido en medidas.md §8). */
  --ds-app-chip-bd-x: 6px;
  /* Título de página: icono de caja 78 px (tabla A). */
  --ds-app-icono-pagina: 78px;
  /* Migas: 44 px de alto, enlace máx. 160 px (tabla A). */
  --ds-app-migas: 44px;
  --ds-app-miga-max: 160px;
  /* Columnas: hueco de 46 px (tabla A). */
  --ds-app-columnas-hueco: 46px;
  /* Separador: bloque de 13 px con la línea en medio (tabla A). */
  --ds-app-separador: 13px;
  /* Interruptor (§ 24): hueco entre bola y pista = (24 - 20) / 2 menos el borde. */
  --ds-app-interruptor-hueco: calc((var(--ds-icon-size-lg) - var(--ds-icon-size)) / 2 - var(--ds-app-linea));
  /* Tabla simple: celda de 35 px, relleno 7/9 (tabla A). */
  --ds-app-celda-simple: 35px;
  --ds-app-celda-y: 7px;
  --ds-app-celda-x: 9px;
  /* Caja de código: relleno 24/22 (tabla A). */
  --ds-app-codigo-y: 24px;
  --ds-app-codigo-x: 22px;
  /* Pestañas de vista: barra 40, píldora 32, relleno 6/12 (tabla B). */
  --ds-app-vista-barra: 40px;
  --ds-app-vista-pildora: 32px;
  --ds-app-vista-y: 6px;
  /* Tabla de base: cabecera 36, fila 37 (45 a 390), grupo 42 (tabla B). */
  --ds-app-tabla-cabecera: 36px;
  --ds-app-tabla-fila: 37px;
  --ds-app-tabla-fila-movil: 45px;
  --ds-app-tabla-grupo: 42px;
  /* Tablero: columna 276, tarjeta 260 (tabla B). */
  --ds-app-tablero-columna: 276px;
  --ds-app-tablero-tarjeta: 260px;
  /* Relleno de tarjeta ~10/12 (tabla B). */
  --ds-app-tarjeta-y: 10px;
  --ds-app-tarjeta-x: 12px;
  /* Galería: tarjeta de 296 px (tabla B). */
  --ds-app-galeria: 296px;
  /* Calendario: celda de 124 px de alto (tabla B). */
  --ds-app-calendario-celda: 124px;
  /* Cronograma: fila 36, barra 34 (tabla B). */
  --ds-app-cronograma-fila: 36px;
  --ds-app-cronograma-barra: 34px;
  /* Lista: fila de 30 px (tabla B). */
  --ds-app-lista-fila: 30px;
  /* Gráfico: 300 px de alto (tabla B). */
  --ds-app-grafico: 300px;
  /* Ficha: fila 34, etiqueta 160 (120 a 390), 37 hasta el cuerpo (tabla B). */
  --ds-app-prop-fila: 34px;
  --ds-app-prop-etiqueta: 160px;
  --ds-app-prop-etiqueta-movil: 120px;
  --ds-app-prop-cuerpo: 37px;
  /* Estado vacío: 144 px sin borde (tabla B). */
  --ds-app-vacio: 144px;
  /* Página ancha (§ 33, 1.4): el tope de Carbon «Max»; no hay token de
     rejilla con ese valor (--ds-grid-grid-max es 1440, el de la web). */
  --ds-app-pagina-max: 1584px;

  /* El tono de un chip de base: lo fija cada .ds-chip--<color> (§ 23, B4)
     y lo leen el chip, la columna de tablero, la portada de galería, la
     barra de cronograma y el gráfico. Es un mecanismo, no un token: sin
     prefijo --ds- porque su valor cambia por clase y app.css solo declara
     --ds-* en este :root. Por defecto, gris. */
  --tono: var(--ds-color-chip-gris);
  --tono-soft: var(--ds-color-chip-gris-soft);
}

/* ═══ 1. Botón ═══════════════════════════════════════════════════════ */
.ds-boton {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--ds-spacing-2xs);
  min-height: var(--ds-spacing-control); padding: 0 var(--ds-spacing-xs);
  border: 0; border-radius: var(--ds-radius-card);
  font-family: inherit; font-size: var(--ds-typography-size-ui-md);
  line-height: var(--ds-typography-line-height-ui-md); font-weight: 500;
  white-space: nowrap; text-decoration: none; cursor: pointer;
  background: var(--ds-color-bg-tertiary); color: var(--ds-color-text);
  transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho),
              color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
.ds-boton--primario { background: var(--ds-app-primario-fondo); color: var(--ds-app-primario-texto); }
.ds-boton--primario:hover { background: var(--ds-app-primario-hover); }
.ds-boton--secundario { background: var(--ds-color-bg-tertiary); color: var(--ds-color-text); }
.ds-boton--secundario:hover { background: var(--ds-color-bg-quaternary); }
.ds-boton--terciario { background: transparent; color: var(--ds-color-text-secondary); }
.ds-boton--terciario:hover { background: var(--ds-color-bg-tertiary); color: var(--ds-color-text); }
/* Lo destructivo es lo único coral de la app (1.5, § 0.7): el error es la
   familia del acento; suave hasta el hover. */
.ds-boton--destructivo { background: var(--ds-color-error-soft); color: var(--ds-color-error-fg); }
.ds-boton--destructivo:hover { background: var(--ds-color-error); color: var(--ds-color-text-on-accent); }
.ds-boton--enlace { background: transparent; color: var(--ds-color-text); padding: 0; text-decoration: underline; text-underline-offset: var(--ds-app-paso-medio); }
.ds-boton--enlace:hover { text-decoration: underline; text-underline-offset: var(--ds-app-paso-medio); }
.ds-boton--icono { padding: 0; width: var(--ds-spacing-control); }
.ds-boton--fila { min-height: var(--ds-spacing-control-sm); }
.ds-boton--icono.ds-boton--fila { width: var(--ds-spacing-control-sm); }
.ds-boton:disabled, .ds-boton[aria-disabled="true"] {
  color: var(--ds-color-text-disabled); cursor: not-allowed;
}
.ds-boton--primario:disabled, .ds-boton--secundario:disabled, .ds-boton--destructivo:disabled,
.ds-boton--primario[aria-disabled="true"], .ds-boton--destructivo[aria-disabled="true"] {
  background: var(--ds-color-bg-tertiary);
}
.ds-boton--terciario:disabled, .ds-boton--enlace:disabled { background: transparent; text-decoration: none; }
/* Grupo de botones (1.4, reglas.md § 1 y § 30.4, Carbon): el par o trío de un
   diálogo, hoja o pie de formulario iguala el ancho del más largo. */
.ds-botones--iguales { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--ds-spacing-2xs); }

/* Foco visible, común a todo lo que se pulsa. */
.ds-boton:focus-visible, .ds-chip:focus-visible, .ds-segmentado__item:focus-visible,
.ds-pestanas__item:focus-visible, a.ds-tarjeta:focus-visible, .ds-fila:focus-visible,
.ds-fab:focus-visible, .ds-barra-inferior__item:focus-visible, .ds-sidebar__item:focus-visible,
.ds-migas a:focus-visible, .ds-chip__quitar:focus-visible {
  outline: var(--ds-app-foco) solid var(--ds-app-foco-color);
  outline-offset: var(--ds-app-foco);
}

/* ═══ 2. Chip de filtro ══════════════════════════════════════════════ */
/* Fila con scroll horizontal, sin salto de línea y sin barra visible. */
.ds-chips {
  display: flex; gap: var(--ds-spacing-2xs); overflow-x: auto;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.ds-chips::-webkit-scrollbar { display: none; }
.ds-chip {
  flex: none; display: inline-flex; align-items: center; gap: var(--ds-app-paso-medio);
  height: var(--ds-app-chip); padding: 0 var(--ds-app-paso-12);
  border: 0; border-radius: var(--ds-radius-full);
  background: var(--ds-color-bg-tertiary); color: var(--ds-color-text-secondary);
  font-family: inherit; font-size: var(--ds-typography-size-ui-sm);
  line-height: var(--ds-typography-line-height-ui-sm); font-weight: 500;
  white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho),
              color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
.ds-chip:hover { color: var(--ds-color-text); }
/* Activo = inverso (fondo claro sobre oscuro), como la MLS. */
.ds-chip[aria-pressed="true"], .ds-chip.es-activo {
  background: var(--ds-color-bg-inverse); color: var(--ds-color-text-inverse);
}
.ds-chip__cuenta { font-variant-numeric: tabular-nums; opacity: 0.7; }
.ds-chip__quitar {
  display: inline-flex; align-items: center; justify-content: center;
  margin-right: calc(var(--ds-app-paso-medio) * -1);
  border: 0; padding: 0; background: none; color: inherit; cursor: pointer;
  font: inherit; line-height: 1;
}

/* ═══ 3. Control segmentado ══════════════════════════════════════════ */
/* Sin JS, el ítem activo lleva el fondo él mismo. Con JS (app.js pone
   data-listo), el fondo lo lleva __indicador y se desliza. */
.ds-segmentado {
  position: relative; display: flex; isolation: isolate;
  padding: var(--ds-app-segmentado-relleno);
  background: var(--ds-color-bg-tertiary); border-radius: var(--ds-radius-full);
}
.ds-segmentado__item {
  flex: 1 1 0; min-width: 0; position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  min-height: calc(var(--ds-spacing-control) - 2 * var(--ds-app-segmentado-relleno));
  padding: 0 var(--ds-app-paso-12);
  border: 0; border-radius: var(--ds-radius-full); background: transparent;
  color: var(--ds-color-text-secondary); font-family: inherit;
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  font-weight: 500; text-decoration: none; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color var(--ds-motion-duration-move) var(--ds-motion-easing-musho);
}
.ds-segmentado__item[aria-selected="true"], .ds-segmentado__item.es-activo {
  background: var(--ds-color-bg-quaternary); color: var(--ds-color-text);
}
.ds-segmentado__indicador {
  display: none; position: absolute; z-index: 0;
  top: var(--ds-app-segmentado-relleno); bottom: var(--ds-app-segmentado-relleno); left: 0;
  background: var(--ds-color-bg-quaternary); border-radius: var(--ds-radius-full);
  pointer-events: none;
}
.ds-segmentado[data-listo] .ds-segmentado__indicador { display: block; }
.ds-segmentado[data-listo] .ds-segmentado__item[aria-selected="true"],
.ds-segmentado[data-listo] .ds-segmentado__item.es-activo { background: transparent; }
.ds-segmentado[data-animado] .ds-segmentado__indicador {
  transition: transform var(--ds-motion-duration-move) var(--ds-motion-easing-musho),
              width var(--ds-motion-duration-move) var(--ds-motion-easing-musho);
}

/* Contador dentro del ítem (CRM 2 · 2a): cuántos hay en cada estado. El
   de «Atrasados» con algo dentro va en rojo: el color dice PRIORIDAD. */
.ds-segmentado__num {
  margin-left: var(--ds-app-paso-medio);
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  font-variant-numeric: tabular-nums; color: var(--ds-color-text-tertiary);
}
.ds-segmentado__num--alerta { color: var(--ds-color-error-fg); }

/* ═══ 4. Pestañas ════════════════════════════════════════════════════ */
.ds-pestanas {
  display: flex; gap: var(--ds-spacing-sm); overflow-x: auto;
  scrollbar-width: none; border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-pestanas::-webkit-scrollbar { display: none; }
.ds-pestanas__item {
  flex: none; display: flex; align-items: center;
  min-height: var(--ds-spacing-touch);
  color: var(--ds-color-text-tertiary); text-decoration: none; white-space: nowrap;
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  font-weight: 500; background: none; border: 0; padding: 0; font-family: inherit; cursor: pointer;
  transition: color var(--ds-motion-duration-move) var(--ds-motion-easing-musho),
              box-shadow var(--ds-motion-duration-move) var(--ds-motion-easing-musho);
}
.ds-pestanas__item:hover { color: var(--ds-color-text-secondary); }
.ds-pestanas__item[aria-current], .ds-pestanas__item.es-activo {
  color: var(--ds-color-text);
  box-shadow: inset 0 calc(var(--ds-app-foco) * -1) 0 var(--ds-app-foco-color);
}

/* ═══ 5. Campo ═══════════════════════════════════════════════════════ */
.ds-campo { display: flex; flex-direction: column; gap: var(--ds-app-paso-medio); min-width: 0; }
.ds-campo__etiqueta {
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary); font-weight: 500;
}
.ds-campo__obligatorio { color: var(--ds-color-error-fg); margin-left: var(--ds-app-paso-medio); }
.ds-campo__control {
  width: 100%; min-height: var(--ds-spacing-control); padding: 0 var(--ds-app-paso-12);
  background: var(--ds-color-bg-elevated); color: var(--ds-color-text);
  border: var(--ds-app-linea) solid var(--ds-color-border); border-radius: var(--ds-radius-card);
  font-family: inherit; font-size: var(--ds-typography-size-ui-md);
  line-height: var(--ds-typography-line-height-ui-md);
  transition: border-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
textarea.ds-campo__control { padding: var(--ds-spacing-2xs) var(--ds-app-paso-12); min-height: calc(var(--ds-spacing-control) * 2); resize: vertical; }
.ds-campo__control::placeholder { color: var(--ds-color-text-placeholder); }
.ds-campo__control:focus { outline: none; border-color: var(--ds-color-border-strong); box-shadow: var(--ds-shadow-xs); }
.ds-campo__control:disabled { color: var(--ds-color-text-disabled); cursor: not-allowed; }
.ds-campo__ayuda {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary);
}
.ds-campo__error {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-error-fg);
}
.ds-campo--error .ds-campo__control { border-color: var(--ds-color-error); }

/* ═══ 6. Etiqueta de estado ══════════════════════════════════════════ */
.ds-etiqueta {
  display: inline-flex; align-items: center; gap: var(--ds-app-paso-medio);
  padding: 0 var(--ds-spacing-2xs); border-radius: var(--ds-radius-tag);
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  font-weight: 500; white-space: nowrap;
  background: var(--ds-color-bg-tertiary); color: var(--ds-color-text-secondary);
}
.ds-etiqueta::before {
  content: ""; flex: none; width: var(--ds-app-punto); height: var(--ds-app-punto);
  border-radius: var(--ds-radius-full); background: currentColor;
}
.ds-etiqueta--ok { background: var(--ds-color-success-soft); color: var(--ds-color-success-fg); }
.ds-etiqueta--aviso { background: var(--ds-color-warning-soft); color: var(--ds-color-warning-fg); }
.ds-etiqueta--error { background: var(--ds-color-error-soft); color: var(--ds-color-error-fg); }
.ds-etiqueta--info { background: var(--ds-color-info-soft); color: var(--ds-color-info-fg); }
.ds-etiqueta--neutro { background: var(--ds-color-bg-tertiary); color: var(--ds-color-text-secondary); }

/* ═══ 7. Tarjeta ═════════════════════════════════════════════════════ */
/* El estado va DENTRO como etiqueta, nunca como borde. */
.ds-tarjeta {
  display: flex; flex-direction: column; gap: var(--ds-app-paso-medio);
  background: var(--ds-color-bg-elevated); border-radius: var(--ds-radius-card);
  padding: var(--ds-spacing-sm); color: var(--ds-color-text); text-decoration: none; min-width: 0;
}
a.ds-tarjeta { transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho); }
a.ds-tarjeta:hover { background: var(--ds-color-bg-tertiary); }
.ds-tarjeta__caption {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary); text-transform: uppercase;
  letter-spacing: var(--ds-typography-letter-spacing-label); font-weight: 500;
}
.ds-tarjeta__titulo {
  margin: 0; font-size: var(--ds-typography-size-ui-lg); line-height: var(--ds-typography-line-height-ui-lg);
  font-weight: 600; color: var(--ds-color-text);
}
.ds-tarjeta__meta {
  margin: 0; font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary);
}
.ds-tarjeta__acciones { display: flex; flex-wrap: wrap; gap: var(--ds-spacing-2xs); margin-top: var(--ds-spacing-2xs); }

/* ═══ 8. Lista de filas ══════════════════════════════════════════════ */
.ds-lista { list-style: none; margin: 0; padding: 0; background: var(--ds-color-bg-elevated); border-radius: var(--ds-radius-card); }
.ds-lista > li + li, .ds-lista > .ds-fila + .ds-fila { border-top: var(--ds-app-linea) solid var(--ds-color-border-subtle); }
.ds-fila {
  display: flex; align-items: center; gap: var(--ds-app-paso-12);
  min-height: var(--ds-spacing-touch); padding: var(--ds-spacing-2xs) var(--ds-spacing-xs);
  color: var(--ds-color-text); text-decoration: none;
  transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
a.ds-fila:hover, button.ds-fila:hover { background: var(--ds-color-bg-tertiary); }
button.ds-fila { width: 100%; border: 0; background: none; font: inherit; text-align: left; cursor: pointer; }
.ds-fila__icono { color: var(--ds-color-text-secondary); }
.ds-fila__texto { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ds-fila__titulo {
  font-size: var(--ds-typography-size-ui-md); line-height: var(--ds-typography-line-height-ui-md);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ds-fila__sub {
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ds-fila__chevron { color: var(--ds-color-text-tertiary); }
/* Anatomía de la fila (1.4, reglas.md § 8): icono · texto (la etiqueta DENTRO
   del título, tras el texto) · meta (un dato corto a la derecha) · hueco de
   acción (chevron, ≤ 2 iconos o .ds-fila__hueco del ancho del chevron), para
   que el borde derecho de la lista sea el mismo en todas las filas. */
.ds-fila__titulo .ds-etiqueta { vertical-align: middle; margin-inline-start: var(--ds-spacing-2xs); }
.ds-fila__meta {
  flex: none; text-align: right; font-variant-numeric: tabular-nums;
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary);
}
.ds-fila__hueco { flex: none; width: var(--ds-icon-size); }

/* ═══ 9. Hoja inferior ═══════════════════════════════════════════════ */
/* <dialog>: en móvil sube desde abajo; en ≥ 720 se centra. La entrada
   la anima @starting-style; app.js solo llama a showModal()/close(). */
.ds-hoja {
  position: fixed; inset: auto 0 0 0; margin: 0; width: 100%; max-width: none;
  max-height: var(--ds-app-hoja-alto); padding: 0; border: 0;
  display: none; flex-direction: column;
  background: var(--ds-color-bg-elevated); color: var(--ds-color-text);
  border-radius: var(--ds-radius-card) var(--ds-radius-card) 0 0;
  transform: translateY(100%);
  transition: transform var(--ds-motion-duration-reveal) var(--ds-motion-easing-musho),
              overlay var(--ds-motion-duration-reveal) allow-discrete,
              display var(--ds-motion-duration-reveal) allow-discrete;
}
.ds-hoja[open] { display: flex; transform: translateY(0); }
@starting-style { .ds-hoja[open] { transform: translateY(100%); } }
.ds-hoja::backdrop, .ds-dialogo::backdrop {
  background: var(--ds-color-bg-overlay); opacity: 0;
  transition: opacity var(--ds-motion-duration-reveal) var(--ds-motion-easing-musho),
              overlay var(--ds-motion-duration-reveal) allow-discrete,
              display var(--ds-motion-duration-reveal) allow-discrete;
}
.ds-hoja[open]::backdrop, .ds-dialogo[open]::backdrop { opacity: 1; }
@starting-style { .ds-hoja[open]::backdrop, .ds-dialogo[open]::backdrop { opacity: 0; } }
.ds-hoja__cabecera {
  display: flex; align-items: center; justify-content: space-between; gap: var(--ds-spacing-2xs);
  padding: var(--ds-spacing-2xs) var(--ds-spacing-2xs) var(--ds-spacing-2xs) var(--ds-spacing-xs);
  border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-hoja__titulo {
  margin: 0; font-size: var(--ds-typography-size-ui-lg); line-height: var(--ds-typography-line-height-ui-lg); font-weight: 600;
}
.ds-hoja__cuerpo { flex: 1; overflow-y: auto; padding: var(--ds-spacing-xs); display: flex; flex-direction: column; gap: var(--ds-spacing-xs); }
.ds-hoja__pie {
  display: flex; gap: var(--ds-spacing-2xs); justify-content: space-between;
  padding: var(--ds-app-paso-12) var(--ds-spacing-xs) calc(var(--ds-app-paso-12) + env(safe-area-inset-bottom));
  border-top: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-hoja__pie .ds-boton--primario { flex: 1; }
@media (min-width: 720px) {
  .ds-hoja {
    inset: 0; margin: auto; width: calc(100% - 2 * var(--ds-spacing-sm)); max-width: var(--ds-app-hoja-max);
    height: fit-content; border-radius: var(--ds-radius-card);
    transform: translateY(var(--ds-spacing-sm)); opacity: 0;
    transition: transform var(--ds-motion-duration-reveal) var(--ds-motion-easing-musho),
                opacity var(--ds-motion-duration-reveal) var(--ds-motion-easing-musho),
                overlay var(--ds-motion-duration-reveal) allow-discrete,
                display var(--ds-motion-duration-reveal) allow-discrete;
  }
  .ds-hoja[open] { transform: translateY(0); opacity: 1; }
  @starting-style { .ds-hoja[open] { transform: translateY(var(--ds-spacing-sm)); opacity: 0; } }
  .ds-hoja__pie { padding-bottom: var(--ds-app-paso-12); }
}

/* ═══ 10. Botón flotante ═════════════════════════════════════════════ */
.ds-fab {
  position: fixed; z-index: var(--ds-app-capa-fab);
  right: var(--ds-spacing-xs);
  bottom: calc(var(--ds-app-barra) + env(safe-area-inset-bottom) + var(--ds-spacing-xs));
  display: flex; align-items: center; justify-content: center;
  width: var(--ds-app-fab); height: var(--ds-app-fab); padding: 0; border: 0;
  border-radius: var(--ds-radius-full); background: var(--ds-app-primario-fondo);
  color: var(--ds-app-primario-texto); box-shadow: var(--ds-shadow-float);
  text-decoration: none; cursor: pointer;
  transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
.ds-fab:hover { background: var(--ds-app-primario-hover); }
@media (min-width: 1056px) { .ds-fab { display: none; } }

/* ═══ 11. Barra inferior ═════════════════════════════════════════════ */
.ds-barra-inferior {
  position: fixed; z-index: var(--ds-app-capa-barra); left: 0; right: 0; bottom: 0;
  display: flex; align-items: stretch;
  height: calc(var(--ds-app-barra) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--ds-color-bg-elevated);
  border-top: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-barra-inferior__item {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--ds-app-paso-medio);
  color: var(--ds-color-text-tertiary); text-decoration: none;
  transition: color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
.ds-barra-inferior__item[aria-current], .ds-barra-inferior__item.es-activo { color: var(--ds-color-text); }
.ds-barra-inferior__texto {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--ds-typography-size-ui-2xs); line-height: var(--ds-typography-line-height-ui-2xs); font-weight: 500;
}
@media (min-width: 1056px) { .ds-barra-inferior { display: none; } }

/* ═══ 12. Barra lateral ══════════════════════════════════════════════ */
.ds-sidebar {
  display: none; flex-direction: column; gap: var(--ds-spacing-2xs);
  width: var(--ds-spacing-sidebar); flex: none;
  padding: var(--ds-spacing-xs); background: var(--ds-color-bg-elevated);
}
@media (min-width: 1056px) { .ds-sidebar { display: flex; } }
.ds-sidebar__logo {
  display: flex; align-items: center; gap: var(--ds-spacing-2xs);
  min-height: var(--ds-spacing-control); padding: 0 var(--ds-app-paso-12);
  font-size: var(--ds-typography-size-ui-lg); line-height: var(--ds-typography-line-height-ui-lg);
  font-weight: 600; color: var(--ds-color-text); text-decoration: none;
}
.ds-sidebar__nav { display: flex; flex-direction: column; gap: var(--ds-app-paso-medio); flex: 1; }
.ds-sidebar__seccion {
  margin: var(--ds-spacing-xs) 0 var(--ds-app-paso-medio); padding: 0 var(--ds-app-paso-12);
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary); text-transform: uppercase;
  letter-spacing: var(--ds-typography-letter-spacing-label); font-weight: 500;
}
.ds-sidebar__item {
  display: flex; align-items: center; gap: var(--ds-app-paso-12);
  min-height: var(--ds-spacing-control); padding: 0 var(--ds-app-paso-12);
  border-radius: var(--ds-radius-card); color: var(--ds-color-text-secondary); text-decoration: none;
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm); font-weight: 500;
  transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho),
              color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
.ds-sidebar__item:hover, .ds-sidebar__item[aria-current], .ds-sidebar__item.es-activo {
  background: var(--ds-color-bg-tertiary); color: var(--ds-color-text);
}
.ds-sidebar__pie {
  display: flex; align-items: center; gap: var(--ds-app-paso-12);
  padding-top: var(--ds-app-paso-12); border-top: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-sidebar__persona { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ds-sidebar__nombre {
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  font-weight: 500; color: var(--ds-color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ds-sidebar__rol {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary);
}

/* ═══ 13. Migas ══════════════════════════════════════════════════════ */
.ds-migas ol {
  display: flex; align-items: center; min-width: 0; list-style: none; margin: 0; padding: 0;
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-tertiary);
}
.ds-migas li { display: flex; align-items: center; min-width: 0; white-space: nowrap; }
/* Se recorta PRIMERO la última miga (la página en la que estás, que el
   título de la página repite entera) y las anteriores conservan su texto
   hasta un 40 % del ancho: con todas encogiendo por igual, en un móvil
   salía «Bo… › Clínica…» y no se leía ni de dónde vienes ni dónde estás
   (CRM 2 fase 1, 26/09). */
.ds-migas li:not(:last-child) { flex: 0 0 auto; max-width: 40%; }
.ds-migas li:last-child { flex: 0 1 auto; }
.ds-migas li + li::before { content: "›"; flex: none; padding: 0 var(--ds-spacing-2xs); }
.ds-migas a, .ds-migas span { overflow: hidden; text-overflow: ellipsis; color: inherit; text-decoration: none; }
.ds-migas a:hover { color: var(--ds-color-text-secondary); }
.ds-migas li:last-child, .ds-migas [aria-current] { color: var(--ds-color-text-secondary); }

/* ═══ 14. Estado vacío ═══════════════════════════════════════════════ */
/* 1.4 (reglas.md § 14, § 30.7 Carbon): a la izquierda, como el resto de la
   página; el centrado de la 1.3 queda en .ds-vacio--centrado. */
.ds-vacio {
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  gap: var(--ds-spacing-2xs); padding: var(--ds-spacing-lg) var(--ds-spacing-sm);
}
.ds-vacio--centrado { align-items: center; text-align: center; }
.ds-vacio__icono { width: var(--ds-app-icono-vacio); height: var(--ds-app-icono-vacio); color: var(--ds-color-text-tertiary); }
.ds-vacio__titulo {
  margin: var(--ds-spacing-2xs) 0 0; font-size: var(--ds-typography-size-ui-lg);
  line-height: var(--ds-typography-line-height-ui-lg); font-weight: 600; color: var(--ds-color-text);
}
.ds-vacio__texto {
  margin: 0 0 var(--ds-spacing-2xs); max-width: 40ch;
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary);
}

/* ═══ 15. Métrica ════════════════════════════════════════════════════ */
.ds-metricas {
  display: grid; gap: var(--ds-spacing-2xs);
  grid-template-columns: repeat(auto-fit, minmax(var(--ds-app-metrica-min), 1fr));
}
.ds-metrica {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--ds-app-paso-medio);
  padding: var(--ds-spacing-xs); background: var(--ds-color-bg-elevated); border-radius: var(--ds-radius-card);
}
.ds-metrica__caption {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary); text-transform: uppercase;
  letter-spacing: var(--ds-typography-letter-spacing-label); font-weight: 500;
}
.ds-metrica__numero {
  font-size: var(--ds-typography-size-metric); line-height: var(--ds-typography-line-height-metric);
  letter-spacing: var(--ds-typography-letter-spacing-metric); font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--ds-color-text);
}
.ds-metrica__sub {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-secondary);
}
/* Dominante (CRM 2 · fase 3): UNA por fila, la que pide acción; ocupa dos
   columnas y su número sube a h2. El color del número dice qué hacer:
   alerta (rojo) = atrasado, aviso (ámbar) = falta algo, ok (verde) = bien. */
.ds-metrica--dominante { grid-column: span 2; }
.ds-metrica--dominante .ds-metrica__numero {
  font-size: var(--ds-typography-size-h2); line-height: var(--ds-typography-line-height-h2);
}
.ds-metrica--alerta .ds-metrica__numero { color: var(--ds-color-error-fg); }
.ds-metrica--aviso .ds-metrica__numero { color: var(--ds-color-warning-fg); }
.ds-metrica--ok .ds-metrica__numero { color: var(--ds-color-success-fg); }

/* ═══ 16. Tabla ══════════════════════════════════════════════════════ */
/* .ds-tabla es el envoltorio con scroll horizontal; dentro, un <table>. */
.ds-tabla { overflow-x: auto; background: var(--ds-color-bg-elevated); border-radius: var(--ds-radius-card); }
.ds-tabla table { width: 100%; border-collapse: collapse; }
.ds-tabla th {
  height: var(--ds-spacing-control); padding: 0 var(--ds-spacing-xs); text-align: left;
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary); text-transform: uppercase;
  letter-spacing: var(--ds-typography-letter-spacing-label); font-weight: 500; white-space: nowrap;
  border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-tabla td {
  height: var(--ds-spacing-touch); padding: 0 var(--ds-spacing-xs);
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text); white-space: nowrap;
  border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-tabla tbody tr:last-child td { border-bottom: 0; }
.ds-tabla tbody tr { transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho); }
.ds-tabla tbody tr:hover { background: var(--ds-color-bg-tertiary); }
.ds-tabla .ds-tabla__num { text-align: right; font-variant-numeric: tabular-nums; }

/* ═══ 17. Avatar ═════════════════════════════════════════════════════ */
.ds-avatar {
  flex: none; display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
  width: var(--ds-app-avatar); height: var(--ds-app-avatar); border-radius: var(--ds-radius-full);
  background: var(--ds-color-bg-quaternary); color: var(--ds-color-text);
  font-size: var(--ds-typography-size-ui-sm); line-height: 1; font-weight: 600; text-transform: uppercase;
}
.ds-avatar--grande { width: var(--ds-spacing-control); height: var(--ds-spacing-control); }
.ds-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ═══ 18. Diálogo ════════════════════════════════════════════════════ */
.ds-dialogo {
  width: calc(100% - 2 * var(--ds-spacing-xs)); max-width: var(--ds-app-dialogo-max);
  margin: auto; padding: 0; border: 0; border-radius: var(--ds-radius-card);
  background: var(--ds-color-bg-elevated); color: var(--ds-color-text);
  box-shadow: var(--ds-shadow-float); opacity: 0; transform: scale(0.96);
  transition: opacity var(--ds-motion-duration-reveal) var(--ds-motion-easing-musho),
              transform var(--ds-motion-duration-reveal) var(--ds-motion-easing-musho),
              overlay var(--ds-motion-duration-reveal) allow-discrete,
              display var(--ds-motion-duration-reveal) allow-discrete;
}
.ds-dialogo[open] { opacity: 1; transform: scale(1); }
@starting-style { .ds-dialogo[open] { opacity: 0; transform: scale(0.96); } }
.ds-dialogo__titulo {
  margin: 0; padding: var(--ds-spacing-sm) var(--ds-spacing-sm) 0;
  font-size: var(--ds-typography-size-ui-lg); line-height: var(--ds-typography-line-height-ui-lg); font-weight: 600;
}
.ds-dialogo__texto {
  margin: 0; padding: var(--ds-spacing-2xs) var(--ds-spacing-sm) 0;
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary);
}
.ds-dialogo__pie {
  display: flex; justify-content: flex-end; gap: var(--ds-spacing-2xs);
  padding: var(--ds-spacing-sm);
}

/* ═══ 19. Icono ══════════════════════════════════════════════════════ */
.ds-icono {
  flex: none; display: block;
  width: var(--ds-icon-size); height: var(--ds-icon-size);
  fill: none; stroke: currentColor; stroke-width: var(--ds-icon-stroke);
  stroke-linecap: round; stroke-linejoin: round; color: inherit;
}
.ds-icono--sm { width: var(--ds-icon-size-sm); height: var(--ds-icon-size-sm); }
.ds-icono--lg { width: var(--ds-icon-size-lg); height: var(--ds-icon-size-lg); }

/* ═══ 20. Cabecera móvil ═════════════════════════════════════════════ */
/* Arriba en móvil y tablet: (avatar) Título (acciones). El título es el
   de la SECCIÓN (de dónde vienes, como Apple); el <h1> de la página dice
   dónde estás. Pegada arriba con sticky y no fixed: así no pide un hueco
   de relleno en cada página. Oculta desde 1056 (allí manda la barra
   lateral). Los botones de las zonas son .ds-boton--terciario --icono. */
.ds-cabecera {
  position: sticky; top: 0; z-index: var(--ds-app-capa-barra);
  display: flex; align-items: center; gap: var(--ds-spacing-2xs);
  min-height: calc(var(--ds-spacing-control) + 2 * var(--ds-spacing-2xs));
  padding: calc(var(--ds-spacing-2xs) + env(safe-area-inset-top)) var(--ds-spacing-2xs) var(--ds-spacing-2xs);
  background: var(--ds-color-bg-elevated); color: var(--ds-color-text);
  border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-cabecera__inicio, .ds-cabecera__acciones {
  flex: none; display: flex; align-items: center; gap: var(--ds-app-paso-medio);
  min-width: var(--ds-spacing-control);
}
.ds-cabecera__acciones { justify-content: flex-end; }
.ds-cabecera__titulo {
  flex: 1; min-width: 0; margin: 0; text-align: center;
  font-size: var(--ds-typography-size-ui-md); line-height: var(--ds-typography-line-height-ui-md);
  font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (min-width: 1056px) { .ds-cabecera { display: none; } }

/* ═══ 21. Título de página ════════════════════════════════════════════ */
/* Cabecera de un detalle (la ficha de un lead): caption (qué es) → h1
   (cuál) → acciones (lo que se hace ya) → meta (el resto). El caption
   calca el de la tarjeta; una etiqueta de estado puede ir a su lado. */
.ds-titulo { display: flex; flex-direction: column; gap: var(--ds-spacing-2xs); min-width: 0; }
.ds-titulo__caption {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--ds-spacing-2xs); margin: 0;
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary); text-transform: uppercase;
  letter-spacing: var(--ds-typography-letter-spacing-label); font-weight: 500;
}
.ds-titulo__caption .ds-etiqueta { text-transform: none; letter-spacing: normal; }
.ds-titulo__h1 {
  margin: 0; font-size: var(--ds-typography-size-h3); line-height: var(--ds-typography-line-height-h3);
  letter-spacing: var(--ds-typography-letter-spacing-h3); font-weight: 600;
  color: var(--ds-color-text); overflow-wrap: anywhere;
}
.ds-titulo__acciones { display: flex; flex-wrap: wrap; gap: var(--ds-spacing-2xs); }
.ds-titulo__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--ds-app-paso-medio) var(--ds-app-paso-12);
  margin: 0; font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary);
}

/* Movimiento reducido: los tokens de duración no lo apagan solos, así
   que aquí se lleva a 0 todo lo de .ds-. */
@media (prefers-reduced-motion: reduce) {
  [class*="ds-"], [class*="ds-"]::backdrop {
    transition-duration: 0s !important; animation-duration: 0s !important;
  }
}

/* ═══ 22. Documento ══════════════════════════════════════════════════ */
/* Piezas de Notion, familia A (1.2, 26/09/2026): Documentos y Biblioteca.
   Mergeadas desde design-system/propuesta/piezas-notion.css (spec
   SPEC-DS-NOTION-PIEZAS.md; valores de notion/huecos.md). Notion da
   geometría, ritmo y relaciones; el color, los roles del DS. Lo que ya
   existía arriba (migas) lleva modificador (--doc) y la base no cambia;
   lo nuevo, nombre nuevo. Sin JS: el desplegable es <details>, el to-do un
   checkbox real. Base ≥ 720, ajustes < 720. */

/* ═══ A1. Marco de lectura (regla 2) ═══ */
.ds-doc {
  max-width: var(--ds-spacing-lectura); margin-inline: auto;
  font-family: var(--ds-typography-family-sans), system-ui, sans-serif;
  font-size: var(--ds-doc-cuerpo); line-height: var(--ds-doc-linea);
  color: var(--ds-color-text);
}
@media (max-width: 719px) { .ds-doc { max-width: var(--ds-spacing-lectura-movil); } }

/* ═══ A2. Título de página (40/700, icono de caja 78) ═══ */
.ds-doc__icono {
  display: grid; place-items: center;
  width: var(--ds-app-icono-pagina); height: var(--ds-app-icono-pagina);
  margin-bottom: var(--ds-spacing-2xs); border-radius: var(--ds-radius-block);
  background: var(--ds-color-bg-tertiary); font-size: var(--ds-doc-titulo); line-height: 1;
}
.ds-doc__titulo {
  margin: 0 0 var(--ds-spacing-2xs);
  font-size: var(--ds-doc-titulo); line-height: 1.2;
  font-weight: var(--ds-doc-peso-titulo); color: var(--ds-color-text);
}

/* ═══ A3. Encabezados y párrafo (reglas 3 y 4) ═══ */
.ds-doc h1, .ds-doc h2, .ds-doc h3, .ds-doc h4 {
  font-weight: var(--ds-doc-peso-encabezado); line-height: 1.3; color: var(--ds-color-text);
}
.ds-doc h1 { font-size: var(--ds-doc-h1); margin: var(--ds-doc-sobre-h1) 0 var(--ds-doc-bajo-h1); }
.ds-doc h2 { font-size: var(--ds-doc-h2); margin: var(--ds-doc-sobre-h2) 0 var(--ds-doc-bajo-h2); }
.ds-doc h3 { font-size: var(--ds-doc-h3); margin: var(--ds-doc-sobre-h3) 0 var(--ds-doc-bajo-h3); }
.ds-doc h4 { font-size: var(--ds-doc-h4); margin: var(--ds-doc-sobre-h4) 0 var(--ds-doc-bajo-h4); }
.ds-doc p { margin: 0 0 var(--ds-doc-parrafo); }

/* ═══ A4. Enlace en tinta (regla 5: la marca no entra en el párrafo) ═══ */
.ds-doc a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: .8px; text-underline-offset: .1em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
}
.ds-doc a:hover { text-decoration-color: currentColor; }

/* ═══ A5. Listas (26 px por nivel, 2 px entre puntos) ═══ */
.ds-doc ul, .ds-doc ol { margin: 0 0 var(--ds-doc-parrafo); padding-left: var(--ds-doc-lista-sangria); }
.ds-doc li + li { margin-top: var(--ds-doc-lista-hueco); }
.ds-doc li > ul, .ds-doc li > ol { margin: var(--ds-doc-lista-hueco) 0 0; }
.ds-doc li::marker { color: var(--ds-color-text); }

/* ═══ A6. Código en línea (tinta sobre bg-tertiary, mono, nunca en rojo) ═══ */
.ds-codigo {
  font-family: var(--ds-typography-family-mono), ui-monospace, monospace;
  font-size: .85em; padding: .2em .4em; border-radius: var(--ds-radius-chip);
  background: var(--ds-color-bg-tertiary); color: var(--ds-color-text);
}

/* ═══ A7. To-do (casilla 16, marcada = texto tachado) ═══ */
.ds-todo { list-style: none; padding-left: 0; margin: 0 0 var(--ds-doc-parrafo); }
.ds-todo li { display: flex; align-items: flex-start; gap: var(--ds-spacing-2xs); }
.ds-todo input {
  flex: none; margin: calc((var(--ds-doc-linea) - var(--ds-icon-size-sm)) / 2) 0 0;
  width: var(--ds-icon-size-sm); height: var(--ds-icon-size-sm);
  accent-color: var(--ds-color-info); cursor: pointer;
}
.ds-todo input:checked + span { text-decoration: line-through; color: var(--ds-color-text-tertiary); }

/* ═══ A8. Desplegable (<details>, triángulo en tinta) ═══ */
.ds-desplegable { margin: 0 0 var(--ds-doc-parrafo); }
.ds-desplegable > summary {
  display: flex; align-items: flex-start; gap: var(--ds-radius-chip);
  list-style: none; cursor: pointer;
}
.ds-desplegable > summary::-webkit-details-marker { display: none; }
.ds-desplegable > summary::before {
  content: "▸"; flex: none; width: var(--ds-icon-size-lg); text-align: center;
  color: var(--ds-color-text);
  transition: transform var(--ds-motion-duration-move) var(--ds-motion-easing-musho);
}
.ds-desplegable[open] > summary::before { transform: rotate(90deg); }
.ds-desplegable > :not(summary) { margin: var(--ds-doc-lista-hueco) 0 0 calc(var(--ds-icon-size-lg) + var(--ds-radius-chip)); }

/* ═══ A9. Aviso / callout (relleno 12, radio 10, icono 24 + 6) ═══ */
.ds-aviso {
  display: flex; align-items: flex-start; gap: calc(var(--ds-spacing-2xs) * .75);
  margin: 0 0 var(--ds-doc-parrafo); padding: calc(var(--ds-spacing-2xs) * 1.5);
  border-radius: var(--ds-radius-block); background: var(--ds-color-bg-tertiary); color: var(--ds-color-text);
}
.ds-aviso__icono { flex: none; width: var(--ds-icon-size-lg); text-align: center; font-size: var(--ds-doc-cuerpo); }
.ds-aviso > p, .ds-aviso > div { margin: 0; min-width: 0; }
.ds-aviso--info { background: var(--ds-color-info-soft); }
.ds-aviso--gris { background: var(--ds-color-bg-tertiary); }
.ds-aviso--aviso { background: var(--ds-color-warning-soft); }
.ds-aviso--ok { background: var(--ds-color-success-soft); }

/* ═══ A10. Cita (raya de 3 en tinta, texto en tinta) ═══ */
.ds-cita {
  margin: 0 0 var(--ds-doc-parrafo); padding: 0 calc(var(--ds-spacing-2xs) * 1.75);
  border-left: var(--ds-app-raya) solid var(--ds-color-text); color: var(--ds-color-text);
}
.ds-cita p { margin: 0; }

/* ═══ A11. Separador (bloque de 13 con línea de 1 al 11 %) ═══ */
.ds-separador {
  height: var(--ds-app-separador); margin: 0 0 var(--ds-doc-parrafo); border: 0;
  background: linear-gradient(var(--ds-color-border), var(--ds-color-border)) center / 100% var(--ds-app-linea) no-repeat;
}

/* ═══ A12. Caja de código (radio 10, relleno 24/22, mono 0,85 em) ═══ */
.ds-bloque-codigo {
  margin: 0 0 var(--ds-doc-parrafo); padding: var(--ds-app-codigo-y) var(--ds-app-codigo-x);
  border-radius: var(--ds-radius-block); background: var(--ds-color-bg-tertiary); color: var(--ds-color-text);
  font-family: var(--ds-typography-family-mono), ui-monospace, monospace;
  font-size: .85em; line-height: 1.5; overflow-x: auto; white-space: pre;
}

/* ═══ A13. Tabla simple (celda 35, relleno 7/9, bordes al 11 %) ═══ */
.ds-tabla-simple { width: 100%; margin: 0 0 var(--ds-doc-parrafo); border-collapse: collapse; }
.ds-tabla-simple th, .ds-tabla-simple td {
  height: var(--ds-app-celda-simple); padding: var(--ds-app-celda-y) var(--ds-app-celda-x);
  border: var(--ds-app-linea) solid var(--ds-color-border); text-align: left; vertical-align: top;
}
.ds-tabla-simple th { background: var(--ds-color-bg-elevated); font-weight: 500; }

/* ═══ A14. Columnas (hueco 46; a < 720 se apilan) ═══ */
.ds-columnas {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  gap: var(--ds-app-columnas-hueco); margin: 0 0 var(--ds-doc-parrafo);
}
.ds-columnas > * > :last-child { margin-bottom: 0; }
@media (max-width: 719px) { .ds-columnas { grid-auto-flow: row; gap: var(--ds-doc-parrafo); } }

/* ═══ A15. Migas de documento (44, separador «/» tenue, enlace máx. 160) ═══ */
.ds-migas--doc { display: flex; align-items: center; min-height: var(--ds-app-migas); }
.ds-migas--doc ol { color: var(--ds-color-text-secondary); }
.ds-migas--doc li + li::before { content: "/"; color: var(--ds-color-border-strong); }
.ds-migas--doc li:not(:last-child) { max-width: var(--ds-app-miga-max); }
.ds-migas--doc li:last-child, .ds-migas--doc [aria-current] { color: var(--ds-color-text); }

/* ═══ A16. Enlace a página hija (línea, icono 24, sin subrayado) ═══ */
.ds-doc a.ds-pagina-hija, .ds-pagina-hija {
  display: flex; align-items: center; gap: var(--ds-radius-chip);
  margin: 0 0 var(--ds-doc-lista-hueco); padding: var(--ds-doc-lista-hueco) 0;
  color: var(--ds-color-text); font-weight: 500; text-decoration: none;
  border-radius: var(--ds-radius-chip);
}
.ds-pagina-hija:hover { background: var(--ds-color-bg-tertiary); }
.ds-pagina-hija__icono { flex: none; width: var(--ds-icon-size-lg); text-align: center; }

/* ═══ A17. Escala de documento a < 720 (regla 3, medida a 390) ═══ */
/* tokens.css se resuelve a 1440: la escala de móvil viaja como tokens
   --ds-doc-*-movil y se aplica aquí, pieza a pieza. */
@media (max-width: 719px) {
  .ds-doc { line-height: var(--ds-doc-linea-movil); }
  .ds-doc__icono, .ds-doc__titulo { font-size: var(--ds-doc-titulo-movil); }
  .ds-doc h1 { font-size: var(--ds-doc-h1-movil); }
  .ds-doc h2 { font-size: var(--ds-doc-h2-movil); }
  .ds-doc h3 { font-size: var(--ds-doc-h3-movil); }
  .ds-doc h4 { font-size: var(--ds-doc-h4-movil); }
  .ds-todo input { margin-top: calc((var(--ds-doc-linea-movil) - var(--ds-icon-size-sm)) / 2); }
}

/* ═══ 23. Vistas de datos ════════════════════════════════════════════ */
/* Piezas de Notion, familia B (1.2, 26/09/2026): Pipeline, Tareas, Hoy,
   fichas. Densidad de interfaz: se escanea a 14 px y la meta a 12. Lo que
   ya existía arriba (pestañas, tabla, chip, tarjeta, lista, vacío) lleva
   modificador (--vista, --bd) y su base NO cambia: las pantallas 0-2a la
   usan. El color de estado es el tono de chip (--tono, ver :root). */

/* ═══ B1. Pestañas de vista (barra 40, activa = píldora 32) ═══ */
.ds-pestanas--vista { align-items: center; gap: var(--ds-radius-chip); min-height: var(--ds-app-vista-barra); }
.ds-pestanas--vista .ds-pestanas__item {
  min-height: var(--ds-app-vista-pildora); padding: var(--ds-app-vista-y) calc(var(--ds-spacing-2xs) * 1.5);
  border-radius: var(--ds-radius-full); color: var(--ds-color-text-secondary);
}
.ds-pestanas--vista .ds-pestanas__item:hover { background: var(--ds-color-bg-tertiary); }
.ds-pestanas--vista .ds-pestanas__item[aria-current], .ds-pestanas--vista .ds-pestanas__item.es-activo {
  background: var(--ds-color-bg-tertiary); color: var(--ds-color-text); box-shadow: none;
}

/* ═══ B2. Tabla de base (cabecera 36 con icono de tipo, fila 37, 14 px) ═══ */
.ds-tabla--bd { background: transparent; border-radius: 0; }
.ds-tabla--bd th {
  height: var(--ds-app-tabla-cabecera); padding: 0 var(--ds-spacing-2xs);
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  font-weight: 400; color: var(--ds-color-text-secondary);
  text-transform: none; letter-spacing: normal;
}
.ds-tabla--bd td {
  height: var(--ds-app-tabla-fila); padding: 0 var(--ds-spacing-2xs);
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
}
.ds-tabla--bd th + th, .ds-tabla--bd td + td { border-left: var(--ds-app-linea) solid var(--ds-color-border-subtle); }
.ds-tabla--bd th:first-child, .ds-tabla--bd td:first-child { width: var(--ds-spacing-sidebar); }
.ds-tabla--bd td:first-child { font-weight: 500; }
.ds-tabla--bd tbody tr:last-child td { border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle); }
.ds-tabla--bd .ds-tabla__num { text-align: right; font-variant-numeric: tabular-nums; }
.ds-tabla__tipo {
  width: var(--ds-icon-size-sm); height: var(--ds-icon-size-sm);
  margin-right: var(--ds-radius-bar); vertical-align: text-bottom; color: var(--ds-color-text-tertiary);
}
/* Agrupada: cabecera de grupo 42, 12 de aire debajo. */
.ds-tabla--bd .ds-tabla__grupo td {
  height: var(--ds-app-tabla-grupo); padding-top: calc(var(--ds-spacing-2xs) * 1.5);
  vertical-align: bottom; border-left: 0; font-weight: 500;
}
.ds-tabla--bd .ds-tabla__grupo:hover { background: transparent; }
@media (max-width: 719px) {
  .ds-tabla--bd th, .ds-tabla--bd td { font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs); }
  .ds-tabla--bd td { height: var(--ds-app-tabla-fila-movil); }
}

/* ═══ B3. Formatos: fecha larga y euros a la derecha ═══ */
.ds-fecha { white-space: nowrap; }
.ds-euro { display: block; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ═══ B4. Chip de base (20 px, 14 px, radio 4, tinta POR COLOR) ═══ */
.ds-chip--bd, .ds-chip--bd:hover {
  height: var(--ds-app-chip-bd); padding: 0 var(--ds-app-chip-bd-x);
  border-radius: var(--ds-radius-chip); line-height: var(--ds-app-chip-bd);
  font-size: var(--ds-typography-size-ui-sm); font-weight: 400;
  background: var(--tono-soft); color: var(--tono); cursor: default;
}
/* El tono: la clase solo fija --tono; lo leen chip, columna, portada, barra y gráfico. */
.ds-chip--gris { --tono: var(--ds-color-chip-gris); --tono-soft: var(--ds-color-chip-gris-soft); }
.ds-chip--marron { --tono: var(--ds-color-chip-marron); --tono-soft: var(--ds-color-chip-marron-soft); }
.ds-chip--naranja { --tono: var(--ds-color-chip-naranja); --tono-soft: var(--ds-color-chip-naranja-soft); }
.ds-chip--amarillo { --tono: var(--ds-color-chip-amarillo); --tono-soft: var(--ds-color-chip-amarillo-soft); }
.ds-chip--verde { --tono: var(--ds-color-chip-verde); --tono-soft: var(--ds-color-chip-verde-soft); }
.ds-chip--azul { --tono: var(--ds-color-chip-azul); --tono-soft: var(--ds-color-chip-azul-soft); }
.ds-chip--morado { --tono: var(--ds-color-chip-morado); --tono-soft: var(--ds-color-chip-morado-soft); }
.ds-chip--rosa { --tono: var(--ds-color-chip-rosa); --tono-soft: var(--ds-color-chip-rosa-soft); }
.ds-chip--rojo { --tono: var(--ds-color-chip-rojo); --tono-soft: var(--ds-color-chip-rojo-soft); }

/* ═══ B5. Tablero (columna 276 tintada al 4 %, hueco 12; < 720 APILA) ═══ */
.ds-tablero {
  display: flex; align-items: flex-start; gap: calc(var(--ds-spacing-2xs) * 1.5);
  overflow-x: auto; padding-bottom: var(--ds-spacing-2xs);
}
.ds-tablero__columna {
  flex: none; display: flex; flex-direction: column; gap: var(--ds-spacing-2xs);
  width: var(--ds-app-tablero-columna); padding: 0 var(--ds-spacing-2xs) var(--ds-spacing-2xs);
  border-radius: var(--ds-radius-block);
  background: color-mix(in srgb, var(--tono) 4%, transparent);
}
.ds-tablero__cabecera {
  display: flex; align-items: center; gap: var(--ds-spacing-2xs);
  min-height: var(--ds-app-vista-barra);
}
.ds-tablero__cabecera .ds-chip--bd { font-weight: 500; }
.ds-tablero__contador { font-size: var(--ds-typography-size-ui-sm); color: var(--ds-color-text-tertiary); font-variant-numeric: tabular-nums; }
.ds-tablero__pie {
  display: flex; align-items: center; gap: var(--ds-radius-chip);
  min-height: var(--ds-app-lista-fila); padding: 0 var(--ds-spacing-2xs);
  border: 0; border-radius: var(--ds-radius-block); background: transparent;
  font: inherit; font-size: var(--ds-typography-size-ui-sm); color: var(--ds-color-text-tertiary);
  cursor: pointer; text-align: left;
}
.ds-tablero__pie:hover { background: var(--ds-color-bg-tertiary); color: var(--ds-color-text-secondary); }
@media (max-width: 719px) {
  .ds-tablero { flex-direction: column; align-items: stretch; overflow-x: visible; }
  .ds-tablero__columna { width: auto; }
}

/* ═══ B6. Tarjeta de base (radio 10, sombra en capas, sin borde) ═══ */
.ds-tarjeta--bd {
  gap: calc(var(--ds-spacing-2xs) * .75);
  padding: var(--ds-app-tarjeta-y) var(--ds-app-tarjeta-x);
  border-radius: var(--ds-radius-block); box-shadow: var(--ds-shadow-card);
}
.ds-tablero .ds-tarjeta--bd { width: var(--ds-app-tablero-tarjeta); }
@media (max-width: 719px) { .ds-tablero .ds-tarjeta--bd { width: auto; } }
.ds-tarjeta--bd .ds-tarjeta__titulo {
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm); font-weight: 500;
}
.ds-tarjeta--bd .ds-tarjeta__meta {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
}
.ds-tarjeta--bd .ds-chip--bd {
  height: var(--ds-app-chip-bd-tarjeta); line-height: var(--ds-app-chip-bd-tarjeta);
  font-size: var(--ds-typography-size-ui-xs);
}
.ds-tarjeta--bd .ds-chips { flex-wrap: wrap; gap: var(--ds-radius-chip); }

/* ═══ B7. Lista de base (fila 30, propiedades a la DERECHA) ═══ */
.ds-lista--bd { background: transparent; border-radius: 0; }
.ds-lista--bd > li {
  display: flex; align-items: center; gap: calc(var(--ds-spacing-2xs) * 1.5);
  min-height: var(--ds-app-lista-fila); padding: var(--ds-radius-chip) var(--ds-spacing-2xs);
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
}
.ds-lista--bd > li > :first-child { flex: 1; min-width: 0; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds-lista--bd > li > :not(:first-child) { flex: none; font-size: var(--ds-typography-size-ui-xs); color: var(--ds-color-text-secondary); }
.ds-lista--bd .ds-lista__relacion { color: var(--ds-color-chip-azul); }
@media (max-width: 719px) {
  .ds-lista--bd > li { flex-wrap: wrap; padding-block: var(--ds-spacing-2xs); gap: var(--ds-radius-chip) var(--ds-spacing-2xs); }
  .ds-lista--bd > li > :first-child { flex-basis: 100%; white-space: normal; }
}

/* ═══ B8. Galería (tarjeta 296, sombra de la regla 8) ═══ */
.ds-galeria {
  display: grid; gap: var(--ds-spacing-xs);
  grid-template-columns: repeat(auto-fill, minmax(min(var(--ds-app-galeria), 100%), 1fr));
}
.ds-galeria__portada {
  height: calc(var(--ds-app-galeria) / 2.5); margin: calc(var(--ds-app-tarjeta-y) * -1) calc(var(--ds-app-tarjeta-x) * -1) var(--ds-radius-chip);
  border-radius: var(--ds-radius-block) var(--ds-radius-block) 0 0;
  background: color-mix(in srgb, var(--tono) 14%, var(--ds-color-bg-tertiary));
}

/* ═══ B9. Calendario (celda ×124, número 14 terciario, píldora radio 6) ═══ */
.ds-calendario {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  border-left: var(--ds-app-linea) solid var(--ds-color-border-subtle);
  border-top: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-calendario__cabecera {
  padding: var(--ds-radius-chip) var(--ds-spacing-2xs);
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary);
  border-right: var(--ds-app-linea) solid var(--ds-color-border-subtle);
  border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-calendario__dia {
  display: flex; flex-direction: column; gap: var(--ds-radius-chip); min-width: 0;
  min-height: var(--ds-app-calendario-celda); padding: var(--ds-radius-bar);
  border-right: var(--ds-app-linea) solid var(--ds-color-border-subtle);
  border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-calendario__dia--fuera { background: var(--ds-color-bg-elevated); }
.ds-calendario__numero {
  align-self: flex-end; font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-tertiary); font-variant-numeric: tabular-nums;
}
.ds-calendario__evento {
  padding: 0 var(--ds-radius-bar);
  border-radius: var(--ds-radius-bar); background: var(--ds-color-bg-elevated); box-shadow: var(--ds-shadow-card);
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 719px) {
  .ds-calendario__dia { min-height: calc(var(--ds-app-calendario-celda) / 2); padding: var(--ds-radius-chip) 0; }
  .ds-calendario__evento { font-size: var(--ds-typography-size-ui-2xs); padding: 0 0; }
}

/* ═══ B10. Cronograma (fila 36, barra 34 radio 6, cabecera 32/14) ═══ */
.ds-cronograma { overflow-x: auto; }
.ds-cronograma__cabecera, .ds-cronograma__fila {
  display: grid; grid-template-columns: repeat(14, minmax(var(--ds-spacing-md), 1fr));
  min-width: calc(var(--ds-spacing-lectura) - var(--ds-spacing-lg));
}
.ds-cronograma__cabecera {
  min-height: var(--ds-spacing-md); align-items: center;
  font-size: var(--ds-typography-size-ui-sm); color: var(--ds-color-text-tertiary);
  font-variant-numeric: tabular-nums; border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-cronograma__cabecera > * { text-align: center; }
.ds-cronograma__fila {
  min-height: var(--ds-app-cronograma-fila); align-items: center;
  border-bottom: var(--ds-app-linea) solid var(--ds-color-border-subtle);
}
.ds-cronograma__barra {
  height: calc(var(--ds-app-cronograma-barra) - var(--ds-radius-chip)); padding: 0 var(--ds-spacing-2xs);
  border-radius: var(--ds-radius-bar); background: var(--tono-soft); color: var(--ds-color-text);
  box-shadow: 0 0 0 var(--ds-app-linea) color-mix(in srgb, var(--tono) 30%, transparent);
  display: block; min-width: 0; line-height: calc(var(--ds-app-cronograma-barra) - var(--ds-radius-chip));
  font-size: var(--ds-typography-size-ui-sm); overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}

/* ═══ B11. Gráfico (svg de barras, 300 de alto, etiquetas 14) ═══ */
.ds-grafico { height: var(--ds-app-grafico); }
.ds-grafico svg { display: block; width: 100%; height: 100%; overflow: visible; }
.ds-grafico__barra { fill: var(--tono); }
.ds-grafico__etiqueta { fill: var(--ds-color-text-secondary); font-size: var(--ds-typography-size-ui-sm); font-family: var(--ds-typography-family-sans), system-ui, sans-serif; }
.ds-grafico__eje { stroke: var(--ds-color-border-subtle); stroke-width: var(--ds-app-linea); }

/* ═══ B12. Propiedades de ficha (fila 34, etiqueta 160, valor SIN caja) ═══ */
.ds-propiedades { display: flex; flex-direction: column; margin: 0 0 var(--ds-app-prop-cuerpo); }
.ds-propiedades__fila {
  display: grid; grid-template-columns: var(--ds-app-prop-etiqueta) minmax(0, 1fr);
  gap: calc(var(--ds-spacing-2xs) * 2.5); align-items: center;
  min-height: var(--ds-app-prop-fila); margin-bottom: var(--ds-radius-chip);
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
}
.ds-propiedades__etiqueta { display: flex; align-items: center; gap: var(--ds-radius-bar); color: var(--ds-color-text-secondary); }
.ds-propiedades__etiqueta svg { flex: none; width: var(--ds-icon-size-sm); height: var(--ds-icon-size-sm); color: var(--ds-color-text-tertiary); }
.ds-propiedades__valor {
  display: flex; align-items: center; gap: var(--ds-radius-chip); flex-wrap: wrap;
  min-height: var(--ds-app-prop-fila); padding: 0 var(--ds-radius-bar);
  border-radius: var(--ds-radius-chip); color: var(--ds-color-text); cursor: pointer;
}
.ds-propiedades__valor:hover { background: var(--ds-color-bg-tertiary); }
.ds-propiedades__valor--vacio { color: var(--ds-color-text-tertiary); }
@media (max-width: 719px) {
  .ds-propiedades__fila { grid-template-columns: var(--ds-app-prop-etiqueta-movil) minmax(0, 1fr); gap: var(--ds-spacing-2xs); }
}

/* ═══ B13. Estado vacío de base (144 sin borde, «Sin resultados») ═══ */
.ds-vacio--bd {
  align-items: center; text-align: center; justify-content: center; gap: calc(var(--ds-spacing-2xs) * 1.5);
  min-height: var(--ds-app-vacio); padding: 0;
}
.ds-vacio--bd .ds-vacio__texto {
  margin: 0; font-size: var(--ds-typography-size-ui-sm); color: var(--ds-color-text-tertiary);
}

/* ═══ 24. Interruptor ════════════════════════════════════════════════ */
/* Toggle a la medida md de Untitled UI (pista 44 × 24, bola 20; regla de
   Asier 26/09: los controles se miden contra Untitled). Un <button
   role="switch" aria-checked>; encendido = acento, como el botón primario.
   Nació en el Sparring (rueditas, 3b) y sube al DS el 26/09 noche: Asier y
   David vieron que «no era del DS». Va siempre con su texto al lado. */
.ds-interruptor {
  flex: none; position: relative; cursor: pointer; padding: 0; box-sizing: border-box;
  width: var(--ds-spacing-touch); height: var(--ds-icon-size-lg);
  border: var(--ds-app-linea) solid var(--ds-color-border); border-radius: var(--ds-radius-full);
  background: var(--ds-color-bg-tertiary);
  transition: background-color var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
.ds-interruptor__bola {
  position: absolute; top: 50%; left: var(--ds-app-interruptor-hueco);
  width: var(--ds-icon-size); height: var(--ds-icon-size); border-radius: var(--ds-radius-full);
  background: var(--ds-color-text-tertiary); transform: translateY(-50%);
  transition: left var(--ds-motion-duration-instant) var(--ds-motion-easing-musho);
}
.ds-interruptor[aria-checked="true"] { background: var(--ds-app-primario-fondo); border-color: var(--ds-app-primario-fondo); }
.ds-interruptor[aria-checked="true"] .ds-interruptor__bola { left: calc(100% - var(--ds-icon-size) - var(--ds-app-interruptor-hueco)); background: var(--ds-app-primario-texto); }
.ds-interruptor:focus-visible { outline: var(--ds-app-foco) solid var(--ds-app-foco-color); outline-offset: var(--ds-app-foco); }
.ds-interruptor:disabled { cursor: not-allowed; background: var(--ds-color-bg-tertiary); border-color: var(--ds-color-border-subtle); }
.ds-interruptor:disabled .ds-interruptor__bola { background: var(--ds-color-text-disabled); }

/* ═══ 25. Título de sección ══════════════════════════════════════════ */
/* 1.3 (26/09/2026, auditoría del Sparring, documentos/p/46): el título de un
   bloque DENTRO de una página. El DS solo tenía títulos amarrados a una pieza
   (tarjeta, hoja, documento) y cada app inventaba el suyo. Título + una frase
   opcional; sin acciones dentro: las de la página viven en .ds-titulo (§ 21).
   Uso: reglas.md § 54. */
.ds-seccion { display: flex; flex-direction: column; gap: var(--ds-app-paso-medio); min-width: 0; margin: 0; }
.ds-seccion__titulo {
  margin: 0; font-size: var(--ds-typography-size-ui-lg); line-height: var(--ds-typography-line-height-ui-lg);
  font-weight: 600; color: var(--ds-color-text);
}
.ds-seccion__texto {
  margin: 0; font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
  color: var(--ds-color-text-secondary);
}

/* ═══ 26. Alerta en línea ════════════════════════════════════════════ */
/* Feedback de algo que acaba de pasar, pegado a lo que lo causó (reglas.md
   § 22 bis y § 55): título = qué pasó (sin punto), texto = qué hacer. No es el
   callout de documento (.ds-aviso, 31), que da contexto ANTES de actuar. El
   color va con texto (§ 0.5): raya + título en el tono, fondo suave. Con
   `hidden` no ocupa sitio. El toast sigue sin pieza. */
.ds-alerta {
  display: flex; flex-direction: column; gap: var(--ds-app-paso-medio); min-width: 0;
  padding: var(--ds-app-paso-12); border-radius: var(--ds-radius-card);
  border-left: var(--ds-app-raya) solid var(--ds-color-info-fg);
  background: var(--ds-color-info-soft); color: var(--ds-color-text);
  font-size: var(--ds-typography-size-ui-sm); line-height: var(--ds-typography-line-height-ui-sm);
}
.ds-alerta[hidden] { display: none; }
.ds-alerta__titulo { margin: 0; font-weight: 600; color: var(--ds-color-info-fg); }
.ds-alerta__texto { margin: 0; color: var(--ds-color-text); }
.ds-alerta--info { border-left-color: var(--ds-color-info-fg); background: var(--ds-color-info-soft); }
.ds-alerta--info .ds-alerta__titulo { color: var(--ds-color-info-fg); }
.ds-alerta--ok { border-left-color: var(--ds-color-success-fg); background: var(--ds-color-success-soft); }
.ds-alerta--ok .ds-alerta__titulo { color: var(--ds-color-success-fg); }
.ds-alerta--atencion { border-left-color: var(--ds-color-warning-fg); background: var(--ds-color-warning-soft); }
.ds-alerta--atencion .ds-alerta__titulo { color: var(--ds-color-warning-fg); }
.ds-alerta--error { border-left-color: var(--ds-color-error-fg); background: var(--ds-color-error-soft); }
.ds-alerta--error .ds-alerta__titulo { color: var(--ds-color-error-fg); }

/* ═══ 27. Saltar al contenido ════════════════════════════════════════ */
/* Primer hijo de <body> (o primer foco de la página) en toda app con
   cabecera (reglas.md § 0.5 y § 56): invisible hasta que recibe foco con el
   teclado; entonces, fijo arriba a la izquierda con el anillo del DS. */
.ds-saltar {
  position: fixed; top: var(--ds-spacing-2xs); left: var(--ds-spacing-2xs); z-index: var(--ds-app-capa-saltar);
  display: inline-flex; align-items: center; min-height: var(--ds-spacing-control);
  padding: 0 var(--ds-app-paso-12); border-radius: var(--ds-radius-card);
  background: var(--ds-color-bg-elevated); color: var(--ds-color-text); box-shadow: var(--ds-shadow-float);
  font-size: var(--ds-typography-size-ui-sm); font-weight: 500; text-decoration: none;
}
.ds-saltar:not(:focus) {
  width: var(--ds-app-linea); height: var(--ds-app-linea); min-height: 0; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; box-shadow: none;
}
.ds-saltar:focus-visible { outline: var(--ds-app-foco) solid var(--ds-app-foco-color); outline-offset: var(--ds-app-foco); }

/* ═══ 28. Texto suelto ═══════════════════════════════════════════════ */
/* Dos utilidades, nada más (reglas.md § 57): .ds-mono para códigos y cifras
   que se comparan en columna; .ds-caption para un pie o una procedencia
   FUERA de una tarjeta (el tamaño y el color de .ds-tarjeta__caption, sin
   versalitas: la mayúscula inicial la pone el texto, § 0.3). */
.ds-mono { font-family: var(--ds-typography-family-mono), ui-monospace, 'Cascadia Mono', Consolas, monospace; font-variant-numeric: tabular-nums; }
.ds-caption {
  font-size: var(--ds-typography-size-ui-xs); line-height: var(--ds-typography-line-height-ui-xs);
  color: var(--ds-color-text-tertiary); font-weight: 500;
}

/* ═══ 33. Página ═════════════════════════════════════════════════════ */
/* 1.4 (27/09/2026, reglas.md § 33, Carbon 2x-grid): el contenedor de toda
   página de una app. Relleno 16 en móvil y 24 desde 720 (Carbon «Max»); UN
   modo por página: lectura (720 de texto + el relleno, la columna de Notion)
   o ancha (tope 1584, Carbon «Max»). Breakpoints: 720 y 1056, nada más. */
.ds-pagina { box-sizing: border-box; width: 100%; margin-inline: auto; padding-inline: var(--ds-spacing-xs); }
@media (min-width: 720px) { .ds-pagina { padding-inline: var(--ds-spacing-sm); } }
.ds-pagina--lectura { max-width: calc(var(--ds-spacing-lectura) + 2 * var(--ds-spacing-sm)); }
.ds-pagina--ancha { max-width: var(--ds-app-pagina-max); }
