/* ==========================================================================
   IACivis — SISTEMA DE ESTILOS
   Spec 32 · v1.0 · 12/08/2026
   --------------------------------------------------------------------------
   FUENTE UNICA DE VERDAD del aspecto del SaaS.

   Regla fundacional:
     Ningun componente escribe valores literales. Todo color, espaciado,
     radio, tamano o sombra se expresa con token. Si hace falta un valor
     que no esta en la escala, se discute anadirlo al catalogo — nunca
     se escribe inline ni en un <style> de plantilla.

   Los tokens de superficie y texto se DERIVAN del tema del tenant
   (--theme-*, inyectados por base.html desde la tabla despachos), de modo
   que un despacho cambia sus colores y el sistema entero responde.
   Los tokens de ESTADO son fijos: un despacho elige su azul corporativo,
   pero el rojo de peligro debe ser rojo en todas partes.

   Ficheros en cuarentena, a vaciar y retirar:
     static/style.css · static/css/iacivis.css · static/css/onboarding.css
     + 47 plantillas con <style> propio
   ========================================================================== */


/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {
    /* --- Superficie y texto: DERIVADOS del tema del tenant --------------- */
    --bg:              var(--theme-bg, #F8FAFC);
    --surface:         var(--theme-card, #FFFFFF);
    --surface-2:       var(--theme-bg, #F8FAFC);
    --border:          var(--theme-card-border, #E2E8F0);
    --border-strong:   var(--theme-card-border, #CBD5E1);
    --text:            var(--theme-text, #0F172A);
    --text-secondary:  var(--theme-text-secondary, #64748B);
    /* ⛔ --text-muted es DECORATIVO: nunca color de texto legible. El porqué,
       medido, en el comentario de `.form-hint` (primera aparición del cambio
       de s123). Para texto secundario, --text-secondary. */
    --text-muted:      var(--theme-text-muted, #94A3B8);
    --accent:          var(--theme-accent, #0EA5E9);
    --accent-hover:    #0284C7;
    --accent-bg:       #F0F9FF;
    --accent-border:   #BAE6FD;

    /* --- Marca IACivis: fija, no depende del tema ------------------------ */
    --brand-blue:      #0EA5E9;
    --brand-green:     #10B981;
    --brand-navy:      #1B3A5C;
    /* s148 · Puerta pública del alta (D-ALTA-07): texto sobre --brand-navy (fijo en los 4 temas:
       la portada pública no tiene tema). Contraste sobre #1B3A5C: 11,63:1 y 7,74:1 (AAA). */
    --on-brand:           #FFFFFF;
    --on-brand-secondary: #C9D4E1;
    /* s148 · mismo valor que --navy de iacivis.css; fondo fijo del navbar (no cambia por tema). */
    --navbar-bg:          #0F172A;

    /* --- Enlace: DERIVADO, porque la marca no se invierte sola ----------- */
    /* La marca de arriba es fija; un enlace no puede serlo. --brand-navy
       sobre el `card` del tema oscuro (#1E293B) da 1,26:1 --- casi invisible,
       y un enlace que no se ve no es un problema de estética. Medidos los
       tres azules de la rampa sky de la marca sobre los DOS fondos oscuros
       (card #1E293B / bg #0F172A): #0EA5E9 da 5,28 y 6,44 --- pasa AA, pero
       es el valor por defecto de --accent, que cada tenant elige, así que el
       enlace dejaría de distinguirse de la marca del despacho; #38BDF8 da
       6,83 y 8,33; #7DD3FC da 8,77 y 10,71, el único que pasa AAA (7:1) en
       los dos. Gana #7DD3FC.
       ⛔ Los enlaces beben de --link y nunca de --brand-navy en crudo ---
       eso último es el pasivo `navy-fijo-en-oscuro` de la sonda de estilos. */
    --link:            var(--brand-navy);

    /* --- Estado: SEMANTICO y FIJO ---------------------------------------- */
    --success:         #10B981;
    --success-bg:      #ECFDF5;
    --success-border:  #A7F3D0;
    --success-text:    #065F46;

    --danger:          #DC2626;
    --danger-bg:       #FEF2F2;
    --danger-border:   #FECACA;
    --danger-text:     #991B1B;

    --warning:         #F59E0B;
    --warning-bg:      #FFFBEB;
    --warning-border:  #FDE68A;
    --warning-text:    #92400E;

    --info:            #0EA5E9;
    --info-bg:         #F0F9FF;
    --info-border:     #BAE6FD;
    --info-text:       #075985;

    /* --- Espaciado: 6 pasos, en px. La geometria NO escala con el zoom --- */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 24px;
    --sp-6: 32px;

    /* --- Radio, en px ---------------------------------------------------- */
    --r-sm:   4px;
    --r-md:   8px;
    --r-lg:  12px;
    --r-full: 999px;

    /* --- Tipografia: en rem, base 16px. El texto SI escala --------------- */
    --fs-xs: 0.6875rem;   /* 11px — meta, timestamps */
    --fs-sm: 0.75rem;     /* 12px — secundario, chips, cabecera de tabla */
    --fs-md: 0.875rem;    /* 14px — cuerpo */
    --fs-lg: 1rem;        /* 16px — titulos de seccion */
    --fs-xl: 1.25rem;     /* 20px — titulos de pagina */

    --fw-normal: 400;
    --fw-medium: 500;
    --fw-bold:   600;

    --lh-tight:  1.25;
    --lh-base:   1.5;

    --font: 'Inter', 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

    /* --- Sombra ---------------------------------------------------------- */
    --sh-sm: 0 1px 2px rgba(0,0,0,.05);
    --sh-md: 0 4px 12px rgba(0,0,0,.08);
    --sh-lg: 0 10px 30px rgba(0,0,0,.15);

    /* --- Transicion ------------------------------------------------------ */
    --t-fast: .12s ease;
    --t-base: .2s ease;

    /* --- Layout ---------------------------------------------------------- */
    --navbar-h:  52px;
    --page-max:  1600px;
    --z-sticky:  10;
    --z-dropdown: 50;
    --z-modal:   100;
}

/* --- Tema oscuro: los fondos de estado se invierten. Los colores de
       trazo NO cambian: un rojo de peligro es rojo en ambos temas. ------- */
body[data-theme="oscuro"] {
    --success-bg:     #064E3B;   --success-border: #065F46;   --success-text: #A7F3D0;
    --danger-bg:      #7F1D1D;   --danger-border:  #991B1B;   --danger-text:  #FECACA;
    --warning-bg:     #78350F;   --warning-border: #92400E;   --warning-text: #FDE68A;
    --info-bg:        #0C4A6E;   --info-border:    #075985;   --info-text:    #BAE6FD;
    --accent-bg:      #0C4A6E;   --accent-border:  #075985;
    --border-strong:  #475569;
    --link:           #7DD3FC;   /* sky-300 · 8,77:1 sobre card, 10,71:1 sobre bg (AAA) */
    --sh-sm: 0 1px 2px rgba(0,0,0,.3);
    --sh-md: 0 4px 12px rgba(0,0,0,.4);
    --sh-lg: 0 10px 30px rgba(0,0,0,.5);
}


/* ==========================================================================
   2. RESET
   ========================================================================== */

.ia *, .ia *::before, .ia *::after { box-sizing: border-box; }

body {
    font-family: var(--font);
    font-size: var(--fs-md);
    line-height: var(--lh-base);
    color: var(--text);
    background: var(--bg);
}

/* Foco visible en TODO lo interactivo. Sin esto, con teclado no se ve
   donde estas. Obligatorio, no opcional. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.hidden { display: none !important; }
/* El ATRIBUTO hidden, no la clase. Sin esta regla lo pisa cualquier clase de
   autor que fije `display` --la del navegador es de la hoja de agente de
   usuario y pierde siempre--, y el elemento se ve pese a llevar el atributo.
   Censado el 31/08/2026: 5 elementos lo sufrian (`.fx-sub`, `.fx-item-error`
   x3 y `.fx-nr-estado`, todos en la ficha de tramite), y el CSS declaraba
   `display` en 102 reglas sin una sola defensa. `!important` es necesario:
   sin el, una clase de igual especificidad vuelve a ganar.
   No afecta a `.modal`, cuya regla base ya es `display:none`. */
[hidden] { display: none !important; }
.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}


/* ==========================================================================
   3. ATOMOS
   ========================================================================== */

/* --- Boton ------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-4);
    border: 1px solid transparent;
    border-radius: var(--r-md);
    font-family: var(--font);
    font-size: var(--fs-md);
    font-weight: var(--fw-medium);
    line-height: var(--lh-tight);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
    white-space: nowrap;
}
.btn:disabled, .btn[disabled], .btn.is-loading {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
}
/* `.ia-btn` vive en `iacivis.css` (cuarentena) y NO tiene estado deshabilitado:
   un boton disabled se veia igual que uno pulsable. Es de TODA la app --lo usan
   `plantillas.html` y la ficha--, no de una pieza. Sin `pointer-events:none` a
   proposito: eso quita el elemento del hit-testing y con el se pierde el propio
   `cursor:not-allowed`; un <button disabled> ya no dispara clic por si solo. */
.ia-btn[disabled] { opacity: .5; cursor: not-allowed; }

/* --- Botones `ia-btn` -----------------------------------------------------
   Migradas de `iacivis.css` (cuarentena) en s128; las de alli son duplicado
   a retirar.

   ia.css carga la ULTIMA (base.html:11), de modo que estas reglas GANAN a
   las de iacivis.css a igual especificidad: cualquier divergencia de un
   pixel cambia la ficha del 886 y el wizard, que ya las usan. Por eso los
   paddings, el `gap` y el 13px del `-sm` van LITERALES: no hay token que
   valga esos valores (--sp-* es 4/8/12/16; --fs-* es 11/12/14/16px) y
   tokenizarlos MOVERIA el pintado. Lo que si tokeniza sin mover un pixel
   son color, radio y transicion, que coinciden al valor:
       --radius-sm (8px)   == --r-md          --transition (.2s ease) == --t-base
       --ia-blue (#0EA5E9) == --accent        --ia-blue-hover (#0284C7) == --accent-hover
       --border (#E2E8F0)  == --border        --text-primary (#0F172A)  == --text
       font-size 14px      == --fs-md (0.875rem con root 16px)

   ⚠ La base `.ia-btn` NO estaba en el dictado y se anade aqui: sin ella,
   retirar `iacivis.css` dejaria estos botones sin `display:inline-flex`,
   sin padding y sin radio -- es decir, el comentario de arriba («duplicado
   a retirar») no seria cierto. Decision de Albert; en sandbox, sin aplicar.

   Los CINCO estados del color van juntos, sin asimetrias: «Abrir DEHU» es
   un <a>, no un <button>, y un <a> sin color fijado en :visited hereda el
   del navegador --hoy `--link` (s123)-- y cambia de color al visitarlo.
   Es el invariante de s124, aqui con sujeto.                              */
.ia-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;                       /* sin token: --sp-1 es 4px, --sp-2 es 8px */
    font-family: inherit;
    font-size: var(--fs-md);
    font-weight: var(--fw-medium);
    padding: 9px 18px;              /* sin token: valores propios del boton  */
    border-radius: var(--r-md);
    border: none;
    cursor: pointer;
    transition: var(--t-base);
    text-decoration: none;
}
.ia-btn:link, .ia-btn:visited, .ia-btn:hover, .ia-btn:focus { text-decoration: none; }

.ia-btn-primary,
.ia-btn-primary:link, .ia-btn-primary:visited { background: var(--accent); color: #fff; }
.ia-btn-primary:hover, .ia-btn-primary:focus  { background: var(--accent-hover); color: #fff; }

.ia-btn-outline,
.ia-btn-outline:link, .ia-btn-outline:visited {
    background: transparent;
    border: 0.5px solid var(--border);
    color: var(--text);
}
.ia-btn-outline:hover, .ia-btn-outline:focus { border-color: var(--accent); color: var(--accent); }

.ia-btn-sm { font-size: 13px; padding: 7px 14px; }   /* 13px/7/14: sin token */

/* --- Avisos de sede (s128): celdas que se pisaban a 1920px ---------------
   Las dos celdas anchas --EXPEDIENTE y ACCESO-- llevaban su flex en linea,
   sin `nowrap` y sin ancho minimo del input, de modo que el boton caia bajo
   el campo y la tabla desbordaba. El ancho lo absorbe ahora el scroll de
   `.table-wrap`, no la fila.                                              */
.fx-aviso-asignar,
.fx-aviso-acceso {
    display: flex;
    gap: var(--sp-2);
    align-items: center;
    white-space: nowrap;
}
/* 11rem, no los 16 de s128-a: dentro de la celda aquel minimo empujaba al
   boton fuera del ancho disponible y `td{overflow:hidden}` lo recortaba. */
.fx-aviso-asignar .form-input,
.fx-aviso-acceso  .form-input { min-width: 11rem; flex: 1 1 auto; }
.fx-aviso-acceso  input[type="date"].form-input {
    flex: 0 0 auto;
    width: 9.5rem;
    min-width: 0;               /* gana al minimo compartido de arriba */
}
.fx-aviso-asignar .ia-btn,
.fx-aviso-acceso  .ia-btn { flex: 0 0 auto; }
/* El hint de `sin_casar` en UNA linea, junto a su enlace. */
.fx-aviso-acceso .form-hint { white-space: nowrap; }

/* --- Avisos de sede (s128-b): que la tabla QUEPA -------------------------
   s128-a metio la tabla en `.table-wrap` y dejo de desbordar la pagina, pero
   la celda seguia sin caber: el contenedor de s124 es `overflow:hidden` +
   `table-layout:fixed` + `td{overflow:hidden}`, de modo que el ancho se
   reparte a partes iguales entre las 7 columnas y lo que sobra NO se
   desplaza, SE RECORTA. Medido en Chrome: el <form> de busqueda ocupaba
   197 px con un input que pedia 256, y el boton «Asignar» quedaba cortado.

   Anchos medidos con esto puesto, a zoom 100 %:
       Vence 112 · Organismo 192 · Concepto 224 · Titular 192 · Vias 147
       · EXPEDIENTE ~300 · ACCESO ~330   =   1550 px, y la pantalla son 1920.
   Por debajo de ese ancho, `is-scroll` DESPLAZA en vez de recortar.

   `is-scroll` es un MODIFICADOR, no un cambio de `.table-wrap`: el recorte de
   s124 es correcto para las tablas que solo llevan texto --- ahi el ellipsis
   con `title` es lo que se quiere. Aqui hay controles, y un boton a medias no
   se puede pulsar.                                                        */
.table-wrap.is-scroll { overflow-x: auto; }

.table.fx-aviso-tabla { table-layout: auto; }

/* Las de texto SI se recortan --- su valor completo va en el `title` del <td>,
   que es la condicion que pone el propio comentario de `.table td`. */
.table.fx-aviso-tabla td.fx-td-organismo { max-width: 12rem; }
.table.fx-aviso-tabla td.fx-td-concepto  { max-width: 14rem; }
.table.fx-aviso-tabla td.fx-td-titular   { max-width: 12rem; }

/* Las de accion NO: llevan controles, y `overflow:hidden` recorta botones. */
.table.fx-aviso-tabla td.fx-td-accion { overflow: visible; }
.table.fx-aviso-tabla td.fx-td-accion > .form-hint { display: block; }

/* Un candidato trae numero de expediente Y nombre completo: puede ser largo.
   Se recorta el ROTULO con ellipsis --- el valor entero sigue en su `title`. */
.fx-aviso-candidato { display: block; max-width: 18rem; }
.fx-aviso-candidato .ia-btn {
    display: block;
    max-width: 18rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* El gap con el bloque de candidatos, que estaba en un `style` de la etiqueta. */
.fx-aviso-asignar { margin-top: var(--sp-1); }

/* ⚠ NO estaba en el dictado, y sin ella la sonda 18 no puede cumplirse: pide
   CERO `style=` en los <form>, y el de filtros de la cabecera es un <form>.
   Con esta clase quedan los DOS inline que el dictado da por buenos --- el
   <div> del titulo y el `width:auto` del <select> --- y ni uno en un form. */
.fx-aviso-filtros {
    display: flex;
    gap: var(--sp-2);
    flex-wrap: wrap;
    align-items: center;
}

/* --- Buscador incremental (s128-c) -------------------------------------
   Sustituye al <datalist>, que no sabe buscar por la etiqueta de la opcion
   --- solo por su `value` ---, de modo que no se puede teclear un nombre y
   enviar un id. La lista se posiciona respecto al contenedor del campo, y
   por eso `.fx-typeahead` lleva `position:relative`.

   El z-index va por encima de la tabla: la lista de una fila tiene que poder
   taparse sobre las de abajo. Funciona porque `td.fx-td-accion` dejo de
   recortar en s128-b --- con `overflow:hidden` la lista se cortaria dentro
   de la celda por mucho z-index que se le pusiera.                       */
.fx-typeahead { position: relative; flex: 1 1 auto; min-width: 11rem; }

.fx-typeahead-lista {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: var(--z-dropdown);
    margin: var(--sp-1) 0 0;
    padding: 0;
    list-style: none;
    max-height: 17rem;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: var(--sh-md);
}
.fx-typeahead-item {
    padding: var(--sp-2) var(--sp-3);
    font-size: var(--fs-md);
    color: var(--text);
    cursor: pointer;
    white-space: normal;        /* el nombre completo cabe en dos lineas */
}
.fx-typeahead-item:hover { background: var(--surface-2); }
.fx-typeahead-item[aria-selected="true"] { background: var(--accent-bg); }
.fx-typeahead-num {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    /* `--text-secondary` NO: cae a 4,12 y 4,34 en dos de los cuatro temas, y
       el numero de expediente es CONTENIDO, no decoracion (regla de s123).
       Lo que lo distingue del nombre es la fuente mono y el tamano. */
    color: var(--text);
    margin-right: var(--sp-2);
}

/* En fila el enlace es «DEHU ↗» y va mas apretado que un boton de texto. */
.fx-dehu { padding: 7px 9px; }

/* Un .btn que es <a> hereda el color de enlace del navegador si no se fija
   en los cuatro estados. Los cuatro juntos, sin asimetrias. */
.btn:link, .btn:visited, .btn:hover, .btn:focus { text-decoration: none; }

.btn-primary, .btn-primary:link, .btn-primary:visited,
.btn-primary:hover, .btn-primary:focus   { color: #fff; }
.btn-primary            { background: var(--accent); }
.btn-primary:hover      { background: var(--accent-hover); }

.btn-danger, .btn-danger:link, .btn-danger:visited,
.btn-danger:hover, .btn-danger:focus     { color: #fff; }

.btn-outline, .btn-outline:link, .btn-outline:visited,
.btn-outline:hover, .btn-outline:focus   { color: var(--text); }

.btn-ghost, .btn-ghost:link, .btn-ghost:visited,
.btn-ghost:focus        { color: var(--text-secondary); }
.btn-ghost:hover        { color: var(--text); }

.btn-outline            { background: transparent; border-color: var(--border-strong); }
.btn-outline:hover      { background: var(--surface-2); }

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

.btn-ghost              { background: transparent; color: var(--text-secondary); }
.btn-ghost:hover        { background: var(--surface-2); color: var(--text); }

.btn-icon               { padding: var(--sp-2); background: transparent; color: var(--text-secondary); border-color: var(--border-strong); }
.btn-icon:hover         { background: var(--surface-2); color: var(--text); }

.btn-sm                 { padding: var(--sp-1) var(--sp-3); font-size: var(--fs-sm); }
.btn-lg                 { padding: var(--sp-3) var(--sp-5); font-size: var(--fs-lg); }
.btn-block              { display: flex; width: 100%; }


/* --- Formulario -------------------------------------------------------- */

.form-group             { margin-bottom: var(--sp-3); }
.form-group-wide        { grid-column: 1 / -1; }

.form-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--sp-3);
}

.form-label {
    display: block;
    margin-bottom: var(--sp-1);
    font-size: var(--fs-sm);
    color: var(--text-secondary);
}
.form-label-req::after  { content: " *"; color: var(--danger); }

.form-input, .form-select, .form-textarea {
    width: 100%;
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    background: var(--surface);
    color: var(--text);
    font-family: var(--font);
    font-size: var(--fs-md);
    transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.form-input:focus, .form-select:focus, .form-textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-bg);
}
.form-input:disabled, .form-select:disabled, .form-textarea:disabled {
    background: var(--surface-2);
    color: var(--text-muted);
    cursor: not-allowed;
}
.form-input.is-error, .form-select.is-error, .form-textarea.is-error {
    border-color: var(--danger);
}
.form-textarea          { min-height: 72px; resize: vertical; }

/* Especificidad (s114, B1): iacivis.css (cuarentena) declara
   `textarea, input[type="text"], input[type="email"], input[type="number"], select { font-size: 16px }`
   y el selector de atributo gana a `.form-input` en los <input>. Se iguala la especificidad
   aquí (elemento + clase) para que la familia entera pinte a --fs-md. ia.css carga después. */
input.form-input, select.form-select, textarea.form-textarea { font-size: var(--fs-md); }

/* Placeholder de la familia: hasta s114 no había regla y salía el gris del navegador. */
.form-input::placeholder, .form-textarea::placeholder { color: var(--text-muted); opacity: 1; }

/* ★★ REGLA DEL TOKEN GRIS (canonizada el 01/09/2026, s123):
   `--text-muted` ES DECORATIVO --- TEXTO LEGIBLE, NUNCA.

   Medido con los valores REALES de TEMAS (app.py), no con los fallbacks:

       --text-muted / --surface      2,56:1 (claro)   3,07:1 (oscuro)   ✗
       --text-muted / --surface-2    2,45:1 (claro)   3,75:1 (oscuro)   ✗
       --text-secondary / --surface  4,76:1 (claro)   5,71:1 (oscuro)   ✓

   El mínimo de WCAG AA para texto es 4,5:1, y NINGUNO de los usos alcanzaba
   el umbral de «texto grande» (18,66px, o 14px en negrita) que permitiría
   bajar a 3:1 --- eran de 11 y 14px, varios además en itálica. Es decir: no
   había excepción que invocar, incumplían los dos temas a la vez.

   ★ Y la causa de que incumplan LOS DOS es que `--text-muted` y
   `--text-secondary` INTERCAMBIAN valor entre claro y oscuro (#94A3B8 ↔
   #64748B): el gris flojo lo es en ambos, solo que contra el fondo contrario.
   Por eso no se arregla «aclarando el oscuro» --- se arregla dejando de usar
   ese token para texto, que es lo que hace este cambio en 20 reglas.

   Lo que SÍ conserva `--text-muted`, y con motivo:
     · `::placeholder`          -- no es contenido, es una pista que desaparece
     · `.form-*:disabled`       -- WCAG 1.4.3 exime EXPRESAMENTE el texto de un
                                   componente inactivo: un control deshabilitado
                                   tiene que PARECER deshabilitado
     · `.metric-dot` (background) -- no es texto

   TEMAS no se toca: la paleta del tenant es correcta; lo que estaba mal era
   qué token se pedía para cada cosa. */
.form-hint              { margin-top: var(--sp-1); font-size: var(--fs-xs); color: var(--text-secondary); }
.form-error             { margin-top: var(--sp-1); font-size: var(--fs-xs); color: var(--danger-text); }

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

.form-section {
    padding-top: var(--sp-4);
    margin-top: var(--sp-4);
    border-top: 1px solid var(--border);
}
.form-section:first-child { padding-top: 0; margin-top: 0; border-top: 0; }


/* --- Badge: ESTADO de la cosa. Rectangular. ---------------------------- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: 3px var(--sp-2);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    background: var(--surface-2);
    color: var(--text-secondary);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    line-height: var(--lh-tight);
    white-space: nowrap;
}
.badge-success  { background: var(--success-bg); border-color: var(--success-border); color: var(--success-text); }
.badge-danger   { background: var(--danger-bg);  border-color: var(--danger-border);  color: var(--danger-text); }
.badge-warning  { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-text); }
.badge-info     { background: var(--info-bg);    border-color: var(--info-border);    color: var(--info-text); }
.badge-neutral  { background: var(--surface-2);  border-color: var(--border);         color: var(--text-secondary); }


/* --- Chip: ETIQUETA o VINCULO. Pildora. -------------------------------- */

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: 3px var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--r-full);
    background: var(--surface-2);
    color: var(--text-secondary);
    font-size: var(--fs-sm);
    line-height: var(--lh-tight);
    text-decoration: none;
    white-space: nowrap;
}
.chip-link      { background: var(--brand-navy); border-color: var(--brand-navy); color: #fff; }
.chip-link:hover{ filter: brightness(1.15); }
.chip-warning   { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-text); }
.chip-remove    { cursor: pointer; opacity: .6; }
.chip-remove:hover { opacity: 1; }


/* --- Alerta ------------------------------------------------------------ */

.alert {
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--surface-2);
    color: var(--text);
    font-size: var(--fs-md);
    margin-bottom: var(--sp-4);
}
.alert-success  { background: var(--success-bg); border-color: var(--success-border); color: var(--success-text); }
.alert-danger   { background: var(--danger-bg);  border-color: var(--danger-border);  color: var(--danger-text); }
.alert-warning  { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-text); }
.alert-info     { background: var(--info-bg);    border-color: var(--info-border);    color: var(--info-text); }


/* --- Spinner ----------------------------------------------------------- */

.spinner {
    display: inline-block;
    width: 14px; height: 14px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: var(--r-full);
    animation: ia-spin .6s linear infinite;
}
@keyframes ia-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .spinner { animation-duration: 2s; }
    * { transition-duration: .01ms !important; }
}


/* --- Avatar ------------------------------------------------------------ */

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px; height: 28px;
    border-radius: var(--r-full);
    background: var(--accent);
    color: #fff;
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
}


/* ==========================================================================
   4. CONTENEDORES
   ========================================================================== */

/* --- Card: superficie elevada CON borde. DELIMITA contenido. ----------- */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: var(--sp-4) var(--sp-5);
}
.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    margin-bottom: var(--sp-3);
}
.card-title  { font-size: var(--fs-lg); font-weight: var(--fw-medium); color: var(--text); }
/* Pares dt/dd dentro de tarjeta. Sustituye a las reglas de descendiente
   .detail-card dt/dd de style.css, que son invisibles al cambiar la clase
   del padre: el <dl> cae a los estilos del navegador sin que nada avise.
   Distinto de .ficha-dato, cuyos dd truncan a una linea por venir del grid
   de 6 columnas — aqui la direccion debe poder envolver. */
.card-dl                    { font-size: var(--fs-md); }
.card-dl dt                 { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-secondary); margin-top: var(--sp-3); }
.card-dl dt:first-of-type   { margin-top: 0; }
.card-dl dd                 { margin: 2px 0 0; color: var(--text); line-height: var(--lh-base); }

.card-accent-danger  { border-left: 3px solid var(--danger); }
.card-accent-warning { border-left: 3px solid var(--warning); }
.card-accent-success { border-left: 3px solid var(--success); }


/* --- Panel: fondo suave SIN borde. AGRUPA sin separar. ----------------- */

.panel {
    background: var(--surface-2);
    border-radius: var(--r-md);
    padding: var(--sp-4) var(--sp-5);
}


/* --- Modal ------------------------------------------------------------- */

.modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: none;
    align-items: center;
    justify-content: center;
    padding: var(--sp-4);
    background: rgba(0,0,0,.45);
}
.modal.open      { display: flex; }
.modal-content {
    width: 100%;
    max-width: 480px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-lg);
}
.modal-lg        { max-width: 720px; }
/* Dos columnas caben en 720 px muy justas: el modal de «+ Nuevo tramite»
   (T5-4) pone el selector a la izquierda y lo que el catalogo sabe a la
   derecha, con un checklist de hasta 20 items debajo. */
.modal-xl        { max-width: 980px; }
.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: var(--sp-4) var(--sp-5);
    border-bottom: 1px solid var(--border);
}
.modal-header h2 { font-size: var(--fs-lg); font-weight: var(--fw-medium); }
.modal-body      { padding: var(--sp-4) var(--sp-5); overflow-y: auto; }
.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--sp-2);
    padding: var(--sp-4) var(--sp-5);
    border-top: 1px solid var(--border);
}
.modal-close {
    background: transparent;
    border: 0;
    color: var(--text-secondary);
    font-size: var(--fs-xl);
    line-height: 1;
    cursor: pointer;
    padding: var(--sp-1);
}
.modal-close:hover { color: var(--text); }


/* --- Tabla ------------------------------------------------------------- */

.table-wrap {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
}

/* s124-bis · style.css aun pinta `.table {background: var(--white)}` y
   `.table thead {background: var(--gray-100)}` sobre la MISMA clase: el
   blanco legacy sobrevivia DENTRO del .table-wrap oscuro. Mientras
   style.css viva, ia.css debe declarar estos fondos, no confiar en su
   ausencia. Certificado en Chrome (claro + oscuro) antes de aplicar. */
.table { background: transparent; }
.table thead { background: var(--surface-2); }

/* s124-bis · h1 bebia de --navy (style.css) -> invisible en oscuro.
   En claro var(--text) es visualmente identico al navy. */
h1 { color: var(--text); }

/* s125-bis · hermanas del h1 de s124-bis: h2 bebia de --navy y h3 de
   --gray-700 (style.css) -> invisibles/apagados sobre tarjeta oscura.
   Certificado en Chrome (titulo del modal de presentacion) antes de aplicar. */
h2 { color: var(--text); }
h3 { color: var(--text); }
.table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}
.table th {
    padding: var(--sp-3);
    text-align: left;
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: .03em;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.table th.is-sorted { color: var(--accent); }
.table td {
    padding: var(--sp-3);
    font-size: var(--fs-md);
    color: var(--text);
    border-bottom: 1px solid var(--border);
    /* Un valor largo se corta en vez de romper el layout. El valor
       completo DEBE ir en el title del <td> o el usuario no lo lee. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.table tr:last-child td { border-bottom: 0; }
.table tbody tr:hover    { background: var(--surface-2); }
.table .td-num           { text-align: right; font-variant-numeric: tabular-nums; }
.table .td-center        { text-align: center; }

/* Enlaces de celda: azules, sin subrayado. Son la via de entrada a la ficha
   y deben distinguirse, pero el subrayado en 50 filas satura. */
/* :not(.btn) — sin esto, .table td a (0,1,2) gana a .btn-outline (0,1,0) y
   pinta de azul los botones que viven dentro de una celda. La correccion va
   aqui, no subiendo especificidad componente por componente. */
.table td a:not(.btn)        { color: var(--accent); text-decoration: none; }
.table td a:not(.btn):hover  { text-decoration: underline; }

/* Enlaces de cabecera (orden por columna): heredan el gris de la cabecera.
   Sin esto salen azules y subrayados, desentonando con el resto. */
.table th a              { color: inherit; text-decoration: none; }
.table th a:hover        { color: var(--accent); }


/* --- Pestanas ---------------------------------------------------------- */

.tabs {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--border);
    margin-bottom: var(--sp-4);
    overflow-x: auto;
}
.tab {
    padding: var(--sp-3) var(--sp-4);
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    color: var(--text-secondary);
    font-family: var(--font);
    font-size: var(--fs-md);
    font-weight: var(--fw-medium);
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
}
.tab:hover        { color: var(--text); }
.tab.active       { color: var(--accent); border-bottom-color: var(--accent); }
.tab-count {
    margin-left: var(--sp-1);
    padding: 1px var(--sp-2);
    border-radius: var(--r-full);
    background: var(--surface-2);
    color: var(--text-secondary);
    font-size: var(--fs-xs);
}
.tab-count.is-alert { background: var(--danger-bg); color: var(--danger-text); }


/* --- Dropdown ---------------------------------------------------------- */

.dropdown          { position: relative; display: inline-block; }
.dropdown-menu {
    position: absolute;
    right: 0;
    top: calc(100% + var(--sp-1));
    z-index: var(--z-dropdown);
    min-width: 180px;
    display: none;
    padding: var(--sp-1);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: var(--sh-md);
}
.dropdown.open .dropdown-menu { display: block; }
.dropdown-item {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    width: 100%;
    padding: var(--sp-2) var(--sp-3);
    border: 0;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text);
    font-family: var(--font);
    font-size: var(--fs-md);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.dropdown-item:hover        { background: var(--surface-2); }
.dropdown-item-danger       { color: var(--danger-text); }
.dropdown-item-danger:hover { background: var(--danger-bg); }
.dropdown-divider           { height: 1px; margin: var(--sp-1) 0; background: var(--border); }

/* Separador dentro del dropdown del navbar (iacivis.css no lo tiene). */
.ia-nav-dropdown-divider    { height: 1px; margin: var(--sp-1) 0; background: var(--border); }


/* ==========================================================================
   5. LAYOUT
   ========================================================================== */

.page {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: var(--sp-5);
}

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: var(--sp-4);
}
.page-title    { font-size: var(--fs-xl); font-weight: var(--fw-medium); color: var(--text); }
.page-count    { font-size: var(--fs-sm); color: var(--text-secondary); }
.page-actions  { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

.breadcrumb {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin-bottom: var(--sp-3);
    font-size: var(--fs-sm);
    color: var(--text-secondary);
}
.breadcrumb a          { color: var(--accent); text-decoration: none; }
.breadcrumb a:hover    { text-decoration: underline; }
.breadcrumb-sep::before{ content: "/"; color: var(--text-secondary); }

.toolbar {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin-bottom: var(--sp-3);
}
.toolbar-grow  { flex: 1; min-width: 180px; }
/* Los controles de la toolbar son secundarios respecto al contenido:
   texto menor y menos alto para que no compitan con la tabla. */
.toolbar .form-input,
.toolbar .form-select {
    padding: var(--sp-1) var(--sp-3);
    font-size: var(--fs-sm);
}
.toolbar label { font-size: var(--fs-sm); color: var(--text-secondary); }

.grid    { display: grid; gap: var(--sp-3); }
.grid-2  { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid-3  { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.grid-6  { grid-template-columns: repeat(6, 1fr); }

.stack   { display: flex; flex-direction: column; gap: var(--sp-3); }
.row     { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
/* Titulo + contador: con 20px y 12px el centrado optico falla, hay que
   alinear por linea base. */
.row-baseline { display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap; }
.row-end { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }

.empty-state {
    padding: var(--sp-6);
    text-align: center;
    color: var(--text-secondary);
    font-size: var(--fs-md);
}


/* ==========================================================================
   6. PATRONES
   ========================================================================== */

/* --- Ficha de detalle -------------------------------------------------- */

.ficha-header {
    position: sticky;
    top: var(--navbar-h);
    z-index: var(--z-sticky);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: var(--sp-3) var(--sp-4);
    margin-bottom: var(--sp-4);
}
.ficha-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: var(--sp-3);
}
.ficha-title-left {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}
.ficha-id    { font-size: var(--fs-sm); color: var(--text-secondary); font-family: var(--font-mono); }
.ficha-name  { font-size: var(--fs-xl); font-weight: var(--fw-medium); color: var(--text); }

.ficha-datos {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: var(--sp-3);
}
.ficha-dato       { min-width: 0; }
.ficha-dato dt {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-secondary);
    margin-bottom: 2px;
}
.ficha-dato dd {
    margin: 0;
    font-size: var(--fs-md);
    font-weight: var(--fw-medium);
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ficha-expand {
    display: none;
    margin-top: var(--sp-3);
    padding-top: var(--sp-3);
    border-top: 1px solid var(--border);
}
.ficha-expand.open { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--sp-3); }
.ficha-expand-btn {
    margin-top: var(--sp-3);
    padding-top: var(--sp-2);
    border-top: 1px solid var(--border);
    font-size: var(--fs-sm);
    color: var(--accent);
    background: transparent;
    border-width: 1px 0 0 0;
    cursor: pointer;
    width: 100%;
    text-align: left;
}
.ficha-estados { display: flex; gap: var(--sp-1); flex-wrap: wrap; margin-bottom: var(--sp-4); }


/* --- Pasos de formulario ----------------------------------------------- */

.steps {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: var(--sp-5);
}
.step        { display: flex; align-items: center; gap: var(--sp-2); padding: 0 var(--sp-3); }
.step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px; height: 22px;
    border: 1px solid var(--border-strong);
    border-radius: var(--r-full);
    background: var(--surface);
    color: var(--text-secondary);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
}
.step-label  { font-size: var(--fs-sm); color: var(--text-secondary); }
.step.is-done .step-num    { background: var(--success); border-color: var(--success); color: #fff; }
.step.is-done .step-label  { color: var(--text-secondary); }
.step.is-active .step-num  { background: var(--accent); border-color: var(--accent); color: #fff; }
.step.is-active .step-label{ color: var(--text); font-weight: var(--fw-medium); }
.step-line   { flex: 1; min-width: 16px; height: 1px; background: var(--border); }
.step.is-done + .step-line { background: var(--border-strong); }


/* --- Metrica de panel --------------------------------------------------- */

.metric        { }
.metric-label  { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--text); }
.metric-dot    { width: 8px; height: 8px; border-radius: var(--r-full); background: var(--text-muted); }
.metric-dot-danger  { background: var(--danger); }
.metric-dot-warning { background: var(--warning); }
.metric-dot-success { background: var(--success); }
.metric-value  { font-size: 28px; font-weight: var(--fw-medium); color: var(--text); line-height: var(--lh-tight); }
.metric-value-danger  { color: var(--danger); }
.metric-value-warning { color: var(--warning-text); }
.metric-unit   { font-size: var(--fs-sm); color: var(--text-secondary); }
.metric-sub    { font-size: var(--fs-sm); color: var(--text-secondary); }


/* ==========================================================================
   7. RESPONSIVE
   ========================================================================== */

/* --- Navbar adaptativo -------------------------------------------------
   El navbar necesita ~1400px con todos sus elementos. iacivis.css solo
   lo reorganiza a 768px, de modo que entre 769 y 1400 desborda y empuja
   el ancho del body: eso es lo que producia scroll horizontal.
   Se recupera espacio por orden de prescindibilidad: primero lo
   informativo (nombre, badges), despues los enlaces menos usados.
   El avatar se queda: ya muestra las iniciales del usuario. --- */

@media (max-width: 1280px) {
    .ia-nav-username { display: none; }
}
@media (max-width: 1150px) {
    .ia-nav-badge-admin { display: none; }
    .ia-navbar-inner { gap: var(--sp-3); }
}
@media (max-width: 1024px) {
    .ficha-datos, .ficha-expand.open { grid-template-columns: repeat(3, 1fr); }
    .grid-6 { grid-template-columns: repeat(3, 1fr); }
    .ia-nav-link { padding-left: 10px; padding-right: 10px; }
}

@media (max-width: 640px) {
    .page { padding: var(--sp-3); }
    .ficha-datos, .ficha-expand.open { grid-template-columns: repeat(2, 1fr); }
    .grid-6 { grid-template-columns: repeat(2, 1fr); }
    .page-header, .ficha-title-row { flex-direction: column; align-items: flex-start; }
    .modal-content { max-width: 100%; }
}


/* --- Pantallas de autenticacion sueltas -------------------------------
   Las que NO heredan base.html (cambiar_contrasena). Centran una .card
   estrecha en el viewport. Sin prefijo ia- porque son contenido, no cromo
   de la aplicacion (decision de alcance de s96). */
.auth-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-4);
}
.auth-card { width: 100%; max-width: 420px; }
.auth-head { text-align: center; margin-bottom: var(--sp-4); }
.auth-head h1 { font-size: var(--fs-lg); font-weight: var(--fw-medium); color: var(--text); margin: 0; }
.auth-head p  { font-size: var(--fs-sm); color: var(--text-secondary); margin: 4px 0 0; }


/* --- s148 · Puerta pública del alta (D-ALTA-07) ------------------------
   Portada pública de dos columnas, franja de aviso de la app y entrada de
   menú bloqueada. Solo tokens (--on-brand* en :root, bloque Marca IACivis). */

/* --- Portada pública de dos columnas: argumento + formulario ----------- */
.auth-split {
    min-height: 100vh;
    display: grid;
    grid-template-columns: minmax(320px, 2fr) 3fr;
    background: var(--bg);
}
.auth-aside {
    background: var(--brand-navy);
    color: var(--on-brand);
    padding: var(--sp-6);
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
}
.auth-aside-brand { font-size: var(--fs-xl); font-weight: var(--fw-bold); }
.auth-aside h1 {
    margin: 0;
    color: var(--on-brand);
    font-size: var(--fs-xl);
    font-weight: var(--fw-bold);
    line-height: var(--lh-tight);
}
.auth-aside p        { margin: 0; color: var(--on-brand-secondary); }
.auth-aside a        { color: var(--on-brand); }
.auth-aside-steps    { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.auth-aside-steps li { display: flex; gap: var(--sp-3); align-items: flex-start; color: var(--on-brand-secondary); }
.auth-aside-steps strong { color: var(--on-brand); font-weight: var(--fw-medium); }
.auth-aside-steps .step-num { flex-shrink: 0; }
.auth-aside-foot     { margin-top: auto; font-size: var(--fs-sm); color: var(--on-brand-secondary); }

.auth-main            { display: flex; align-items: flex-start; justify-content: center; padding: var(--sp-6); }
.auth-main .auth-card { max-width: 640px; }

@media (max-width: 768px) {
    .auth-split { grid-template-columns: 1fr; }
    .auth-main  { order: -1; padding: var(--sp-4); }
}

/* --- Fondo del navbar (cromo: prefijo ia-). Mismo valor que pinta iacivis.css (cuarentena): sin cambio
       visual; da a la sonda de estilos un fondo resoluble desde ia.css para .ia-nav-link. */
.ia-navbar { background: var(--navbar-bg); }

/* --- Franja de aviso de toda la app, bajo el navbar (cromo: prefijo ia-) */
.ia-banner {
    display: flex;
    gap: var(--sp-3);
    align-items: flex-start;
    padding: var(--sp-3) var(--sp-5);
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    font-size: var(--fs-md);
}
.ia-banner strong   { font-weight: var(--fw-bold); }
.ia-banner svg      { flex-shrink: 0; margin-top: 2px; }
.ia-banner-warning  { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-text); }

/* --- Entrada de menú bloqueada (estado, sin color propio) -------------- */
.ia-nav-link.is-locked {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    color: var(--on-brand-secondary);
    cursor: not-allowed;
}


/* --- Tarjetas de opcion (wizard) ---------------------------------------
   Eleccion visual entre pocas alternativas, cuando la lista de radios no
   basta porque cada opcion lleva su explicacion debajo. El estado verdadero
   es el <input type="radio"> que va DENTRO de cada tarjeta: .is-selected es
   solo la piel, y por eso la tarjeta sigue diciendo la verdad aunque el JS
   no llegue a pintarla. Estrena --accent-bg como fondo (hasta hoy solo lo
   usaba el foco de .form-input), que ya viene invertido en tema oscuro. */

.option-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--sp-3);
}
.option-card {
    display: block;                     /* <label> es inline por defecto */
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--surface);
    cursor: pointer;
    transition: border-color var(--t-fast), background var(--t-fast);
}
.option-card:hover       { border-color: var(--accent); }
.option-card.is-selected { border-color: var(--accent); background: var(--accent-bg); }


/* --- Grupos plegables de tarjetas de opcion (wizard, paso 4) -----------
   El catalogo llega del GET ya ordenado por COALESCE(grupo_orden,9999),
   grupo, nombre: aqui no se ordena nada, solo se pliega.

   EL ESTADO VIVE EN EL CONTENEDOR -- `.option-group.open` --, no en el
   cuerpo: asi un unico toggle gobierna a la vez la cabecera destacada, el
   giro del indicador y la apertura del cuerpo, en vez de tres clases que
   pueden desincronizarse. `.open` es la convencion de estado de la casa
   (.modal, .dropdown); `.is-selected` queda reservado a SELECCION, que
   aqui es cosa de .option-card y no del grupo.

   `.option-card` y `.option-cards` NO se tocan: la tarjeta es la misma, y
   la rejilla pasa a vivir en el cuerpo del grupo. El contador reutiliza
   `.chip` -- pildora de ETIQUETA -- y no `.badge`, que es rectangular y
   dice ESTADO. ------------------------------------------------------- */

.option-group {
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: var(--surface);
    overflow: hidden;                  /* el radio recorta la cabecera */
}
.option-group + .option-group { margin-top: var(--sp-3); }

.option-group-head {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    width: 100%;
    padding: var(--sp-3) var(--sp-4);
    border: 0;
    background: transparent;
    color: var(--text);
    font-size: var(--fs-md);
    text-align: left;
    cursor: pointer;
    transition: background var(--t-fast);
}
.option-group-head:hover { background: var(--surface-2); }

/* Borde acentuado por sombra interior y no por `border`: cambiar el borde
   real moveria el contenido un pixel al abrir y cerrar. */
.option-group.open .option-group-head {
    background: var(--accent-bg);
    box-shadow: inset 0 0 0 1px var(--accent-border);
}

.option-group-rotulo {
    flex: 1 1 auto;
    min-width: 0;                      /* empuja el contador a la derecha */
    font-weight: var(--fw-bold);
}

.option-group-caret {
    flex: 0 0 auto;
    color: var(--text-secondary);
    transition: transform var(--t-fast);
}
.option-group.open .option-group-caret { transform: rotate(90deg); }

/* El cuerpo cerrado no ocupa; la rejilla solo existe abierto.
   minmax(0, 1fr) y NO 1fr: `1fr` es minmax(auto, 1fr) y no encoge por
   debajo de su contenido, de modo que un nombre de tramite largo empujaria
   su columna y desbordaria la rejilla en silencio. */
.option-group-body { display: none; }
.option-group.open .option-group-body {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-3);
    padding: var(--sp-4);
    border-top: 1px solid var(--border);
}
@media (max-width: 640px) {
    .option-group.open .option-group-body { grid-template-columns: 1fr; }
}


/* === Ficha de expediente (T3-2, ex <style> de detalle_expediente.html; ámbito .exp-ficha) === */
/* === CABECERA EXPEDIENTE === */
.exp-ficha .exp-header { background:var(--theme-card,#fff); padding:14px 20px 10px; border-bottom:0.5px solid var(--theme-card-border,#E2E8F0); position:sticky; top:52px; z-index:10; }
.exp-ficha .exp-header-row1 { display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:8px; }
.exp-ficha .exp-header-left { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.exp-ficha .exp-title { font-size:17px; font-weight:700; color:var(--theme-text,#0F172A); margin:0; }
.exp-ficha .exp-header-btns { display:flex; gap:6px; flex-wrap:wrap; }
.exp-ficha .exp-header-btns .ia-btn { font-size:12px; padding:6px 12px; }
.exp-ficha .badge-ref { background:var(--navy,#1B3A5C); color:#fff; padding:3px 10px; border-radius:6px; font-size:12px; font-weight:700; letter-spacing:0.5px; }
.exp-ficha .badge-serie { padding:3px 8px; border-radius:4px; font-size:11px; font-weight:700; letter-spacing:1px; }
.exp-ficha .badge-serie-cla,
.exp-ficha .badge-serie-a { background:var(--navy,#1B3A5C); color:#fff; }
.exp-ficha .badge-serie-apc { background:var(--gold,#0EA5E9); color:#fff; }
.exp-ficha .badge-estado { padding:3px 10px; border-radius:100px; font-size:11px; font-weight:600; }
.exp-ficha .badge-abierto { background:#DCFCE7; color:#166534; }
.exp-ficha .badge-recurso { background:#FEF3C7; color:#92400E; }
.exp-ficha .badge-ejecucion { background:#FEF3C7; color:#92400E; }
.exp-ficha .badge-archivado { background:#F1F5F9; color:#64748B; }
.exp-ficha .badge-cerrado { background:#FEE2E2; color:#991B1B; }
.exp-ficha .badge-lopd { background:#EDE9FE; color:#5B21B6; font-size:10px; padding:2px 8px; border-radius:4px; }
.exp-ficha .exp-header-grid { display:grid; grid-template-columns:repeat(6,1fr); gap:10px; margin-top:10px; }
.exp-ficha .exp-header-grid dt { font-size:10px; text-transform:uppercase; letter-spacing:0.5px; color:var(--theme-text-secondary,#64748B); margin-bottom:2px; }
.exp-ficha .exp-header-grid dd { font-size:13px; font-weight:500; color:var(--theme-text,#0F172A); margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.exp-ficha .exp-header-expand { display:none; margin-top:10px; padding-top:10px; border-top:0.5px solid var(--theme-card-border,#E2E8F0); }
.exp-ficha .exp-header-expand.open { display:grid; grid-template-columns:repeat(6,1fr); gap:10px; }
.exp-ficha .exp-toggle { font-size:11px; color:var(--theme-accent,#0EA5E9); cursor:pointer; margin-top:8px; display:inline-block; }
.exp-ficha .exp-toggle:hover { text-decoration:underline; }
/* === CAMBIAR ESTADO === */
.exp-ficha .exp-estado-bar { display:flex; align-items:center; gap:6px; margin-top:8px; padding-top:8px; border-top:0.5px solid var(--theme-card-border,#E2E8F0); flex-wrap:wrap; }
.exp-ficha .exp-estado-bar span { font-size:11px; font-weight:600; color:var(--theme-text-secondary,#64748B); text-transform:uppercase; letter-spacing:0.5px; }
.exp-ficha .exp-estado-btn { padding:3px 10px; border-radius:4px; font-size:11px; font-weight:500; border:0.5px solid var(--theme-card-border,#E2E8F0); background:var(--theme-card,#fff); cursor:pointer; color:var(--theme-text,#0F172A); }
.exp-ficha .exp-estado-btn:hover { border-color:var(--theme-accent,#0EA5E9); }
/* === PESTANAS === */
.exp-ficha .exp-tabs { display:flex; gap:0; border-bottom:0.5px solid var(--theme-card-border,#E2E8F0); background:var(--theme-card,#fff); padding:0 20px; overflow-x:auto; position:sticky; top:140px; z-index:9; }
.exp-ficha .exp-tab { font-size:13px; padding:10px 14px; color:var(--theme-text-secondary,#64748B); cursor:pointer; border-bottom:2px solid transparent; white-space:nowrap; text-decoration:none; display:inline-flex; align-items:center; gap:4px; }
.exp-ficha .exp-tab:hover { color:var(--theme-text,#0F172A); }
.exp-ficha .exp-tab.active { color:var(--theme-accent,#0EA5E9); border-bottom-color:var(--theme-accent,#0EA5E9); font-weight:500; }
.exp-ficha .tab-badge { background:#EF4444; color:#fff; font-size:10px; padding:1px 6px; border-radius:50px; min-width:16px; text-align:center; }
.exp-ficha .tab-badge-blue { background:#0EA5E9; }
/* === PANELES === */
.exp-ficha .exp-pane { display:none; padding:16px 20px; min-height:400px; }
.exp-ficha .exp-pane.active { display:block; }
/* === DOCUMENTOS — LAYOUT 3 COLUMNAS === */
.exp-ficha .doc-layout-3col { display:grid; grid-template-columns:180px minmax(240px,1fr) minmax(320px,1.2fr); gap:0; min-height:520px; border:0.5px solid var(--theme-card-border,#E2E8F0); border-radius:10px; overflow:hidden; background:var(--theme-card,#fff); }
.exp-ficha .doc-sidebar { background:var(--theme-bg,#F8FAFC); border-right:0.5px solid var(--theme-card-border,#E2E8F0); padding:10px 8px; overflow-y:auto; }
.exp-ficha .doc-folder { padding:7px 10px; border-radius:6px; font-size:12px; cursor:pointer; display:flex; align-items:center; gap:6px; margin-bottom:2px; color:var(--theme-text,#0F172A); }
.exp-ficha .doc-folder:hover { background:#fff; }
.exp-ficha .doc-folder.active { background:#E0F2FE; color:#0369A1; font-weight:500; }
.exp-ficha .doc-files { border-right:0.5px solid var(--theme-card-border,#E2E8F0); padding:12px; overflow-y:auto; }
.exp-ficha .doc-toolbar { display:flex; gap:6px; margin-bottom:10px; align-items:center; flex-wrap:wrap; }
.exp-ficha .doc-file-row { display:flex; align-items:center; gap:10px; padding:8px 10px; border-bottom:0.5px solid var(--theme-card-border,#E2E8F0); font-size:13px; cursor:pointer; border-radius:6px; }
.exp-ficha .doc-file-row:hover { background:var(--theme-bg,#F8FAFC); }
.exp-ficha .doc-file-row.selected { background:#E0F2FE; }
.exp-ficha .doc-dropzone { border:2px dashed var(--theme-card-border,#E2E8F0); border-radius:8px; padding:16px; text-align:center; color:var(--theme-text-secondary,#64748B); font-size:12px; margin-top:10px; transition:all .2s; }
.exp-ficha .doc-dropzone.dragover { border-color:var(--theme-accent,#0EA5E9); background:#F0F9FF; color:var(--theme-accent,#0EA5E9); }
/* Panel preview */
.exp-ficha .doc-preview { background:var(--theme-card,#fff); display:flex; flex-direction:column; }
.exp-ficha .doc-preview-head { padding:10px 14px; border-bottom:0.5px solid var(--theme-card-border,#E2E8F0); display:flex; justify-content:space-between; align-items:center; gap:8px; }
.exp-ficha .doc-preview-title { font-size:13px; font-weight:600; color:var(--theme-text,#0F172A); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.exp-ficha .doc-preview-body { flex:1; overflow:auto; background:#F8FAFC; min-height:320px; display:flex; align-items:stretch; justify-content:stretch; }
.exp-ficha .doc-preview-body iframe,
.exp-ficha .doc-preview-body img { width:100%; height:100%; border:none; }
.exp-ficha .doc-preview-body img { object-fit:contain; background:#fff; }
.exp-ficha .doc-preview-empty { margin:auto; text-align:center; color:#94A3B8; font-size:13px; padding:40px 20px; }
.exp-ficha .doc-preview-docx { padding:16px; font-size:13px; line-height:1.6; color:#334155; background:#fff; width:100%; }
.exp-ficha .doc-preview-footer { padding:8px 14px; border-top:0.5px solid var(--theme-card-border,#E2E8F0); display:flex; gap:6px; justify-content:center; flex-wrap:wrap; background:var(--theme-bg,#F8FAFC); }
.exp-ficha .doc-preview-footer .ia-btn { font-size:11px; padding:4px 10px; }
/* Iconos por tipo */
.exp-ficha .file-icon { width:28px; height:36px; border-radius:4px; display:flex; align-items:center; justify-content:center; font-size:9px; font-weight:600; color:#fff; flex-shrink:0; letter-spacing:0.5px; }
.exp-ficha .file-icon-pdf { background:#EF4444; }
.exp-ficha .file-icon-docx { background:#2563EB; }
.exp-ficha .file-icon-doc { background:#2563EB; }
.exp-ficha .file-icon-xlsx { background:#10B981; }
.exp-ficha .file-icon-xls { background:#10B981; }
.exp-ficha .file-icon-jpg { background:#8B5CF6; }
.exp-ficha .file-icon-jpeg { background:#8B5CF6; }
.exp-ficha .file-icon-png { background:#8B5CF6; }
.exp-ficha .file-icon-webp { background:#8B5CF6; }
.exp-ficha .file-icon-gif { background:#8B5CF6; }
.exp-ficha .file-icon-msg { background:#F59E0B; }
.exp-ficha .file-icon-eml { background:#F59E0B; }
.exp-ficha .file-icon-otro { background:#64748B; }
.exp-ficha .doc-file-meta { display:flex; flex-direction:column; min-width:0; flex:1; gap:2px; }
.exp-ficha .doc-file-name { font-size:13px; font-weight:500; color:var(--theme-text,#0F172A); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.exp-ficha .doc-file-sub { font-size:11px; color:var(--theme-text-secondary,#64748B); }
/* Responsive: oculta preview en pantallas pequeñas */
@media (max-width:1200px) {.exp-ficha .doc-layout-3col { grid-template-columns:180px 1fr; }
.exp-ficha .doc-preview { display:none; }
}
/* === INTERVINIENTES === */
.exp-ficha .int-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.exp-ficha .int-card { background:var(--theme-card,#fff); border:0.5px solid var(--theme-card-border,#E2E8F0); border-radius:8px; padding:14px; transition:border-color .2s; }
.exp-ficha .int-card:hover { border-color:var(--theme-accent,#0EA5E9); }
.exp-ficha .int-name { font-size:14px; font-weight:600; color:var(--theme-text,#0F172A); margin-top:6px; }
.exp-ficha .int-detail { font-size:12px; color:var(--theme-text-secondary,#64748B); margin-top:2px; }
.exp-ficha .int-actions { display:flex; gap:4px; margin-top:10px; padding-top:8px; border-top:0.5px solid var(--theme-card-border,#E2E8F0); flex-wrap:wrap; }
.exp-ficha .int-actions button,
.exp-ficha .int-actions a { font-size:11px; padding:3px 8px; border-radius:4px; cursor:pointer; border:0.5px solid var(--theme-card-border,#E2E8F0); background:var(--theme-card,#fff); color:var(--theme-text,#0F172A); text-decoration:none; }
.exp-ficha .int-actions button:hover,
.exp-ficha .int-actions a:hover { border-color:var(--theme-accent,#0EA5E9); }
.exp-ficha .int-role { font-size:10px; font-weight:600; padding:2px 8px; border-radius:4px; text-transform:uppercase; letter-spacing:0.5px; }
.exp-ficha .int-parte-header { font-size:13px; font-weight:600; color:var(--theme-text-secondary,#64748B); margin:16px 0 8px; padding-bottom:6px; border-bottom:1px solid var(--theme-card-border,#E2E8F0); text-transform:uppercase; letter-spacing:0.5px; }
.exp-ficha .int-parte-header:first-child { margin-top:0; }
.exp-ficha .role-cliente { background:#D1FAE5; color:#065F46; }
.exp-ficha .role-abogado { background:#E0F2FE; color:#0369A1; }
.exp-ficha .role-procurador { background:#EDE9FE; color:#5B21B6; }
.exp-ficha .role-parte_contraria { background:#FEE2E2; color:#991B1B; }
.exp-ficha .role-letrado_contrario { background:#FEF3C7; color:#92400E; }
.exp-ficha .role-procurador_contrario { background:#FEF3C7; color:#92400E; }
.exp-ficha .role-perito { background:#F0FDF4; color:#166534; }
.exp-ficha .role-juzgado { background:#F1F5F9; color:#334155; }
.exp-ficha .role-ministerio_fiscal { background:#F1F5F9; color:#334155; }
.exp-ficha .role-testigo { background:#FDF2F8; color:#9D174D; }
.exp-ficha .role-aseguradora { background:#FFF7ED; color:#9A3412; }
.exp-ficha .role-notario { background:#ECFDF5; color:#047857; }
.exp-ficha .role-mediador { background:#F0FDF4; color:#166534; }
.exp-ficha .role-administrador_concursal { background:#FFF7ED; color:#9A3412; }
.exp-ficha .role-otro { background:#F1F5F9; color:#334155; }
/* === ECONOMICO === */
.exp-ficha .eco-summary { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:16px; }
.exp-ficha .eco-card { background:var(--theme-card,#fff); border:0.5px solid var(--theme-card-border,#E2E8F0); border-radius:8px; padding:14px; text-align:center; }
.exp-ficha .eco-card-label { font-size:11px; color:var(--theme-text-secondary,#64748B); text-transform:uppercase; letter-spacing:0.5px; }
.exp-ficha .eco-card-value { font-size:20px; font-weight:700; color:var(--navy,#1B3A5C); margin-top:4px; }
/* === RESPONSIVE === */
@media (max-width:768px) {.exp-ficha .exp-header-grid { grid-template-columns:repeat(3,1fr); }
.exp-ficha .exp-header-expand.open { grid-template-columns:repeat(3,1fr); }
.exp-ficha .int-grid { grid-template-columns:1fr; }
.exp-ficha .doc-layout-3col { grid-template-columns:1fr; min-height:auto; }
.exp-ficha .doc-sidebar { border-right:none; border-bottom:0.5px solid var(--theme-card-border,#E2E8F0); padding:6px 8px; display:flex; gap:4px; flex-wrap:wrap; overflow-x:auto; }
.exp-ficha .eco-summary { grid-template-columns:repeat(2,1fr); }
.exp-ficha .exp-header-btns { width:100%; }
}
/* === Menú contextual ⋮ y modal mover (sub-sprint 1 gestión documental) === */
.exp-ficha .doc-file-actions { margin-left:auto; position:relative; flex-shrink:0; }
.exp-ficha .doc-file-actions-btn { background:none; border:none; cursor:pointer; padding:4px 8px; font-size:18px; color:#64748B; border-radius:4px; line-height:1; }
.exp-ficha .doc-file-actions-btn:hover { background:#E2E8F0; color:#0F172A; }
.exp-ficha .doc-file-actions-menu { display:none; position:absolute; right:0; top:100%; background:#fff; border:1px solid var(--theme-card-border,#E2E8F0); border-radius:6px; box-shadow:0 4px 12px rgba(0,0,0,0.1); min-width:160px; z-index:100; }
.exp-ficha .doc-file-actions-menu.show { display:block; }
.exp-ficha .doc-file-actions-menu button { display:block; width:100%; text-align:left; background:none; border:none; padding:8px 14px; font-size:13px; cursor:pointer; color:#0F172A; }
.exp-ficha .doc-file-actions-menu button:hover { background:#F1F5F9; }
.exp-ficha .doc-file-actions-menu button.danger { color:#991B1B; }
.exp-ficha .doc-file-actions-menu button.danger:hover { background:#FEE2E2; }
.exp-ficha .modal-mover-overlay { display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:1000; align-items:center; justify-content:center; }
.exp-ficha .modal-mover-overlay.show { display:flex; }
.exp-ficha .modal-mover-box { background:#fff; border-radius:8px; padding:20px; max-width:480px; width:90%; max-height:80vh; display:flex; flex-direction:column; gap:12px; }
.exp-ficha .modal-mover-title { font-size:16px; font-weight:600; color:#0F172A; }
.exp-ficha .modal-mover-subtitle { font-size:13px; color:#64748B; }
.exp-ficha .modal-mover-tree { max-height:300px; overflow-y:auto; border:1px solid var(--theme-card-border,#E2E8F0); border-radius:6px; padding:8px; background:#F8FAFC; }
.exp-ficha .modal-mover-folder { padding:6px 10px; cursor:pointer; border-radius:4px; font-size:13px; user-select:none; }
.exp-ficha .modal-mover-folder:hover { background:#E2E8F0; }
.exp-ficha .modal-mover-folder.selected { background:#E0F2FE; font-weight:600; color:#075985; }
.exp-ficha .modal-mover-actions { display:flex; gap:8px; justify-content:flex-end; }
/* === Modal Papelera (sub-sprint 2 gestión documental) === */
.exp-ficha .papelera-trigger { position:relative; }
.exp-ficha .papelera-trigger-badge { display:inline-block; background:#EF4444; color:#fff; font-size:10px; font-weight:700; padding:1px 6px; border-radius:10px; margin-left:4px; min-width:18px; text-align:center; line-height:1.4; }
.exp-ficha .papelera-trigger-badge.cero { background:#94A3B8; }
.exp-ficha .modal-papelera-overlay { display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:1000; align-items:center; justify-content:center; }
.exp-ficha .modal-papelera-overlay.show { display:flex; }
.exp-ficha .modal-papelera-box { background:#fff; border-radius:8px; padding:20px; max-width:680px; width:90%; max-height:85vh; display:flex; flex-direction:column; gap:14px; }
.exp-ficha .modal-papelera-header { display:flex; justify-content:space-between; align-items:flex-start; gap:12px; }
.exp-ficha .modal-papelera-title { font-size:17px; font-weight:600; color:#0F172A; margin:0; }
.exp-ficha .modal-papelera-subtitle { font-size:12px; color:#64748B; margin-top:4px; }
.exp-ficha .modal-papelera-close { background:none; border:none; font-size:22px; cursor:pointer; color:#64748B; line-height:1; padding:0; }
.exp-ficha .modal-papelera-close:hover { color:#0F172A; }
.exp-ficha .modal-papelera-list { flex:1; overflow-y:auto; border:1px solid var(--theme-card-border,#E2E8F0); border-radius:6px; padding:8px; background:#F8FAFC; min-height:200px; max-height:50vh; }
.exp-ficha .modal-papelera-item { background:#fff; border:1px solid var(--theme-card-border,#E2E8F0); border-radius:6px; padding:10px 12px; margin-bottom:8px; display:flex; align-items:center; gap:12px; }
.exp-ficha .modal-papelera-item-icon { font-size:22px; flex-shrink:0; }
.exp-ficha .modal-papelera-item-info { flex:1; min-width:0; }
.exp-ficha .modal-papelera-item-name { font-size:13px; font-weight:600; color:#0F172A; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.exp-ficha .modal-papelera-item-meta { font-size:11px; color:#64748B; margin-top:3px; }
.exp-ficha .modal-papelera-item-meta strong { color:#475569; }
.exp-ficha .modal-papelera-item-actions { display:flex; gap:6px; flex-shrink:0; }
.exp-ficha .modal-papelera-empty { text-align:center; padding:40px 20px; color:#94A3B8; font-size:13px; }
.exp-ficha .modal-papelera-footer { display:flex; justify-content:space-between; align-items:center; gap:8px; }
.exp-ficha .modal-papelera-footer-left { font-size:11px; color:#64748B; }
.exp-ficha .modal-papelera-footer-right { display:flex; gap:8px; }
/* === SS-D: Selección múltiple + descarga (sub-sprint descarga selección) === */
.exp-ficha .doc-checkbox { margin-right:8px; cursor:pointer; flex-shrink:0; width:16px; height:16px; }
.exp-ficha .doc-checkbox:checked { accent-color:#0EA5E9; }
.exp-ficha .doc-seleccion-toolbar { display:none; align-items:center; gap:10px; padding:8px 12px; background:#E0F2FE; border:1px solid #7DD3FC; border-radius:6px; margin-bottom:8px; font-size:13px; color:#075985; flex-wrap:wrap; }
.exp-ficha .doc-seleccion-toolbar.show { display:flex; }
.exp-ficha .doc-seleccion-count { font-weight:600; }
.exp-ficha .doc-seleccion-aviso { color:#92400E; background:#FEF3C7; padding:2px 8px; border-radius:4px; font-size:11px; }
.exp-ficha .doc-seleccion-btn-primary { background:#0EA5E9; color:#fff; border:none; padding:6px 12px; border-radius:6px; font-size:12px; cursor:pointer; font-weight:600; }
.exp-ficha .doc-seleccion-btn-primary:hover { background:#0284C7; }
.exp-ficha .doc-seleccion-btn-primary:disabled { background:#94A3B8; cursor:not-allowed; }
.exp-ficha .doc-seleccion-btn-secundario { background:transparent; color:#075985; border:1px solid #7DD3FC; padding:5px 10px; border-radius:6px; font-size:12px; cursor:pointer; }
.exp-ficha .doc-seleccion-btn-secundario:hover { background:#BAE6FD; }
.exp-ficha .toast-descarga { position:fixed; bottom:24px; right:24px; background:#0F172A; color:#fff; padding:14px 18px; border-radius:8px; box-shadow:0 4px 16px rgba(0,0,0,0.25); z-index:2000; font-size:13px; display:none; min-width:240px; max-width:360px; }
.exp-ficha .toast-descarga.show { display:block; }
.exp-ficha .toast-descarga-titulo { font-weight:600; margin-bottom:4px; }
.exp-ficha .toast-descarga-progreso { font-size:11px; color:#94A3B8; margin-top:6px; }
.exp-ficha .toast-descarga-bar { height:4px; background:#1E293B; border-radius:2px; margin-top:8px; overflow:hidden; }
.exp-ficha .toast-descarga-bar-inner { height:100%; background:#0EA5E9; width:0%; transition:width 0.3s ease; }


/* =============================================================================
   T3-2 — bloque `fx-` para static/css/ia.css.  Va al FINAL, tras el bloque
   acotado de la ficha (04b).

   Prefijo `fx-` = ficha · trámites: el motor de la pestaña «Trámite» y las
   cajas de la cabecera. Lo usan el partial GENÉRICO (_tab_tramite.html) y las
   plantillas de materia — no es de extranjería, aunque extranjería sea hoy la
   única materia que lo estrena.

   NO SE ACOTA a `.exp-ficha`, y es deliberado: el prefijo `fx-` ya es su
   ámbito. Acotarlo impediría reutilizar estas tarjetas fuera de la ficha de
   expediente el día que otra pantalla las necesite.

   ★ ESTE FICHERO SE REESCRIBIÓ EN EL PASO 2, y conviene saber por qué: la
   versión del PASO 1 definía `.fx-caja`, `.fx-rejilla` y `.fx-paso-hecho`,
   nombres que las plantillas abandonaron en el 1b (`.fx-card`, `.fx-kv`,
   `.fx-paso-done`). Al aplicar, `ia.css` quedó con 74 clases de las que 22 de
   las usadas NO estaban definidas. **No habría fallado nada**: las tarjetas
   habrían salido sin caja, sin borde y sin rejilla, y el único síntoma sería
   una pantalla fea. Lo cazó cotejar definidas contra usadas antes de reiniciar.
   De ahí que ahora el fichero se escriba DESDE el censo de las plantillas.

   TODO color sale de un token: así el tema oscuro (body[data-theme="oscuro"])
   funciona sin una regla más, porque allí los tokens ya están invertidos.

   VOCABULARIOS, medidos contra los CHECK de las tablas (27/08). Ojo a dos que
   rompen el patrón: el trámite usa `presentada` y `requerida`, en femenino.
     trámite:       propuesto contratado presentada requerida resuelto documentado cerrado
     plazo:         sin_base pendiente vencido cumplido
     checklist:     pendiente aportado no_procede
     requerimiento: pendiente prorroga_solicitada contestado_parcial contestado caducado
     notificación:  propuesta confirmada pendiente_acceso accedida rechazada sin_casar
     pasos (UI):    done now next req
   ============================================================================= */

/* --- Rejilla de dos columnas de la pestaña ------------------------------- */
/* minmax(min(...),1fr) y no 1fr: `1fr` es minmax(auto,1fr) y NO encoge por
   debajo de su contenido, de modo que una tabla ancha empuja la rejilla y
   desborda el body (invariante de s96). */
.fx-cols {
    display: grid; gap: var(--sp-4);
    grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
    align-items: start;
}
.fx-col { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-4); }

/* --- Tarjeta ------------------------------------------------------------- */
.fx-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: var(--sp-4);
}
.fx-card-cab { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.fx-card-cab h3 { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--text); }
.fx-card-aviso { border-color: var(--warning-border); background: var(--warning-bg); }
.fx-contador {
    margin-left: auto; font-size: var(--fs-sm); color: var(--text-secondary);
    background: var(--surface-2); border-radius: var(--r-full); padding: 2px var(--sp-2);
}
.fx-titular { margin: 0 0 var(--sp-1); font-size: var(--fs-lg); font-weight: var(--fw-medium); color: var(--text); }
.fx-chips { margin: 0 0 var(--sp-3); display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.fx-acciones { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }

/* Caja simple de contenido dentro de un modal o una tarjeta. Nacio SIN REGLA
   en T5-2c (31/08/2026): la clase se uso en `cnSecAvisoSede` dando por hecho
   que existia, y su unica aparicion en esta hoja era el comentario de arriba,
   que precisamente cuenta que el PASO 1 la definia y las plantillas la
   abandonaron. Se pintaba sin fondo, sin borde y sin padding, sin error
   alguno -- mismo defecto que `.modal-box` en s118. */
.fx-caja {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    margin-bottom: 10px;
}

/* --- Las tres cajas de un vistazo (cabecera) ------------------------------ */
.fx-cajas3 {
    display: grid; gap: var(--sp-3);
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    margin-top: var(--sp-4);
}

/* --- Rejilla clave/valor -------------------------------------------------- */
.fx-kv {
    display: grid; gap: var(--sp-3); margin: 0;
    grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr));
}
.fx-kv dt {
    font-size: var(--fs-xs); color: var(--text-secondary);
    text-transform: uppercase; letter-spacing: .03em; margin-bottom: 2px;
}
.fx-kv dd { margin: 0; font-size: var(--fs-md); color: var(--text); }
.fx-kv-materia { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px dashed var(--border); }

/* --- Rejilla de seis de la cabecera --------------------------------------- */
.fx-grid6 { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }
.fx-sub { display: block; font-size: var(--fs-xs); color: var(--text-secondary); margin-top: 2px; }
.fx-vacio-dd { color: var(--text-secondary); font-style: italic; }
.fx-link { color: var(--link); font-weight: var(--fw-bold); text-decoration: none; }
.fx-link:hover { text-decoration: underline; }

/* --- Badge de materia y chips --------------------------------------------- */
.fx-badge-materia {
    background: var(--info-bg); color: var(--info-text); border: 1px solid var(--info-border);
    border-radius: var(--r-full); padding: 2px var(--sp-2);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
.fx-chip {
    display: inline-block; background: var(--surface-2); color: var(--text-secondary);
    border: 1px solid var(--border); border-radius: var(--r-sm);
    padding: 1px var(--sp-2); font-size: var(--fs-xs); text-decoration: none;
}
.fx-chip-ok      { background: var(--success-bg); color: var(--success-text); border-color: var(--success-border); }
.fx-chip-aviso   { background: var(--warning-bg); color: var(--warning-text); border-color: var(--warning-border); }
.fx-chip-alerta  { background: var(--danger-bg);  color: var(--danger-text);  border-color: var(--danger-border); }
.fx-chip-vacio   { color: var(--text-secondary); font-style: italic; }
.fx-chip-regimen { background: var(--accent-bg); color: var(--info-text); border-color: var(--accent-border); }

/* --- Estado del trámite (los 7 del CHECK) --------------------------------- */
.fx-estado {
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
    border-radius: var(--r-full); padding: 2px var(--sp-3); border: 1px solid transparent;
}
.fx-estado-propuesto   { background: var(--surface-2);  color: var(--text-secondary); border-color: var(--border); }
.fx-estado-contratado  { background: var(--accent-bg);  color: var(--info-text);      border-color: var(--accent-border); }
.fx-estado-presentada  { background: var(--info-bg);    color: var(--info-text);      border-color: var(--info-border); }
.fx-estado-requerida   { background: var(--warning-bg); color: var(--warning-text);   border-color: var(--warning-border); }
.fx-estado-resuelto    { background: var(--success-bg); color: var(--success-text);   border-color: var(--success-border); }
.fx-estado-documentado { background: var(--success-bg); color: var(--success-text);   border-color: var(--success-border); }
.fx-estado-cerrado     { background: var(--surface-2);  color: var(--text-secondary); border-color: var(--border); }

/* --- Pasos: done · now · next · req --------------------------------------- */
.fx-pasos { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin: 0 0 var(--sp-3); padding: 0; list-style: none; }
.fx-paso  { display: flex; align-items: center; gap: var(--sp-1); font-size: var(--fs-xs); }
.fx-paso-punto { width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); flex: 0 0 auto; }
.fx-paso-fecha { color: var(--text-secondary); }
.fx-paso-done .fx-paso-punto  { background: var(--success); }
.fx-paso-done .fx-paso-nombre { color: var(--text); font-weight: var(--fw-medium); }
.fx-paso-now  .fx-paso-punto  { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-bg); }
.fx-paso-now  .fx-paso-nombre { color: var(--text); font-weight: var(--fw-bold); }
.fx-paso-next .fx-paso-nombre { color: var(--text-secondary); }
/* `requerida` es DESVÍO, no un paso más de la línea: se entra y se sale de él
   desde `presentada`. Por eso se pinta aparte y en tono de aviso. */
.fx-paso-req  .fx-paso-punto  { background: var(--warning); }
.fx-paso-req  .fx-paso-nombre { color: var(--warning-text); font-style: italic; }

/* --- Plazos --------------------------------------------------------------- */
.fx-plazos { list-style: none; margin: 0; padding: 0; }
.fx-plazo {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2);
    padding: var(--sp-2) 0; border-bottom: 1px solid var(--border);
}
.fx-plazo:last-child { border-bottom: 0; }
.fx-plazo-concepto { font-weight: var(--fw-bold); font-size: var(--fs-md); }
.fx-plazo-valor    { font-size: var(--fs-md); }
.fx-plazo-txt      { font-size: var(--fs-xs); color: var(--text-secondary); }
.fx-plazo-vencido   .fx-plazo-valor { color: var(--danger-text);  font-weight: var(--fw-bold); }
.fx-plazo-pendiente .fx-plazo-valor { color: var(--text); }
.fx-plazo-cumplido  .fx-plazo-valor { color: var(--success-text); }
.fx-plazo-sin_base  .fx-plazo-valor { color: var(--text-secondary); }
.fx-sinbase { color: var(--text-secondary); font-style: italic; }

/* --- Badges de estado (los cinco vocabularios) ---------------------------- */
.fx-badge {
    display: inline-block; font-size: var(--fs-xs); font-weight: var(--fw-medium);
    border-radius: var(--r-sm); padding: 1px var(--sp-2);
    background: var(--surface-2); color: var(--text-secondary); border: 1px solid var(--border);
}
.fx-badge-vencido, .fx-badge-caducado, .fx-badge-rechazada {
    background: var(--danger-bg); color: var(--danger-text); border-color: var(--danger-border); }
.fx-badge-cumplido, .fx-badge-contestado, .fx-badge-accedida, .fx-badge-confirmada,
.fx-badge-resuelto, .fx-badge-documentado {
    background: var(--success-bg); color: var(--success-text); border-color: var(--success-border); }
.fx-badge-pendiente, .fx-badge-pendiente_acceso, .fx-badge-prorroga_solicitada,
.fx-badge-contestado_parcial, .fx-badge-sin_casar, .fx-badge-requerida {
    background: var(--warning-bg); color: var(--warning-text); border-color: var(--warning-border); }
.fx-badge-presentada, .fx-badge-contratado, .fx-badge-propuesta {
    background: var(--info-bg); color: var(--info-text); border-color: var(--info-border); }
.fx-badge-sin_base { background: var(--surface-2); color: var(--text-secondary); font-style: italic; }

/* --- Checklist e ítems ----------------------------------------------------- */
.fx-grupo h4 {
    margin: var(--sp-3) 0 var(--sp-2); font-size: var(--fs-sm);
    color: var(--text-secondary); text-transform: uppercase; letter-spacing: .03em;
}
.fx-lista { list-style: none; margin: 0; padding: 0; }
.fx-item {
    display: flex; align-items: center; gap: var(--sp-2);
    padding: var(--sp-2) 0; border-bottom: 1px solid var(--border); font-size: var(--fs-md);
}
.fx-item:last-child { border-bottom: 0; }
.fx-item-txt    { flex: 1 1 auto; min-width: 0; }   /* min-width:0 = el flex encoge (s96) */
.fx-item-estado { font-size: var(--fs-xs); color: var(--text-secondary); white-space: nowrap; }

/* Punto de semaforo por proximidad de vencimiento. Nace en P1 (31/08/2026)
   para la tarjeta de avisos de sede del panel.

   ⚠ NO se reutilizo `.fx-item-marca`, que es la casilla del checklist: son
   14x14 con borde grueso porque representan «hecho / no hecho», no urgencia.
   Compartir la clase ataria el aspecto del semaforo a los cambios del
   checklist, y al reves.

   El color lo pone el MODIFICADOR; el punto base es neutro, que es lo que
   corresponde a un aviso sin vencimiento o con plazo holgado. Los tres tokens
   de color ya existen y se redefinen en oscuro, asi que el semaforo sigue el
   tema del tenant sin bloque propio.

   ★ LOS COLORES SE CORRIGIERON EL 31/08/2026 TRAS LA CERTIFICACION VISUAL, y
   la medicion daba la razon al ojo con creces. El punto vive sobre el fondo de
   `.fx-card-aviso` --`--warning-bg`--, y los primeros tokens elegidos eran de
   la MISMA familia clara que ese fondo:

       ambar  --warning-border  1.20:1 (claro) · 1.28:1 (oscuro)   invisible
       neutro --border-strong   1.43:1 (claro) · 1.20:1 (oscuro)   invisible

   Se cambian por el token de TEXTO de cada familia, que es el que esta pensado
   para leerse SOBRE ese fondo:

       ambar  --warning-text    6.84:1 (claro) · 7.28:1 (oscuro)
       neutro --text-secondary  4.59:1 (claro) · 3.54:1 (oscuro)

   Los cuatro por encima de 3:1, que es el minimo de WCAG para elementos
   graficos. `--warning-text` se INVIERTE en oscuro (#92400E -> #FDE68A), de
   modo que el ambar contrasta en los dos temas sin regla aparte.

   ⚠ LECCION: `-border` y `-bg` de una familia son tonos VECINOS por diseno --el
   borde de una caja de aviso va sobre su propio fondo--. Para pintar ENCIMA de
   `-bg` hay que ir al `-text` de esa familia, no a su `-border`. */
.fx-dot {
    width: 8px; height: 8px; border-radius: var(--r-full); flex: 0 0 auto;
    background: var(--text-secondary);
}
.fx-dot-ambar { background: var(--warning-text); }
.fx-dot-rojo  { background: var(--danger-text); }
.fx-item-marca {
    width: 14px; height: 14px; border-radius: var(--r-sm); flex: 0 0 auto;
    border: 1.5px solid var(--border-strong); background: var(--surface);
}
/* `pendiente` es el estado por defecto y hereda de .fx-item: la marca vacia y
   el texto normal YA son lo correcto. Se declara igualmente, vacia, para que el
   cotejo «clases usadas vs definidas» salga limpio y para que quien busque el
   estilo del pendiente lo encuentre en vez de concluir que falta. */
.fx-item-pendiente { }
.fx-item-aportado   .fx-item-marca { background: var(--success); border-color: var(--success); }
.fx-item-no_procede .fx-item-marca { background: var(--surface-2); border-style: dashed; }
.fx-item-no_procede .fx-item-txt   { color: var(--text-secondary); text-decoration: line-through; }

/* --- Línea de tiempo de trámites ------------------------------------------ */
.fx-linea { list-style: none; margin: 0; padding: 0; }
.fx-linea-item {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
    padding: var(--sp-2); border-radius: var(--r-sm); border-bottom: 1px solid var(--border);
}
.fx-linea-item:last-child { border-bottom: 0; }
.fx-linea-nombre { flex: 1 1 auto; min-width: 0; font-size: var(--fs-md); }
.fx-linea-plazo  { font-size: var(--fs-xs); color: var(--warning-text); font-weight: var(--fw-medium); }
.fx-linea-siguiente { border-left: 3px solid var(--accent); background: var(--accent-bg); }
.fx-fila-actual  { background: var(--accent-bg); }

/* --- Tablas ---------------------------------------------------------------- */
/* overflow-x propio: una tabla ancha scrollea DENTRO, el body nunca. */
.fx-card:has(> .fx-tabla) { overflow-x: auto; }
.fx-tabla { width: 100%; border-collapse: collapse; font-size: var(--fs-md); }
.fx-tabla th {
    text-align: left; font-size: var(--fs-sm); color: var(--text-secondary);
    font-weight: var(--fw-medium); text-transform: uppercase; letter-spacing: .03em;
    padding: var(--sp-2); border-bottom: 1px solid var(--border); white-space: nowrap;
}
.fx-tabla td { padding: var(--sp-2); border-bottom: 1px solid var(--border); vertical-align: top; }
.fx-tabla tr:last-child td { border-bottom: 0; }

/* --- Requerimientos -------------------------------------------------------- */
.fx-req { border-left: 3px solid var(--warning); padding-left: var(--sp-3); margin-bottom: var(--sp-4); }
.fx-req:last-child { margin-bottom: 0; }
.fx-req-cab { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }

/* --- Avisos, notas y vacíos ------------------------------------------------ */
.fx-alerta        { color: var(--danger-text); font-weight: var(--fw-medium); }
.fx-alerta-inline {
    color: var(--danger-text); background: var(--danger-bg);
    border: 1px solid var(--danger-border); border-radius: var(--r-sm);
    padding: 0 var(--sp-1); font-size: var(--fs-xs); white-space: nowrap;
}
.fx-nota     { color: var(--text-secondary); font-size: var(--fs-xs); }
.fx-nota-pie { color: var(--text-secondary); font-size: var(--fs-xs); margin: var(--sp-2) 0 0; }
.fx-siguiente-res { font-size: var(--fs-md); margin: var(--sp-2) 0; }
.fx-vacio {
    padding: var(--sp-5); text-align: center; color: var(--text-secondary);
    background: var(--surface-2); border-radius: var(--r-md);
}
.fx-vacio-linea { color: var(--text-secondary); font-size: var(--fs-md); margin: 0; }

/* Un hueco de materia sin contenido no ocupa: la sonda lo cuenta por su
   atributo data-slot, no por su altura. */
.fx-slot-vacio { display: none; }

/* === T4 · checklist escribible === */
/* Los tres tokens existen en ia.css (medido: --sp-1 x19, --danger-text x12,
   --fs-xs x18), asi que no hace falta ningun literal. */
.fx-item-acciones { display: flex; gap: var(--sp-1); flex-shrink: 0; }
.fx-item-motivo   { display: block; font-style: italic; }
.fx-item-error    { display: block; color: var(--danger-text); font-size: var(--fs-xs); }

/* --- Notificación recibida (T5-1) ------------------------------------- */

/* La fila de una propuesta se distingue SIN color de alarma: no es un error,
   es trabajo pendiente. Barra lateral en el tono de acento, mismo recurso que
   .fx-fila-actual usa para «la pieza en curso». */
.fx-fila-propuesta > td:first-child {
    box-shadow: inset 3px 0 0 var(--accent);
}
.fx-fila-propuesta > td { background: var(--accent-bg); }

/* El CSV es un identificador: monoespaciado, porque se compara carácter a
   carácter y en proporcional dos caracteres parecidos no se distinguen.
   --font-mono ya está definido en ia.css: no se declara una pila nueva. */
.fx-mono {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    letter-spacing: -.01em;
}

/* Confianza de la lectura. Discreta a propósito: informa, no compite con el
   estado — el dato que manda es «propuesta», no el porcentaje. */
.fx-conf {
    font-size: var(--fs-xs);
    color: var(--text-secondary);
    margin-left: .35em;
}

/* Acciones dentro de una celda: en línea y sin que la fila crezca. */
.fx-acc-fila {
    white-space: nowrap;
    text-align: right;
}
.fx-acc-fila .ia-btn { margin-left: var(--sp-1); }

/* Estado por fichero durante la subida. Una línea por documento: en un lote de
   cinco, un mensaje único no diría cuál falló. */
.fx-nr-estado {
    margin: var(--sp-2) 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
}
.fx-nr-linea {
    font-size: var(--fs-sm);
    padding: var(--sp-1) var(--sp-2);
    border-radius: var(--r-sm);
    background: var(--surface-2);
    /* min-width:0 para que un nombre de fichero largo pueda encogerse: sin
       esto el flex no baja del ancho del contenido y el modal desborda
       (invariante de s96). */
    min-width: 0;
    overflow-wrap: anywhere;
}
.fx-nr-curso { color: var(--text-secondary); }
.fx-nr-ok    { box-shadow: inset 3px 0 0 var(--success); }
.fx-nr-error { box-shadow: inset 3px 0 0 var(--danger-border); color: var(--danger-text); }

/* NO hace falta bloque de tema oscuro: los ocho tokens usados aquí ya se
   redefinen en su :root, de modo que estas reglas responden solas. Añadir un
   `body[data-theme="oscuro"]` con colores propios sería volver a fijar valores
   donde el sistema ya los tiene — el defecto que este fichero viene a evitar.
   (La versión anterior de este borrador declaraba un --fx-propuesta-fondo con
   rgba literal y su variante oscura: retirado, `--accent-bg` ya lo hace.) */

/* ============================================================
   + NUEVO TRAMITE (T5-4, s126) — modal de dos columnas
   ============================================================
   Solo la ARMAZON: las tarjetas, el acordeon (`.option-group*`,
   `.option-card`) y las fichas de datos (`.card-dl`) ya existen y se
   reutilizan tal cual — son las mismas del paso 4 del wizard.
   ============================================================ */
.fx-nt-cols {
    display: grid;
    /* `minmax(0, …)` y no `1fr` a secas: un nombre de tramite largo empujaria
       la columna y desbordaria la rejilla sin que nada fallase (invariante
       s96). Con el minimo a 0 la columna puede encoger y el texto recorta. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--sp-4);
    align-items: start;
}
@media (max-width: 860px) {
    .fx-nt-cols { grid-template-columns: minmax(0, 1fr); }
}
.fx-nt-sel  { min-width: 0; }
.fx-nt-info {
    min-width: 0;
    padding: var(--sp-3);
    background: var(--surface-2);
    border-radius: var(--r-md);
}
.fx-nt-info .card-dl { margin: 0; }
.fx-nt-filtros {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin: var(--sp-2) 0 var(--sp-3);
}
/* El chip como BOTON de filtro. `.chip` ya existe como contador; aqui es
   pulsable, de modo que necesita cursor y estado marcado propios —
   `.option-card.is-selected` no le llega. */
.fx-nt-filtros .chip {
    cursor: pointer;
    border: 1px solid var(--border);
    background: var(--surface);
    /* Texto LEGIBLE, no decorativo (s123): el chip es un boton de filtro con
       su rotulo, de modo que va a --text y no a --text-secondary, que en el
       pasivo declarado de la familia `estilos` es el par de tope congelado. */
    color: var(--text);
}
.fx-nt-filtros .chip.is-selected {
    background: var(--accent-bg);
    border-color: var(--accent);
    color: var(--text);
}
/* La lista tiene tope de altura y scroll propio: 88 tramites en 18 grupos no
   pueden empujar el pie del modal fuera de la pantalla. */
.fx-nt-sel .stack {
    max-height: 42vh;
    overflow-y: auto;
    margin-bottom: var(--sp-3);
}
/* Un hijo flex NO baja de su contenido gracias a `min-height:auto`... salvo que
   tenga `overflow` distinto de `visible`, y `.option-group` lleva `overflow:
   hidden` para que el radio recorte la cabecera: su minimo automatico pasa a 0
   y los 18 grupos se encogian a la altura de sus bordes -- 18 rayas vacias. */
.fx-nt-sel .stack > .option-group { flex: 0 0 auto; }

/* --- SUB-UX-1 · subida con progreso (D-43). Tokens, nunca colores cableados. --- */
.exp-ficha .doc-subidas { margin:var(--sp-2) 0; display:flex; flex-direction:column; gap:6px; }
.exp-ficha .doc-subida { background:var(--surface-2); border:1px solid var(--border);
    border-radius:var(--r-sm); padding:8px 10px; font-size:var(--fs-sm); }
.exp-ficha .doc-subida-cab { display:flex; justify-content:space-between; gap:var(--sp-2); align-items:baseline; }
.exp-ficha .doc-subida-nombre { color:var(--text); font-weight:var(--fw-medium);
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.exp-ficha .doc-subida-estado { color:var(--text); white-space:nowrap; font-size:var(--fs-xs); }
.exp-ficha .doc-subida-bar { height:4px; background:var(--border); border-radius:var(--r-full);
    margin-top:6px; overflow:hidden; }
.exp-ficha .doc-subida-bar-inner { height:100%; width:0%; background:var(--accent);
    transition:width var(--t-fast, .15s) ease; }
.exp-ficha .doc-subida-detalle { color:var(--text); font-size:var(--fs-xs); margin-top:4px; }
.exp-ficha .doc-subida.ok { border-color:var(--success-border); }
.exp-ficha .doc-subida.ok .doc-subida-estado { color:var(--success-text); }
.exp-ficha .doc-subida.ok .doc-subida-bar-inner { background:var(--success); }
.exp-ficha .doc-subida.error { border-color:var(--danger-border); background:var(--danger-bg); }
.exp-ficha .doc-subida.error .doc-subida-estado,
.exp-ficha .doc-subida.error .doc-subida-detalle { color:var(--danger-text); }
.exp-ficha .doc-subida.error .doc-subida-bar-inner { background:var(--danger); }
.exp-ficha .doc-subida-resumen { padding:8px 10px; border-radius:var(--r-sm);
    font-size:var(--fs-sm); font-weight:var(--fw-medium); }
.exp-ficha .doc-subida-resumen.error { background:var(--danger-bg); color:var(--danger-text);
    border:1px solid var(--danger-border); }
.exp-ficha .doc-dropzone.ocupada { opacity:.55; pointer-events:none; }
/* SUB-UX-1b: la fila OK se desvanece y se retira sola; la de error lleva aspa. */
.exp-ficha .doc-subida { transition:opacity var(--t-base); }
.exp-ficha .doc-subida.saliendo { opacity:0; }
.exp-ficha .doc-subida.error .doc-subida-nombre { margin-right:auto; }
.exp-ficha .doc-subida-cerrar { background:none; border:0; padding:0 2px; line-height:1;
    cursor:pointer; color:var(--danger-text); font-size:var(--fs-md); }
.exp-ficha .doc-subida-cerrar:hover { color:var(--text); }
