/* ============================================================================
   IDENTIDAD VISUAL — Configuración                      scope: .cfg-ui
   ============================================================================
   TODO acá adentro está scopeado bajo `.cfg-ui`. Una sola regla que se escape
   —una `.card`, un `.btn`— rompe los nueve módulos que siguen en Tailwind con
   su propia paleta. Ver docs/identidad-visual.md §6.

   LA PALETA NO ESTÁ ACÁ. Vive en src/core/tokens.css, que se carga antes.
   Configuración **no se aparta en ningún token**: usa la escala tal cual.

   ── POR QUÉ EL TRATAMIENTO PLANO Y NO "CAPAS" ───────────────────────────────
   El ABM usa "Capas" (lienzo oscurecido, tres planos de sombra, acento azure
   propio) porque apila cabecera + barra + rail + tabla: cuatro zonas que a
   13,5 px el peso tipográfico solo no logra separar.

   Configuración tiene otra forma. Cinco de sus siete pantallas son
   FORMULARIOS de una columna —Períodos, Facturación, Ajustes, y las dos de
   sólo lectura— y apenas dos son tablas. Una columna angosta al lado de un
   menú no necesita elevación para tener jerarquía: le alcanza con un ancho de
   lectura acotado y un rail.

   Y el acento es NAVY, no un color inventado: acá el módulo es el sistema
   configurándose a sí mismo, así que por una vez "lo del sistema es navy"
   vale también adentro del área de trabajo. Eso evita tener que justificar un
   segundo azul, que es lo que obligó al ABM a inventar `--azure`.

   Resultado práctico: cero apartamientos de token, y el presupuesto de azul
   de la regla §1.2 se gasta en UNA sola superficie (el botón primario) más el
   trazo del rail.
   ========================================================================== */

/* ── Base ─────────────────────────────────────────────────────────────────
   La fuente, el tamaño y la tinta salen de tokens.css (selector agrupado).
   `.hidden` y `.tnum` también: no se repiten acá. */
.cfg-ui .material-symbols-outlined { font-size: 18px; line-height: 1; vertical-align: -4px; }

/* Obligación §5.2: quien navega con Tab tiene que ver dónde está parado. */
.cfg-ui :focus-visible { outline: 2px solid var(--navy-500); outline-offset: 2px; border-radius: 5px; }

/* ── Armazón ──────────────────────────────────────────────────────────────
   SIN ESPACIO entre las dos clases. El div es `class="cfg-ui cfg-shell"`: UN
   elemento con las dos, no un `.cfg-shell` adentro de un `.cfg-ui`. Escrito
   con espacio el bloque no matchea NADA y se cae entero en silencio — sin
   `display:flex` y sin `height:100%`, el módulo crece con su contenido dentro
   de un contenedor `overflow:hidden` y se queda sin scroll. Es exactamente el
   bug que le costó seis etapas al ABM. Ver §8 del manual. */
.cfg-ui.cfg-shell {
    display: flex; flex-direction: column;
    height: 100%; min-height: 0;
    background: var(--canvas);
}

.cfg-ui .cfg-split { display: flex; align-items: stretch; flex: 1; min-height: 0; }

/* ── Rail de secciones ────────────────────────────────────────────────────
   Siete destinos que no tienen nada que ver entre sí: cada uno necesita una
   etiqueta lo bastante larga para decir QUÉ es ("Copias de seguridad",
   "Mapeo Flexxus"). Siete etiquetas así no entran en una barra horizontal a
   13,5 px — que es justo lo que tenía y por qué se leía como un cajón.
   Los `grupo` no son decoración: dicen de qué especie es cada cosa. */
.cfg-ui .cfg-rail {
    flex: 0 0 232px; min-width: 232px;
    background: var(--surface);
    border-right: 1px solid var(--hair);
    padding: 10px 10px 18px;
    overflow-y: auto; overscroll-behavior: contain;
}
.cfg-ui .cfg-rail .grp {
    font-size: .58rem; font-weight: 800; text-transform: uppercase; letter-spacing: .12em;
    color: var(--faint); padding: 16px 10px 6px;
}
.cfg-ui .cfg-rail .grp:first-child { padding-top: 4px; }

.cfg-ui .cfg-rail button {
    position: relative; display: flex; align-items: center; gap: 10px;
    width: 100%; padding: 8px 10px; margin-bottom: 1px;
    background: none; border: 0; border-radius: 8px;
    font: inherit; font-weight: 650; color: var(--muted); text-align: left;
    cursor: pointer;
    transition: background .14s var(--curva), color .14s var(--curva),
                transform .18s var(--curva);
}
/* §5: navegación en COLUMNA. Se corre hacia donde está el contenido y le
   crece una barra al margen. No sube 2 px: eso es el gesto de los BOTONES,
   y confundirlos hace que un ítem de menú se lea como algo que se dispara. */
.cfg-ui .cfg-rail button::before {
    content: ''; position: absolute; left: 0; top: 6px; bottom: 6px; width: 3px;
    border-radius: 0 3px 3px 0; background: var(--hair-strong);
    transform: scaleY(0); transform-origin: center;
    transition: transform .18s var(--curva), background .14s var(--curva);
}
.cfg-ui .cfg-rail button .material-symbols-outlined {
    font-size: 19px; color: var(--faint);
    transition: color .14s var(--curva);
}
.cfg-ui .cfg-rail button:hover,
.cfg-ui .cfg-rail button:focus-visible { background: var(--canvas); color: var(--ink); transform: translateX(4px); }
.cfg-ui .cfg-rail button:hover::before,
.cfg-ui .cfg-rail button:focus-visible::before { transform: scaleY(.55); }
.cfg-ui .cfg-rail button:hover .material-symbols-outlined { color: var(--navy-500); }

.cfg-ui .cfg-rail button[aria-current="page"] {
    background: var(--navy-050); color: var(--navy); transform: none;
}
.cfg-ui .cfg-rail button[aria-current="page"]::before { transform: scaleY(1); background: var(--navy); }
.cfg-ui .cfg-rail button[aria-current="page"] .material-symbols-outlined { color: var(--navy); }

/* ── Área de trabajo ──────────────────────────────────────────────────────
   LO QUE ENTRA ACÁ NO SE ENCOGE. Un ítem flex cuyo `overflow` no es `visible`
   tiene mínimo automático CERO, así que una tarjeta con más contenido que
   pantalla se ACHICA hasta entrar en vez de desbordar: se ve perfecta y
   recorta, que es el peor de los casos porque no hay nada que mirar. */
.cfg-ui .cfg-work {
    flex: 1; min-width: 0; min-height: 0;
    overflow-y: auto; overscroll-behavior: contain;
    display: flex; flex-direction: column;
}
.cfg-ui .cfg-work > * { flex-shrink: 0; }

/* La excepción: una pantalla-TABLA, que en vez de crecer hacia abajo ocupa el
   alto entero y scrollea adentro, para que el encabezado y la barra de filtros
   queden fijos. Es (0,3,0) contra los (0,2,0) de la regla de arriba, así que le
   gana por especificidad y no por orden — que es lo que hay que buscar cuando
   dos reglas se contradicen a propósito. */
.cfg-ui .cfg-work > .cfg-lleno {
    flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column; gap: 14px; padding: var(--gutter);
}
/* Lo de arriba de la tabla (la tira de resumen) mide lo que mide; el que se
   estira y scrollea es la tarjeta, y esa regla es más específica (0,3,0). */
.cfg-ui .cfg-lleno > * { flex-shrink: 0; }

/* La columna de lectura. Un formulario de configuración no se lee mejor por
   ser más ancho: al revés. §3 del manual (78ch de máximo). */
.cfg-ui .cfg-col { width: 100%; max-width: 780px; margin: 0 auto;
                   padding: var(--gutter); display: flex; flex-direction: column; gap: 16px; }
.cfg-ui .cfg-col.ancha { max-width: 1180px; }
.cfg-ui .cfg-col > * { flex-shrink: 0; }

/* ── Estado vacío / bienvenida ────────────────────────────────────────────
   Lo que se ve antes de elegir. No es un tablero: el rail YA es el menú, y
   repetirlo acá sería escribir el mismo nombre por tercera vez. */
.cfg-ui .cfg-ph {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 8px; padding: 44px 24px; text-align: center; color: var(--faint);
}
.cfg-ui .cfg-ph .material-symbols-outlined { font-size: 40px; color: var(--hair-strong); }
.cfg-ui .cfg-ph b { font-size: .95rem; font-weight: 700; color: var(--ink); }
.cfg-ui .cfg-ph span { font-size: .78rem; line-height: 1.6; max-width: 46ch; }

/* ── Tarjeta ──────────────────────────────────────────────────────────────
   Un solo plano: filete de 1 px y la sombra plana del tratamiento sin capas. */
.cfg-ui .cfg-card {
    background: var(--surface); border: 1px solid var(--hair);
    border-radius: var(--r-card); box-shadow: var(--shadow);
    overflow: hidden;
}
.cfg-ui .cfg-card-h {
    display: flex; align-items: center; gap: 9px;
    padding: 13px var(--gutter) 11px; border-bottom: 1px solid var(--hair);
}
.cfg-ui .cfg-card-h .material-symbols-outlined { color: var(--navy-500); font-size: 19px; }
.cfg-ui .cfg-card-h h4 {
    margin: 0; font-size: .68rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: .09em; color: var(--navy);
}
/* El contador se va SIEMPRE al borde derecho, esté en la cabecera de una
   tarjeta o en la barra de filtros. Estaba scopeado sólo a `.cfg-card-h` y en
   la barra quedaba pegado al buscador, como si fuera parte de él. */
.cfg-ui .cfg-card-h .cfg-hint,
.cfg-ui .cfg-bar .cfg-hint { margin-left: auto; }
.cfg-ui .cfg-card-b { padding: var(--gutter); }
.cfg-ui .cfg-card-b > p.cfg-lead { margin: 0 0 14px; font-size: .78rem; line-height: 1.65; color: var(--muted); max-width: 72ch; }
.cfg-ui .cfg-card-f {
    display: flex; align-items: center; gap: 10px;
    padding: 12px var(--gutter); border-top: 1px solid var(--hair); background: #fafbfd;
}

/* Una lista de REGLAS adentro de una tarjeta — no de opciones ni de filas de
   datos, que ya tienen su marcado. Nació con las Guardas de tarifa, donde dos de
   las cinco guardas no tienen perilla que mostrar: lo único que se puede hacer
   con ellas es EXPLICARLAS, y una explicación de tres renglones metida en un
   `<p>` se lee como prosa y se saltea. El punto colgado a la izquierda es lo que
   hace que se cuenten. */
.cfg-ui .cfg-lista { margin: 0; padding-left: 18px; max-width: 72ch; }
.cfg-ui .cfg-lista li { font-size: .78rem; line-height: 1.65; color: var(--muted); margin-bottom: 10px; }
.cfg-ui .cfg-lista li:last-child { margin-bottom: 0; }
.cfg-ui .cfg-lista li b { color: var(--ink); font-variant-numeric: tabular-nums; }

.cfg-ui .cfg-hint { font-size: .72rem; font-weight: 600; color: var(--faint); }
.cfg-ui .cfg-hint b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* ── Botones ──────────────────────────────────────────────────────────────
   §5: se levanta lo que se puede apretar. El primario es la ÚNICA superficie
   navy del área de trabajo — el presupuesto de azul de §1.2 se agota acá. */
.cfg-ui .cfg-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    padding: 8px 15px; border-radius: 9px;
    background: var(--navy); border: 1px solid var(--navy); color: #fff;
    font: inherit; font-size: .78rem; font-weight: 700; white-space: nowrap; cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 43, 107, .22);
    transition: background .14s var(--curva), border-color .14s var(--curva),
                transform .18s var(--curva), box-shadow .18s var(--curva);
}
.cfg-ui .cfg-btn .material-symbols-outlined { font-size: 17px; transition: transform .18s var(--curva); }
.cfg-ui .cfg-btn:hover { background: var(--navy-700); border-color: var(--navy-700);
                         transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 43, 107, .26); }
.cfg-ui .cfg-btn:hover .material-symbols-outlined { transform: translateY(-2px); }
.cfg-ui .cfg-btn:active { transform: translateY(0); box-shadow: 0 2px 8px rgba(0, 43, 107, .22); }
.cfg-ui .cfg-btn:disabled { opacity: .45; cursor: default; transform: none; box-shadow: none; }

/* Secundario: en reposo es GRIS. Si tres secundarios llevan color, ninguno de
   los cuatro botones de la pantalla es el principal. */
.cfg-ui .cfg-btn.sec { background: var(--surface); color: var(--muted);
                       border-color: var(--hair-strong); box-shadow: none; }
.cfg-ui .cfg-btn.sec:hover { background: var(--navy-050); border-color: var(--navy-300);
                             color: var(--navy); box-shadow: none; }

.cfg-ui .cfg-btn.ok { background: var(--ok); border-color: var(--ok); box-shadow: 0 2px 8px rgba(15, 122, 82, .24); }
.cfg-ui .cfg-btn.ok:hover { background: #0b5c3e; border-color: #0b5c3e; }
.cfg-ui .cfg-btn.danger { background: var(--crit); border-color: var(--crit); box-shadow: 0 2px 8px rgba(198, 40, 40, .24); }
.cfg-ui .cfg-btn.danger:hover { background: #a71f1f; border-color: #a71f1f; }

.cfg-ui .cfg-btn.ln { background: none; border-color: transparent; color: var(--navy-500);
                      box-shadow: none; padding-inline: 9px; }
.cfg-ui .cfg-btn.ln:hover { background: var(--navy-050); box-shadow: none; }

/* Íconos de acción sueltos (editar, borrar en una fila). §5: crecen 18%,
   porque el blanco de clic es chico. */
.cfg-ui .cfg-x {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; border: 0; border-radius: 7px;
    background: none; color: var(--faint); cursor: pointer;
    transition: background .14s var(--curva), color .14s var(--curva), transform .18s var(--curva);
}
.cfg-ui .cfg-x:hover { background: var(--navy-050); color: var(--navy); transform: scale(1.18); }
.cfg-ui .cfg-x:active { transform: scale(.94); }
.cfg-ui .cfg-x.del:hover { background: var(--crit-050); color: var(--crit); }

/* ── Campos ───────────────────────────────────────────────────────────────*/
.cfg-ui .cfg-in, .cfg-ui .cfg-txt {
    width: 100%; padding: 7px 11px; border-radius: 8px;
    border: 1px solid var(--hair-strong); background: var(--surface);
    font: inherit; font-size: .8rem; color: var(--ink); outline: 0;
    transition: border-color .14s var(--curva), box-shadow .14s var(--curva);
}
.cfg-ui .cfg-in:focus, .cfg-ui .cfg-txt:focus {
    border-color: var(--navy-500); box-shadow: 0 0 0 3px rgba(21, 74, 148, .13);
}
.cfg-ui .cfg-in:disabled { background: #f5f7fa; color: var(--muted); cursor: default; }
.cfg-ui select.cfg-in { cursor: pointer; }
.cfg-ui .cfg-txt { min-height: 70px; resize: vertical; }
.cfg-ui input.cfg-in.corto { width: 96px; text-align: center; font-weight: 700; }

.cfg-ui .cfg-lbl {
    display: block; font-size: .64rem; text-transform: uppercase; letter-spacing: .08em;
    font-weight: 800; color: var(--faint); margin-bottom: 5px;
}
.cfg-ui .cfg-lbl .req { color: var(--crit); }
.cfg-ui .cfg-lbl .opt { color: var(--hair-strong); font-weight: 600; text-transform: none; letter-spacing: 0; }
/* La explicación de un campo va DEBAJO del campo, no adentro del placeholder:
   un placeholder desaparece justo cuando empezás a escribir. */
.cfg-ui .cfg-ayuda { font-size: .7rem; line-height: 1.5; color: var(--faint); margin: 5px 0 0; }
.cfg-ui .cfg-err { font-size: .74rem; font-weight: 600; color: var(--crit); margin: 6px 0 0; }

.cfg-ui .cfg-campos { display: grid; gap: 14px; }
.cfg-ui .cfg-campos.dos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cfg-ui .cfg-campos .ancho { grid-column: 1 / -1; }
.cfg-ui .cfg-fila { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }

/* Buscador: el ícono adentro, y el campo crece hasta un máximo legible. */
.cfg-ui .cfg-search { position: relative; flex: 1; min-width: 200px; max-width: 360px; }
.cfg-ui .cfg-search .material-symbols-outlined {
    position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
    color: var(--faint); pointer-events: none;
}
.cfg-ui .cfg-search .cfg-in { padding-left: 34px; }

/* Interruptor con su explicación al lado (§4). */
.cfg-ui .cfg-switch { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.cfg-ui .cfg-switch input { margin-top: 2px; width: 15px; height: 15px; accent-color: var(--navy); cursor: pointer; }
.cfg-ui .cfg-switch .t { font-size: .8rem; font-weight: 700; color: var(--ink); }
.cfg-ui .cfg-switch .d { font-size: .72rem; color: var(--faint); line-height: 1.5; }

/* ── Barra de filtros / segmento ──────────────────────────────────────────
   §7: dos "secciones" que comparten el render son UN filtro. Internos y
   Externos son la misma tabla, las mismas columnas y las mismas acciones —
   lo único que cambia es un `rol === 4`. Van acá, no en el rail. */
.cfg-ui .cfg-bar {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 12px var(--gutter); border-bottom: 1px solid var(--hair);
}
.cfg-ui .cfg-seg { display: inline-flex; background: var(--canvas); border-radius: 9px; padding: 2px; gap: 2px; }
.cfg-ui .cfg-seg button {
    padding: 5px 13px; border: 0; border-radius: 7px; background: none;
    font: inherit; font-size: .74rem; font-weight: 700; color: var(--muted); cursor: pointer;
    transition: background .14s var(--curva), color .14s var(--curva), box-shadow .14s var(--curva);
}
.cfg-ui .cfg-seg button:hover { color: var(--ink); }
.cfg-ui .cfg-seg button[aria-pressed="true"] {
    background: var(--surface); color: var(--navy); box-shadow: var(--e1);
}

/* ── Tabla ────────────────────────────────────────────────────────────────
   §1.2: el encabezado NO es una franja de color. Fondo blanco y una regla de
   2 px abajo — una banda navy fija arriba de 60 filas que se miran 20 minutos
   es la mayor fuente de fatiga del sistema. */
.cfg-ui .cfg-g { width: 100%; border-collapse: collapse; font-size: .79rem; }
.cfg-ui .cfg-g thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--surface); border-bottom: 2px solid var(--navy-050);
    padding: 9px var(--gutter); text-align: left; white-space: nowrap;
    font-size: .61rem; font-weight: 800; text-transform: uppercase; letter-spacing: .09em;
    color: var(--faint);
}
.cfg-ui .cfg-g tbody td { padding: 9px var(--gutter); border-bottom: 1px solid var(--hair); vertical-align: middle; }
.cfg-ui .cfg-g tbody tr:last-child td { border-bottom: 0; }
.cfg-ui .cfg-g .n { text-align: right; font-variant-numeric: tabular-nums; }
.cfg-ui .cfg-g .c { text-align: center; }
.cfg-ui .cfg-g .mono { font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace; font-size: .74rem; }

/* §5: barra de 3 px al margen. Marca dónde está el cursor sin mover la fila
   —si la fila se desplaza, el ojo pierde la columna que venía leyendo. */
.cfg-ui .cfg-g tbody tr { position: relative; transition: background .12s var(--curva); }
.cfg-ui .cfg-g tbody tr:hover { background: var(--navy-050); }
.cfg-ui .cfg-g tbody tr > td:first-child { box-shadow: inset 3px 0 0 transparent; transition: box-shadow .14s var(--curva); }
.cfg-ui .cfg-g tbody tr:hover > td:first-child { box-shadow: inset 3px 0 0 var(--navy-300); }
/* La fila vigente de un historial de vigencias: no es hover, es estado. */
.cfg-ui .cfg-g tbody tr.vigente > td:first-child { box-shadow: inset 3px 0 0 var(--ok); }
.cfg-ui .cfg-g tbody tr.baja { color: var(--faint); }
.cfg-ui .cfg-g tbody tr.baja > td:first-child { box-shadow: inset 3px 0 0 var(--hair-strong); }

.cfg-ui .cfg-tabla-wrap { overflow: auto; }
/* Una tarjeta que ES la pantalla: la barra de filtros y el encabezado quedan
   quietos y sólo se mueven las filas. `min-height:0` en los dos eslabones o el
   mínimo automático de flex estira la tarjeta y la barra se va de pantalla. */
.cfg-ui .cfg-card.lleno { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.cfg-ui .cfg-card.lleno .cfg-tabla-wrap { flex: 1; min-height: 0; }

/* Un dato ausente es información (§1.4): gris, itálica, y dice qué falta. */
.cfg-ui .vacio { color: var(--faint); font-style: italic; }

.cfg-ui .cfg-empty { padding: 44px 24px; text-align: center; color: var(--faint); }
.cfg-ui .cfg-empty .material-symbols-outlined { font-size: 34px; color: var(--hair-strong); display: block; margin-bottom: 6px; }
.cfg-ui .cfg-empty p { margin: 0; font-size: .8rem; }
.cfg-ui .cfg-empty p + p { font-size: .72rem; margin-top: 4px; }

/* ── Badge de estado ──────────────────────────────────────────────────────
   §1.1: los niveles son ESTADO, nunca categoría. `nav` es "informativo,
   previsto" y `mut` es "neutro, no se esperaba nada" — no son dos colores
   más para repartir entre rubros. */
.cfg-ui .cfg-b {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 8px; border-radius: 999px; border: 1px solid;
    font-size: .66rem; font-weight: 800; letter-spacing: .02em; white-space: nowrap;
}
.cfg-ui .cfg-b.ok  { color: var(--ok);   background: var(--ok-050);   border-color: var(--ok-hair); }
.cfg-ui .cfg-b.wrn { color: var(--warn); background: var(--warn-050); border-color: var(--warn-hair); }
.cfg-ui .cfg-b.neg { color: var(--crit); background: var(--crit-050); border-color: var(--crit-hair); }
.cfg-ui .cfg-b.nav { color: var(--navy); background: var(--navy-050); border-color: #d3e0f2; }
.cfg-ui .cfg-b.mut { color: var(--muted); background: var(--canvas);  border-color: var(--hair-strong); }

/* ── Aviso contextual ─────────────────────────────────────────────────────
   Trazo al margen, no relleno de ancho completo: el aviso tiene que poder
   convivir con el formulario sin robarle la pantalla. */
.cfg-ui .cfg-risk {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 11px 14px; border-radius: 10px;
    border: 1px solid var(--hair); border-left: 3px solid var(--navy-300);
    background: var(--navy-050); font-size: .76rem; line-height: 1.55; color: var(--ink);
}
.cfg-ui .cfg-risk .material-symbols-outlined { flex: 0 0 auto; font-size: 18px; color: var(--navy-500); margin-top: 1px; }
.cfg-ui .cfg-risk p { margin: 0; }
.cfg-ui .cfg-risk.alerta  { border-left-color: var(--warn); background: var(--warn-050); border-color: var(--warn-hair); }
.cfg-ui .cfg-risk.alerta  .material-symbols-outlined { color: var(--warn); }
.cfg-ui .cfg-risk.critico { border-left-color: var(--crit); background: var(--crit-050); border-color: var(--crit-hair); }
.cfg-ui .cfg-risk.critico .material-symbols-outlined { color: var(--crit); }
.cfg-ui .cfg-risk.bien    { border-left-color: var(--ok); background: var(--ok-050); border-color: var(--ok-hair); }
.cfg-ui .cfg-risk.bien    .material-symbols-outlined { color: var(--ok); }

/* ── Cifra destacada ──────────────────────────────────────────────────────
   Para "vigente hoy: 8%" y las tarjetas de estado de los backups. Acento a la
   izquierda, no relleno: el número tiene que ser lo más oscuro de la caja. */
.cfg-ui .cfg-kpis { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.cfg-ui .cfg-kpi {
    background: var(--surface); border: 1px solid var(--hair);
    border-left: 3px solid var(--navy-300); border-radius: 10px; padding: 11px 14px;
}
.cfg-ui .cfg-kpi .k { font-size: .59rem; text-transform: uppercase; letter-spacing: .1em; font-weight: 800; color: var(--faint); }
.cfg-ui .cfg-kpi .v { font-size: 1.32rem; font-weight: 800; line-height: 1.25; margin-top: 2px; font-variant-numeric: tabular-nums; }
.cfg-ui .cfg-kpi .d { font-size: .7rem; font-weight: 600; color: var(--faint); margin-top: 1px; }
.cfg-ui .cfg-kpi.ok  { border-left-color: var(--ok); }
.cfg-ui .cfg-kpi.ok  .v { color: var(--ok); }
.cfg-ui .cfg-kpi.wrn { border-left-color: var(--warn); }
.cfg-ui .cfg-kpi.wrn .v { color: var(--warn); }
.cfg-ui .cfg-kpi.neg { border-left-color: var(--crit); }
.cfg-ui .cfg-kpi.neg .v { color: var(--crit); }

/* ── Tira de resumen ──────────────────────────────────────────────────────
   Arriba de la lista. Le da a los semánticos un lugar donde significar algo
   —«3 sin teléfono»— ANTES de aparecer en las filas. Sin ella, el ámbar y el
   rojo de abajo terminan decorando. Variante `tira`: las cifras se abrazan al
   contenido en vez de estirarse a lo ancho, porque son tres y no doce. */
.cfg-ui .cfg-kpis.tira { display: flex; flex-wrap: wrap; gap: 11px; }
.cfg-ui .cfg-kpis.tira .cfg-kpi { min-width: 138px; }

/* ── Filas de acceso ──────────────────────────────────────────────────────
   La alternativa a la tabla: cada fila es un ACCESO, no un registro. Lo que
   gana el alto extra es el segundo renglón, donde va escrita la consecuencia
   —a qué avisos llega, qué stock ve, desde cuándo no entra— en vez de dejar
   una celda vacía que el lector tiene que saber interpretar.

   El estado va en la franja del margen y NO mueve la fila: si la fila se
   corriera, el ojo perdería la columna que venía leyendo. */
.cfg-ui .cfg-rows { display: flex; flex-direction: column; }
.cfg-ui .cfg-row {
    position: relative; display: flex; align-items: flex-start; gap: 13px;
    padding: 12px var(--gutter); border-bottom: 1px solid var(--hair);
    transition: background .12s var(--curva);
}
.cfg-ui .cfg-row:last-child { border-bottom: 0; }
.cfg-ui .cfg-row:hover { background: var(--navy-050); }
.cfg-ui .cfg-row::before {
    content: ''; position: absolute; left: 0; top: 9px; bottom: 9px; width: 3px;
    border-radius: 0 3px 3px 0; background: var(--ok);
}
.cfg-ui .cfg-row.ojo::before  { background: var(--warn); }
.cfg-ui .cfg-row.baja::before { background: var(--hair-strong); }

/* Iniciales. Son un ancla para el ojo al recorrer, no un adorno: con filas
   altas, la lista sin ellas se lee como un párrafo. */
.cfg-ui .cfg-row .ini {
    width: 33px; height: 33px; border-radius: 50%; flex: 0 0 auto; margin-top: 1px;
    background: var(--navy-050); color: var(--navy);
    display: flex; align-items: center; justify-content: center;
    font-size: .7rem; font-weight: 800; text-transform: uppercase;
}
.cfg-ui .cfg-row.baja .ini { background: var(--canvas); color: var(--muted); }

.cfg-ui .cfg-row .cuerpo { flex: 1; min-width: 0; }
.cfg-ui .cfg-row .l1 { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.cfg-ui .cfg-row .nom { font-size: .89rem; font-weight: 700; }
.cfg-ui .cfg-row.baja .nom { color: var(--muted); }
/* El rol es TEXTO, no una pastilla de color. Antes eran siete colores para
   siete roles —color = categoría, la regla §1.1 al revés— y con todo teñido
   el ámbar de «esto hay que mirarlo» no se distinguía del ámbar de «es
   Producción Interno». El color queda libre para el estado. */
.cfg-ui .cfg-row .rol {
    font-size: .68rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: .07em; color: var(--navy-500);
}
.cfg-ui .cfg-row.baja .rol { color: var(--muted); }
.cfg-ui .cfg-row .log {
    font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
    font-size: .68rem; color: var(--faint);
}
.cfg-ui .cfg-row .l2 {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    font-size: .755rem; color: var(--muted); margin-top: 3px;
}
.cfg-ui .cfg-row .l2 .material-symbols-outlined { font-size: 15px; flex: 0 0 auto; vertical-align: -3px; }
.cfg-ui .cfg-row .l2 b { color: var(--ink); font-weight: 700; }
.cfg-ui .cfg-row .l2.falta { color: var(--warn); font-weight: 600; }
.cfg-ui .cfg-row .l2.falta b { color: var(--warn); }

.cfg-ui .cfg-row .accs { display: flex; gap: 2px; flex: 0 0 auto; margin-top: 2px; }

/* ── Lo que RIGE hoy ──────────────────────────────────────────────────────
   La forma "A" de una regla: la respuesta arriba y grande, con el porqué al
   lado. Va en Períodos, donde la pregunta de todos los días es «¿hasta qué
   fecha no puedo cargar?» y la respuesta sale de combinar DOS reglas. */
.cfg-ui .cfg-rige { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.cfg-ui .cfg-rige .v {
    font-size: 2.2rem; font-weight: 800; line-height: 1; color: var(--navy);
    font-variant-numeric: tabular-nums;
}
.cfg-ui .cfg-rige .d { font-size: .78rem; line-height: 1.6; color: var(--muted); max-width: 52ch; }
.cfg-ui .cfg-rige .d b { color: var(--ink); }

/* El rótulo de quién manda. Cuando dos reglas se combinan y el resultado es el
   máximo de las dos, la pantalla tiene que decir cuál ganó — o esa cuenta la
   termina haciendo el usuario de cabeza, mirando dos paneles separados. */
.cfg-ui .cfg-manda {
    margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 9px; border-radius: 999px; border: 1px solid;
    font-size: .63rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
    color: var(--ok); background: var(--ok-050); border-color: var(--ok-hair);
}
.cfg-ui .cfg-manda.no { color: var(--muted); background: var(--canvas); border-color: var(--hair-strong); }
.cfg-ui .cfg-manda.off { color: var(--faint); background: transparent; border-color: var(--hair); }

/* ── Línea de tiempo de vigencias ─────────────────────────────────────────
   La forma "B": el historial ES la pantalla. Va en Facturación, donde la regla
   existe para que una factura vieja se reimprima igual que el día que se
   emitió — o sea que la pregunta no es «¿qué rige hoy?» sino «¿qué regía
   cuando salió ESTE comprobante?». */
.cfg-ui .cfg-tl { position: relative; padding: 4px var(--gutter) 10px 46px; }
.cfg-ui .cfg-tl::before {
    content: ''; position: absolute; left: 32px; top: 16px; bottom: 22px;
    width: 2px; background: var(--hair);
}
.cfg-ui .cfg-tramo { position: relative; padding: 11px 0; }
.cfg-ui .cfg-tramo::before {
    content: ''; position: absolute; left: -19px; top: 17px;
    width: 11px; height: 11px; border-radius: 50%;
    background: var(--surface); border: 2px solid var(--hair-strong);
}
.cfg-ui .cfg-tramo.vigente::before { background: var(--ok); border-color: var(--ok); }
.cfg-ui .cfg-tramo .l1 { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding-right: 34px; }
.cfg-ui .cfg-tramo .val { font-size: 1.1rem; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.cfg-ui .cfg-tramo.vigente .val { font-size: 1.65rem; color: var(--ok); }
.cfg-ui .cfg-tramo .rango { font-size: .755rem; font-weight: 700; color: var(--muted); }
.cfg-ui .cfg-tramo .l2 { font-size: .73rem; color: var(--faint); margin-top: 2px; padding-right: 34px; }
.cfg-ui .cfg-tramo .l2 b { color: var(--muted); }
/* El primer tramo es SINTÉTICO: no lo registró nadie, cubre hacia atrás todo
   lo anterior al primer cambio para que ninguna reimpresión quede sin valor. */
.cfg-ui .cfg-tramo.origen .val { color: var(--muted); }
.cfg-ui .cfg-tramo .accs { position: absolute; right: 0; top: 13px; }

.cfg-ui .cfg-tl-vacia { padding: 26px var(--gutter) 26px 46px; font-size: .8rem; color: var(--faint); }

/* ── Modal ────────────────────────────────────────────────────────────────
   Cuelga de <body>, así que lleva la clase raíz del módulo EN SU PROPIO root
   (§7). Por eso todas estas reglas son compuestas —`.cfg-ui.cfg-modal`— y no
   descendentes, y por eso el `.hidden` de tokens.css no las alcanza: hace
   falta la línea explícita de abajo. */
.cfg-ui.cfg-modal {
    position: fixed; inset: 0; z-index: 220;
    display: flex; align-items: center; justify-content: center; padding: 18px;
    background: rgba(20, 28, 44, .55);
}
.cfg-ui.cfg-modal.hidden { display: none; }
.cfg-ui.cfg-modal .cfg-modal-panel {
    width: 100%; max-width: 480px; max-height: calc(100vh - 60px);
    display: flex; flex-direction: column;
    background: var(--surface); border-radius: var(--r-card); box-shadow: var(--e3);
    overflow: hidden;
    animation: cfgSube .2s var(--curva);
}
.cfg-ui.cfg-modal .cfg-modal-panel.ancho { max-width: 620px; }
@keyframes cfgSube { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.cfg-ui .cfg-modal-h {
    display: flex; align-items: center; gap: 10px;
    padding: 14px var(--gutter); border-bottom: 1px solid var(--hair); flex-shrink: 0;
}
.cfg-ui .cfg-modal-h h3 { margin: 0; font-size: .92rem; font-weight: 800; color: var(--navy); }
.cfg-ui .cfg-modal-h .cerrar { margin-left: auto; }
.cfg-ui .cfg-modal-b { padding: var(--gutter); overflow-y: auto; flex: 1; min-height: 0; }
.cfg-ui .cfg-modal-f {
    display: flex; gap: 10px; justify-content: flex-end;
    padding: 13px var(--gutter); border-top: 1px solid var(--hair); background: #fafbfd; flex-shrink: 0;
}

/* El ícono de recargar gira 180° (§5): anticipa lo que va a pasar. Va acá y
   no bajo `.cfg-ui` a secas porque los botones de la barra superior viven
   FUERA del scope del módulo — para esos está `.shell-spin` en shell-ui.css. */
.cfg-ui .cfg-spin { animation: cfgGira .9s linear infinite; }
@keyframes cfgGira { to { transform: rotate(360deg); } }

/* ── Movimiento reducido ──────────────────────────────────────────────────
   No se apaga la INFORMACIÓN, se apaga el desplazamiento: los indicadores
   siguen apareciendo, pero de golpe en vez de crecer. */
@media (prefers-reduced-motion: reduce) {
    .cfg-ui .cfg-rail button,
    .cfg-ui .cfg-rail button::before,
    .cfg-ui .cfg-btn, .cfg-ui .cfg-btn .material-symbols-outlined,
    .cfg-ui .cfg-x, .cfg-ui .cfg-g tbody tr > td:first-child { transition-duration: .01ms; }
    .cfg-ui .cfg-rail button:hover, .cfg-ui .cfg-rail button:focus-visible { transform: none; }
    .cfg-ui .cfg-btn:hover { transform: none; }
    .cfg-ui .cfg-btn:hover .material-symbols-outlined { transform: none; }
    .cfg-ui .cfg-x:hover { transform: none; }
    .cfg-ui.cfg-modal .cfg-modal-panel { animation: none; }
    .cfg-ui .cfg-spin { animation-duration: 1.6s; }
}
