/* ---------- Continuidad entre páginas ----------
   La transición nativa entre documentos se retiró el 26/08/2026. No fue por
   el mapa: fue por la barra lateral de dos niveles, cuya caja cambia de
   anchura entre páginas y por tanto se deforma en lugar de quedarse quieta.
   El razonamiento completo está en la cabecera de assets/css/app.css. */

@layer legacy {
    /* =====================================================================
       Nexo Azul — campaign.css
       Centro de mando + Territorio 78 + Agenda y actos + operativa.

       El bloque de acceso se ha extraído a auth.css. La cabecera de Mi día se
       queda aquí: estaba archivada bajo el rótulo «Acceso (login)», que era
       justamente lo que hacía ilegible el archivo.
       ===================================================================== */

    /* =====================================================================
       Mi día — cabecera inmersiva 2026
       El selector :has() mantiene el paisaje y la topbar transparente aislados
       en esta vista. Los navegadores sin soporte conservan el hero anterior.
       ===================================================================== */
    body.app-body:has(.myday-hero) {
        background-color: var(--b-50);
        background-image: none;
    }

    body.app-body .main-content:has(.myday-hero) {
        position: relative;
        isolation: isolate;
        background: var(--b-50);
    }

    /* El panel contextual ya aporta su propio margen y sombra. En el resto de
       vistas los 12px que reserva el armazón se funden con el fondo plano; aquí
       quedaban entre el panel y el paisaje como una costura vertical. El
       contenido empieza bajo la sombra, justo en el canto real del panel. */
    @media (min-width: 1181px) {
        body.app-body:has(.myday-hero) .sidebar {
            width: calc(var(--nav-rail-w) + var(--nav-context-w));
        }

        body.app-body.sidebar-context-closed:has(.myday-hero) .sidebar {
            width: var(--nav-rail-w);
        }
    }

    body.app-body .main-content:has(.myday-hero)::before {
        content: "";
        position: absolute;
        z-index: -1;
        inset: 0 0 auto;
        height: 485px;
        pointer-events: none;
        background-image:
            linear-gradient(90deg, rgba(239, 247, 255, .82) 0%, rgba(239, 247, 255, .46) 38%, rgba(239, 247, 255, .08) 76%),
            linear-gradient(180deg, rgba(239, 247, 255, .08) 0%, rgba(243, 246, 251, .04) 54%, var(--b-50) 88%, var(--b-50) 100%),
            url(../img/mi-dia-paisaje-asturias.webp);
        background-repeat: no-repeat;
        background-position: center, center, center 48%;
        background-size: cover;
    }

    body.app-body .main-content:has(.myday-hero) > .topbar,
    body.app-body .main-content:has(.myday-hero) > .page {
        position: relative;
    }

    /* En Mi día la barra forma parte de la escena y deja de ser una banda sticky. */
    body.app-body .main-content:has(.myday-hero) > .topbar {
        z-index: 30;
        top: auto;
        background: transparent;
        border-bottom: 0;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    body.app-body .main-content:has(.myday-hero) .topbar__search,
    body.app-body .main-content:has(.myday-hero) .icon-btn,
    body.app-body .main-content:has(.myday-hero) .topbar__menu,
    body.app-body .main-content:has(.myday-hero) .countdown {
        background: rgba(255, 255, 255, .84);
        border-color: rgba(255, 255, 255, .72);
        box-shadow: 0 14px 30px -22px rgba(18, 54, 103, .5), inset 0 1px 0 rgba(255, 255, 255, .78);
        -webkit-backdrop-filter: blur(14px) saturate(135%);
        backdrop-filter: blur(14px) saturate(135%);
    }

    body.app-body .main-content:has(.myday-hero) > .page {
        z-index: auto;
        padding-top: var(--sp-7);
    }

    body.app-body .main-content:has(.myday-hero) .myday-hero {
        min-height: 192px;
        gap: var(--sp-8);
        margin-bottom: 20px;
        padding: var(--sp-8) var(--sp-4) var(--sp-9);
        overflow: visible;
        border: 0;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
    }

    body.app-body .main-content:has(.myday-hero) .myday-hero__glow,
    body.app-body .main-content:has(.myday-hero) .myday-hero__dots {
        display: none;
    }

    body.app-body .main-content:has(.myday-hero) .myday-hero__icon {
        width: 72px;
        height: 72px;
        border: 1px solid rgba(255, 255, 255, .72);
        color: #fff;
        background: linear-gradient(145deg, var(--b-400) 0%, var(--b-600) 70%, var(--b-700) 100%);
        box-shadow: 0 15px 30px -14px rgba(9, 74, 170, .72), inset 0 1px 0 rgba(255, 255, 255, .42);
    }

    body.app-body .main-content:has(.myday-hero) .myday-hero__icon svg {
        width: 35px;
        height: 36px;
    }

    body.app-body .main-content:has(.myday-hero) .myday-hero__title {
        margin-bottom: 16px;
        color: var(--b-900);
        font-size: clamp(30px, 3.2vw, 43px);
        font-weight: 400;
        letter-spacing: var(--tracking-hero);
        text-shadow: 0 1px 0 rgba(255, 255, 255, .72), 0 8px 24px rgba(255, 255, 255, .46);
    }

    body.app-body .main-content:has(.myday-hero) .myday-hero__title strong {
        color: var(--brand-700);
        font-weight: 700;
    }

    body.app-body .main-content:has(.myday-hero) .hchip {
        color: var(--b-800);
        background: rgba(255, 255, 255, .8);
        border-color: rgba(255, 255, 255, .76);
        box-shadow: 0 10px 24px -18px rgba(18, 54, 103, .52), inset 0 1px 0 rgba(255, 255, 255, .86);
        -webkit-backdrop-filter: blur(12px) saturate(135%);
        backdrop-filter: blur(12px) saturate(135%);
    }

    @media (hover: hover) and (pointer: fine) {
        body.app-body .main-content:has(.myday-hero) a.hchip:hover {
            color: var(--b-700);
            background: rgba(255, 255, 255, .94);
            box-shadow: var(--shadow);
        }
    }

    body.app-body .main-content:has(.myday-hero) .hchip__ic {
        color: var(--b-500);
        background: rgba(31, 111, 224, .11);
    }

    body.app-body .main-content:has(.myday-hero) .hchip--danger {
        color: var(--c-rose);
    }

    body.app-body .main-content:has(.myday-hero) .hchip--danger .hchip__ic {
        color: var(--c-rose);
        background: rgba(199, 35, 57, .12);
    }

    body.app-body .main-content:has(.myday-hero) .hchip--warn {
        color: var(--warn);
    }

    body.app-body .main-content:has(.myday-hero) .hchip--warn .hchip__ic {
        color: var(--c-amber);
        background: rgba(155, 96, 13, .13);
    }

    body.app-body .main-content:has(.myday-hero) .hchip--phase {
        color: var(--ok);
    }

    body.app-body .main-content:has(.myday-hero) .hchip--phase .hchip__ic {
        color: var(--c-green);
        background: rgba(35, 168, 104, .13);
    }

    body.app-body .main-content:has(.myday-hero) .myday-hero__meta {
        color: var(--b-800);
        text-shadow: 0 1px 0 rgba(255, 255, 255, .76);
    }

    body.app-body .main-content:has(.myday-hero) .hmeta svg {
        color: var(--b-500);
    }

    body.app-body .main-content:has(.myday-hero) .hmeta__sep {
        color: rgba(38, 63, 101, .36);
    }

    @media (max-width: 900px) {
        body.app-body .main-content:has(.myday-hero)::before {
            height: 520px;
            background-position: center, center, 67% center;
        }

        body.app-body .main-content:has(.myday-hero) .myday-hero {
            min-height: 0;
            gap: var(--sp-6);
            padding: var(--sp-8) var(--sp-1) var(--sp-8);
        }

        body.app-body .main-content:has(.myday-hero) .myday-hero__icon {
            width: 60px;
            height: 60px;
        }

        body.app-body .main-content:has(.myday-hero) .myday-hero__icon svg {
            width: 29px;
            height: 28px;
        }
    }

    @media (max-width: 600px) {
        body.app-body .main-content:has(.myday-hero)::before {
            height: 590px;
            background-position: center, center, 72% center;
        }

        body.app-body .main-content:has(.myday-hero) > .page {
            padding-top: var(--sp-5);
        }

        body.app-body .main-content:has(.myday-hero) .myday-hero {
            padding-bottom: var(--sp-8);
        }

        body.app-body .main-content:has(.myday-hero) .myday-hero__title {
            font-size: clamp(28px, 9vw, 36px);
        }

        body.app-body .main-content:has(.myday-hero) .myday-hero__chips {
            gap: var(--sp-4);
        }

        body.app-body .main-content:has(.myday-hero) .hchip {
            padding-right: var(--sp-5);
            font-size: var(--fs-sm);
        }
    }

    .flash-stack { margin-bottom: 16px; }

    /* Enlace en títulos de filas (tareas/incidencias asociadas en fichas padre) */
    .row-link { color: inherit; text-decoration: none; }
    .row-link:hover { color: var(--brand-texto); text-decoration: underline; }

    /* ---------- KPIs (tarjetas con chip) ---------- */
    .stat-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--sp-6); margin-bottom: 20px; }
    .stat-card { background: var(--surface); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); border: 1px solid var(--surface-border); border-radius: var(--r); padding: var(--sp-7) var(--sp-7); box-shadow: var(--shadow); display: flex; flex-direction: column; gap: var(--sp-4); transition: transform .18s, box-shadow .18s; }
    .stat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
    .stat-card__chip { width: 46px; height: 46px; border-radius: var(--r); display: grid; place-items: center; }
    .stat-card__chip svg { width: 23px; height: 23px; }
    .stat-card__chip--blue { background: var(--c-blue-bg); color: var(--c-blue); }
    .stat-card__chip--teal { background: var(--c-teal-bg); color: var(--c-teal); }
    .stat-card__chip--violet { background: var(--c-violet-bg); color: var(--c-violet); }
    .stat-card__chip--amber { background: var(--c-amber-bg); color: var(--c-amber); }
    .stat-card__chip--rose { background: var(--c-rose-bg); color: var(--c-rose); }
    .stat-card__label { font-size: var(--fs-md); color: var(--ink-2); font-weight: 500; }
    .stat-card__value { font-size: var(--fs-5xl); font-weight: 700; letter-spacing: var(--tracking-display); line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
    .stat-card__sub { font-size: var(--fs-sm); color: var(--ink-3); }

    /* ---------- Filas del dashboard ---------- */
    .dash-row { display: grid; gap: var(--sp-7); margin-bottom: 20px; align-items: stretch; }
    .dash-row > .panel { margin-bottom: 0; }
    .dash-row--3 { grid-template-columns: 1fr 1.28fr 1fr; }
    .dash-row--2 { grid-template-columns: 1.62fr 1fr; }

    /* ---------- Cabecera de panel ---------- */
    .panel__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-5); margin-bottom: 16px; }
    .panel__title { font-size: var(--fs-lg); font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: var(--sp-4); }
    .panel__title svg { width: 18px; height: 18px; color: var(--brand-texto); }
    .panel__link { font-size: var(--fs-md); font-weight: 500; color: var(--brand-texto); text-decoration: none; white-space: nowrap; padding: var(--sp-3) var(--sp-5); border-radius: var(--r-sm); background: var(--brand-soft); }
    .panel__link:hover { background: rgba(31, 111, 224, .2); }
    .table-scroll { overflow-x: auto; }

    /* Listados: la tabla va a ras de la tarjeta (sin separación lateral). Si es el único
       contenido del panel, también a ras arriba; si va tras una cabecera o filtro, full-bleed
       por los lados y abajo. Las esquinas se recortan al radio del panel. En móvil, donde las
       filas se vuelven tarjetas, se restaura el padding. */
    body.app-body .panel > .table-scroll:last-child { margin: 0 -20px -18px; }
    body.app-body .panel > .table-scroll:only-child { margin-top: -18px; }
    body.app-body .panel:has(> .table-scroll:last-child) { overflow: hidden; }
    body.app-body .panel > .table-scroll:last-child .data-table th:first-child,
    body.app-body .panel > .table-scroll:last-child .data-table th:last-child { border-radius: 0; }
    @media (max-width: 760px) {
        body.app-body .panel > .table-scroll:last-child { margin: 0; }
        body.app-body .panel:has(> .table-scroll:last-child) { overflow: visible; }
        /* Panel que es SOLO una tabla: en móvil deja de ser tarjeta (las filas ya son
           tarjetas) para evitar el doble marco. Los paneles con cabecera lo conservan. */
        body.app-body .panel:has(> .table-scroll:only-child) {
            background: transparent; border: 0; box-shadow: none; padding: 0;
        }
    }
    .empty-state { color: var(--ink-3); font-size: var(--fs-md); padding: var(--sp-4) 0; }

    /* N-32. La ausencia se escribe, no se dibuja con un guion. Va en cursiva y
       en el tono apagado para que se distinga de un valor real de un vistazo:
       «Sin asignar» tiene que leerse como estado, no como nombre de alguien. */
    .detail-value--vacio { color: var(--ink-3); font-style: italic; }
    /* La linea que resume lo que falta en un panel: separada del contenido y con
       su enlace de rellenar, porque decir que falta algo sin dar la via para
       arreglarlo es la mitad del trabajo. */
    .empty-state--pendiente { border-top: 1px solid var(--line); margin-top: var(--sp-4); padding-top: var(--sp-4); }

    /* ---------- Próximos actos (lista) ---------- */
    .evt-list { display: flex; flex-direction: column; gap: var(--sp-4); }
    .evt-item { display: flex; align-items: center; gap: var(--sp-5); padding: var(--sp-5); border-radius: var(--r); background: rgba(255, 255, 255, .42); border: 1px solid var(--line); text-decoration: none; transition: background .15s, transform .12s; }
    .evt-item:hover { background: rgba(255, 255, 255, .72); transform: translateX(2px); }
    .evt-date { flex-shrink: 0; width: 46px; text-align: center; background: var(--brand-soft); border-radius: var(--r); padding: var(--sp-3) 0; }
    .evt-date b { display: block; font-size: var(--fs-xl); font-weight: 700; color: var(--brand-700); line-height: 1; font-variant-numeric: tabular-nums; }
    .evt-date span { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .08em; color: var(--brand-700); }
    .evt-time { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-3); font-variant-numeric: tabular-nums; flex-shrink: 0; }
    /* El titulo del acto es el CONTENIDO de esta fila; la etiqueta de estado
       es contexto. Con `min-width: 0` y una etiqueta que no encoge
       (`flex-shrink: 0`), a 768 px el titulo llegaba a cero de ancho: no
       recortado, desaparecido. Es el mismo mecanismo de P-01, y lo destapo un
       cambio de 2 pixeles de espaciado entre letras, que solo fue el detonante.
       Ahora el titulo tiene suelo y quien cede es la etiqueta. */
    .evt-body { flex: 1 1 auto; min-width: 10ch; }
    .evt-body b { display: block; font-size: var(--fs-base); font-weight: 700; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .evt-body small { font-size: var(--fs-sm); color: var(--ink-3); }
    .evt-tag { flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); padding: var(--sp-2) var(--sp-4); border-radius: var(--r-pill); background: var(--c-blue-bg); color: var(--brand-700); }
    .panel__foot { margin-top: 14px; padding-top: var(--sp-5); border-top: 1px solid var(--line); }
    .panel__foot a { display: flex; align-items: center; justify-content: space-between; font-size: var(--fs-md); font-weight: 500; color: var(--brand-texto); text-decoration: none; }

    /* ---------- Mini-mapa territorial ---------- */
    .zmap { position: relative; width: 100%; max-width: 420px; margin: 4px auto 0; }
    .zmap .z-occidental { --tmap-color: var(--ok); --tmap-hover-color: color-mix(in srgb, var(--ok) 84%, white); fill: var(--tmap-current, var(--tmap-color, rgba(22, 124, 69, .8))); transition: fill .2s; }
    .zmap .z-central { --tmap-color: var(--b-500); --tmap-hover-color: color-mix(in srgb, var(--b-500) 84%, white); fill: var(--tmap-current, var(--tmap-color, rgba(31, 111, 224, .82))); transition: fill .2s; }
    .zmap .z-oriental { --tmap-color: var(--c-violet); --tmap-hover-color: color-mix(in srgb, var(--c-violet) 84%, white); fill: var(--tmap-current, var(--tmap-color, rgba(129, 76, 189, .82))); transition: fill .2s; }
    .zmap path:not([class]) { fill: rgba(126, 144, 169, .25); }
    /* Relleno neutro base de cada concejo. Los <path> del SVG llevan class="concejo"
       (no la consume ningún selector funcional), lo que dejaba sin efecto la regla
       path:not([class]) de arriba para los concejos: uno sin zona/cobertura asignada
       caía al fill="var(--b-200)" crudo del SVG y se veía «de otro color». Con :where() la
       especificidad es 0, así que cualquier color de zona o cobertura lo sobreescribe;
       esto solo fija el suelo neutro. */
    .zmap :where(.concejo) { fill: rgba(126, 144, 169, .25); }

    /* Contadores de actos por circunscripción, superpuestos al mapa (con glow) */
    .zbadge { position: absolute; transform: translate(-50%, -50%); z-index: 2; display: grid; place-items: center; min-width: 40px; padding: var(--sp-3) var(--sp-4); border-radius: var(--r); background: var(--zcolor, var(--b-600)); color: #fff; border: 2px solid rgba(255, 255, 255, .92); text-align: center; line-height: 1; box-shadow: 0 6px 16px -4px var(--zglow), 0 0 18px 1px var(--zglow); }
    .zbadge__num { font-size: var(--fs-xl); font-weight: 700; letter-spacing: -.01em; }
    .zbadge__label { margin-top: 2px; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); opacity: .85; }
    .zbadge--occidental { --zcolor: var(--ok); --zglow: rgba(22, 124, 69, .6); left: 25%; top: 50%; }
    .zbadge--central    { --zcolor: var(--b-500); --zglow: rgba(31, 111, 224, .6); left: 53%; top: 55%; }
    .zbadge--oriental   { --zcolor: var(--c-violet); --zglow: rgba(129, 76, 189, .6); left: 74%; top: 47%; }
    /* Sin actos, la insignia se apaga. Pero seguía llevando texto blanco
       encima, y --n-400 es un color de iconos y trazos: 3,26 sobre blanco.
       Apagarla es bajarle el brillo, no volverla ilegible (P-12). */
    .zbadge:not(.is-active) { background: var(--n-500); --zglow: rgba(83, 102, 131, .42); opacity: .82; }
    .zbadge.is-active { animation: zbadge-pulse 2.6s ease-in-out infinite; }
    /* Las chapas de zona pertenecen a "Por zona"; el JS las oculta en "Cobertura".
       Necesario porque .zbadge fija display:grid y eso anula el atributo [hidden]. */
    .zbadge[hidden] { display: none; }
    @keyframes zbadge-pulse {
        0%, 100% { box-shadow: 0 6px 16px -4px var(--zglow), 0 0 16px 1px var(--zglow); }
        50%      { box-shadow: 0 6px 18px -4px var(--zglow), 0 0 30px 7px var(--zglow); }
    }
    @media (max-width: 520px) {
        .zbadge { min-width: 34px; padding: var(--sp-2) var(--sp-3); border-radius: var(--r); }
        .zbadge__num { font-size: var(--fs-lg); }
        .zbadge__label { font-size: var(--fs-xs); }
    }
    @media (prefers-reduced-motion: reduce) {
        .zbadge.is-active { animation: none; }
    }
    .zmap-legend { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); margin-top: 16px; padding-top: var(--sp-6); border-top: 1px solid var(--line); }
    /* Cada vista, su leyenda: "Por zona" muestra la de circunscripciones y "Cobertura"
       la de niveles de actividad. El JS alterna [hidden]; display:grid lo anulaba. */
    .zmap-legend[hidden] { display: none; }
    .zmap-legend__item { display: flex; flex-direction: column; gap: var(--sp-1); }
    .zmap-legend__top { display: flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-md); font-weight: 700; color: var(--ink); }
    .zmap-legend__dot--occidental { background: var(--ok); }
    .zmap-legend__dot--central { background: var(--b-500); }
    .zmap-legend__dot--oriental { background: var(--c-violet); }
    .zmap-legend__sub { font-size: var(--fs-sm); color: var(--ink-3); padding-left: var(--sp-6); }

    /* ---------- Actividad reciente ---------- */
    .act-list { display: flex; flex-direction: column; gap: var(--sp-2); }
    .act-item { display: flex; align-items: flex-start; gap: var(--sp-5); padding: var(--sp-4) 0; }
    .act-item + .act-item { border-top: 1px solid var(--line); }
    .act-icon { width: 34px; height: 34px; border-radius: var(--r-sm); display: grid; place-items: center; flex-shrink: 0; }
    .act-icon svg { width: 17px; height: 17px; }
    .act-icon--blue { background: var(--c-blue-bg); color: var(--c-blue); }
    .act-icon--teal { background: var(--c-teal-bg); color: var(--c-teal); }
    .act-icon--violet { background: var(--c-violet-bg); color: var(--c-violet); }
    .act-icon--amber { background: var(--c-amber-bg); color: var(--c-amber); }
    .act-icon--rose { background: var(--c-rose-bg); color: var(--c-rose); }
    .act-body { flex: 1; min-width: 0; }
    .act-body b { display: block; font-size: var(--fs-md); font-weight: 500; color: var(--ink); line-height: 1.35; }
    .act-body small { font-size: var(--fs-sm); color: var(--ink-3); }
    .act-title { display: block; margin: 0; font-size: var(--fs-md); font-weight: 500; color: var(--ink); line-height: 1.4; }
    .act-subject { color: var(--brand-700); font-weight: 700; text-decoration: none; text-underline-offset: 2px; }
    .act-subject:hover { text-decoration: underline; }
    .act-subject:focus-visible, .act-open:focus-visible { outline: 2px solid var(--brand-700); outline-offset: 2px; border-radius: var(--r-2xs); }
    .act-time { font-size: var(--fs-xs); color: var(--ink-3); white-space: nowrap; flex-shrink: 0; }
    /* Fila de metadatos de la pantalla de Actividad reciente (módulo · autor · abrir). */
    .act-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4); margin-top: 4px; }
    .act-meta__who { font-size: var(--fs-sm); color: var(--ink-3); }
    .act-open { font-size: var(--fs-sm); font-weight: 700; color: var(--brand-700); text-decoration: none; }
    .act-body small .act-open { margin-left: 8px; }
    .act-open:hover { text-decoration: underline; }
    /* Es una acción autónoma, no un enlace en una frase: en táctil su caja
       efectiva tiene que alcanzar el suelo aunque el rótulo sea corto. */
    @media (pointer: coarse) {
        .act-open { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; }
    }

    /* ---------- Tareas urgentes (filas con avatar) ---------- */
    .utask-list { display: flex; flex-direction: column; }
    .utask { display: flex; align-items: center; gap: var(--sp-5); padding: var(--sp-5) var(--sp-2); border-bottom: 1px solid var(--line); }
    .utask:last-child { border-bottom: 0; }
    .utask__check { width: 19px; height: 19px; flex-shrink: 0; margin: 0; accent-color: var(--brand); }
    /* Botón explícito de completar (sustituye al check de autosubmit). */
    .utask__done { flex-shrink: 0; padding: var(--sp-3) var(--sp-5); border: 1px solid var(--line); border-radius: var(--r-pill); background: #fff; color: var(--brand-700); font-size: var(--fs-sm); font-weight: 700; cursor: pointer; transition: background .12s, border-color .12s; }
    .utask__done:hover { background: var(--brand-soft); border-color: rgba(31, 111, 224, .4); }
    .utask__done:focus-visible { outline: 2px solid var(--brand-700); outline-offset: 2px; }
    .utask__main { flex: 1; min-width: 0; }

    .utask__main a:hover { color: var(--brand-texto); }
    .utask__tag { flex-shrink: 0; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); padding: var(--sp-2) var(--sp-4); border-radius: var(--r-xs); background: var(--brand-soft); color: var(--brand-texto); }
    .utask__due { flex-shrink: 0; font-size: var(--fs-md); font-weight: 500; color: var(--ink-2); width: 66px; }
    .utask__due--soon { color: var(--bad); }
    .utask__who { flex-shrink: 0; }
    .avatar-sm { width: 28px; height: 28px; border-radius: var(--r-round); background: var(--brand-grad); color: #fff; display: grid; place-items: center; font-size: var(--fs-xs); font-weight: 700; }
    .avatar-sm--none { background: var(--muted-bg); color: var(--ink-3); }
    @media (max-width: 520px) { .utask__tag, .utask__due { display: none; } }

    /* ---------- Atajos rápidos ---------- */
    .shortcuts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); }
    .shortcut { display: flex; flex-direction: column; align-items: center; gap: var(--sp-4); padding: var(--sp-7) var(--sp-4); border-radius: var(--r-lg); background: rgba(255, 255, 255, .42); border: 1px solid var(--line); text-decoration: none; text-align: center; transition: background .15s, transform .12s, box-shadow .15s; }
    .shortcut:hover { background: #fff; transform: translateY(-2px); box-shadow: var(--shadow-sm); }
    .shortcut__chip { width: 44px; height: 44px; border-radius: var(--r); display: grid; place-items: center; }
    .shortcut__chip svg { width: 21px; height: 21px; }
    .shortcut span { font-size: var(--fs-sm); font-weight: 500; color: var(--ink-2); }
    .shortcuts form { display: contents; }
    .shortcut[type="submit"] { border: 1px solid var(--line); font: inherit; cursor: pointer; }
    .utask form { display: contents; }

    /* ---------- Bento grid del Centro de mando ---------- */
    .bento { display: grid; grid-template-columns: 1fr 1.35fr 1fr; gap: var(--sp-7); margin-bottom: 20px; align-items: stretch; }
    .bento .panel { margin-bottom: 0; display: flex; flex-direction: column; }
    .bento .panel .panel__foot { margin-top: auto; }
    .b-proximos  { grid-column: 1; grid-row: 1; }
    .b-map       { grid-column: 2; grid-row: 1; }
    .b-actividad { grid-column: 3; grid-row: 1; }
    .b-tareas    { grid-column: 1 / span 2; grid-row: 2; }
    .b-atajos    { grid-column: 3; grid-row: 2; }
    .bento--secondary .b-tareas { grid-column: 1 / span 2; grid-row: 1; }
    .bento--secondary .b-atajos { grid-column: 3; grid-row: 1; }
    .b-atajos .shortcuts { flex: 1; align-content: center; }
    .text-overdue { color: var(--bad); font-weight: 700; }

    /* ---------- Centro de mando accionable (Hoy / 48 h / Decisiones) ---------- */
    .command-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(265px, 1fr)); gap: var(--sp-7); margin-bottom: 20px; align-items: stretch; }
    .cmd-panel { margin-bottom: 0; display: flex; flex-direction: column; }
    .cmd-list { display: flex; flex-direction: column; gap: var(--sp-1); }
    /* P-01. Esto era `display: flex` y por eso el título de cada asunto medía
       CERO píxeles de ancho en un teléfono.

       El marcado tiene cuatro hijos: punto de severidad, título, etiqueta de la
       regla y acción esperada. La acción ya declaraba `grid-column: 1 / -1` en
       app.css con el comentario «va en su propia línea», pero dentro de un
       contenedor flex esa propiedad es inerte: la acción no bajaba de línea y
       se comía 154 px de la fila. Como el título es el único hijo con
       `min-width: 0`, era el único que podía encogerse, y encogía hasta cero.
       Medido: ancho 0 con `scrollWidth` de 261 a 347 px, y no sólo en móvil —
       también a 1440 px en las columnas estrechas de la rejilla.

       Con rejilla la intención escrita se cumple sola: tres columnas para la
       primera línea y la acción ocupando la segunda entera. El título vive en
       una pista `minmax(0, 1fr)`, que es lo que le permite recortar con puntos
       suspensivos sin desaparecer.

       El reparto se declara por PAPEL —áreas con nombre—, no por el orden en
       que caen los hijos. No es preciosismo: el mismo componente se usa en el
       Resumen operativo con sus cuatro hijos y en Búsqueda con sólo dos, y una
       rejilla posicional colocaba el título de Búsqueda en la pista del punto,
       dejando la etiqueta a cero ancho. El primer arreglo de P-01 introdujo
       exactamente ese defecto y el arnés lo cazó en la misma corrida. Con áreas
       con nombre, un hijo que no está deja su área vacía y nadie se mueve. */
    .cmd-item {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas:
            "punto titulo meta"
            "punto accion accion"
            "punto clears clears";
        align-items: center;
        column-gap: var(--sp-4);
        row-gap: var(--sp-1);
        padding: var(--sp-4) var(--sp-4);
        border-radius: var(--r);
        text-decoration: none;
        transition: background .15s;
    }
    /* El punto y la etiqueta se colocan aquí porque aquí se definen. El título
       y la acción reciben su área en app.css, donde ya vivían sus otras
       propiedades: repetir un selector en dos hojas de la misma capa es la
       deuda que produjo P-04, y el trinquete de bin/ui_debt.php la canta en
       cuanto aparece. Lo hizo con estas dos, en el commit en que se
       introdujeron. */
    .cmd-item > .cmd-dot { grid-area: punto; }
    .cmd-item__meta { grid-area: meta; }
    .cmd-item__clears { grid-area: clears; }
    /* Sólo las filas canónicas de Attention llevan punto de severidad. En
       ellas la pista de metadatos no puede crecer por el contenido: dos reglas
       largas de Solicitudes se comían el título a 1440 px. Búsqueda reutiliza
       `.cmd-item` sin punto y conserva su reparto natural. */
    .cmd-item:has(> .cmd-dot) {
        grid-template-columns: auto minmax(0, 1fr) minmax(0, 42%);
    }
    .cmd-item:hover { background: var(--surface-2); }
    /* Fila informativa sin destino (p. ej. responsable sin filtro fiable): no debe
       parecer clicable. */
    .cmd-item--static { cursor: default; }
    .cmd-item--static:hover { background: transparent; }
    .cmd-item__meta { font-size: var(--fs-xs); color: var(--ink-3); }

    /* N-05. `rule_label` es una etiqueta CANONICA: el mismo texto sale de la
       misma funcion para el Resumen operativo y para Direccion. Se pintaba con
       dos tratamientos —gris de cuerpo recortado al 42 % en uno, versal de peso
       700 en el otro— y quien pasaba de una pantalla a otra no reconocia que
       era el mismo dato. E-1 unifico el dato; esto unifica como se ve.

       Un solo componente, y lo usan LOS CUATRO sitios donde se pinta
       `rule_label`: Centro de mando, las decisiones y los riesgos de Direccion,
       y el foco de Mi dia. Decia «los dos sitios» y eran cuatro; los otros dos
       lo pintaban con un <span> pelado, que es el defecto que I-2 persigue.
       Lo que queda en `.dir-decision__type` y en `.cmd-item__meta` es
       colocacion, no tipografia: ahi cada pantalla si tiene motivos propios. */
    .rule-label {
        font-size: var(--fs-xs);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
        color: var(--ink-3);
    }
    .attention-severity {
        display: inline-flex;
        align-items: center;
        gap: var(--sp-2);
        color: var(--ink-3);
        font-size: var(--fs-xs);
        font-weight: 700;
        white-space: nowrap;
    }
    .attention-severity::before {
        width: 7px;
        height: 7px;
        border-radius: var(--r-round);
        background: var(--muted);
        content: "";
    }
    .attention-severity--bad::before { background: var(--bad); }
    .attention-severity--warn::before { background: var(--warn); }
    .attention-severity--info::before { background: var(--info); }
    .attention-clears {
        color: var(--ink-3);
        font-size: var(--fs-xs);
        line-height: 1.4;
    }
    .cmd-dot { background: var(--muted); }
    .cmd-dot--ok { background: var(--ok); }
    .cmd-dot--info { background: var(--info); }
    .cmd-dot--warn { background: var(--warn); }
    .cmd-dot--bad { background: var(--bad); }
    .panel__title .cmd-dot { width: 11px; height: 11px; }

    @media (max-width: 1100px) {
        .bento { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
        .b-proximos  { grid-column: 1; grid-row: 1; }
        .b-map       { grid-column: 2; grid-row: 1; }
        .b-tareas    { grid-column: 1 / -1; grid-row: 2; }
        .b-actividad { grid-column: 1; grid-row: 3; }
        .b-atajos    { grid-column: 2; grid-row: 3; }
        .bento--secondary .b-tareas { grid-column: 1; grid-row: 1; }
        .bento--secondary .b-atajos { grid-column: 2; grid-row: 1; }
    }
    @media (max-width: 760px) {
        .bento { grid-template-columns: minmax(0, 1fr); }
        .b-proximos, .b-tareas, .b-map, .b-actividad, .b-atajos { grid-column: 1; grid-row: auto; }
        .bento--secondary .b-tareas, .bento--secondary .b-atajos { grid-column: 1; grid-row: auto; }
    }

    /* ---------- Rejilla genérica de ficha (Territorio/Actos) ---------- */
    .dashboard-grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: var(--sp-7); align-items: start; }
    .dashboard-col { display: flex; flex-direction: column; gap: var(--sp-7); min-width: 0; }
    .dash-subtitle { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-3); font-weight: 700; margin-bottom: 10px; }
    .dash-list { display: flex; flex-direction: column; }
    .dash-list__item { display: flex; gap: var(--sp-5); padding: var(--sp-4) 0; border-bottom: 1px solid var(--line); font-size: var(--fs-base); align-items: center; }
    .dash-list__item:last-child { border-bottom: 0; }
    .dash-list__item--col { flex-direction: column; align-items: flex-start; gap: var(--sp-4); }
    .dash-list__main a { font-weight: 700; color: var(--ink); text-decoration: none; }
    .dash-list__main a:hover { color: var(--brand-texto); }
    .dash-list__main small { color: var(--ink-3); font-size: var(--fs-sm); }
    .badge-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

    /* feed (fichas) */
    .activity-feed { display: flex; flex-direction: column; }
    .activity-feed__item { display: flex; gap: var(--sp-5); padding: var(--sp-4) 0; font-size: var(--fs-md); }
    .activity-feed__dot { width: 7px; height: 7px; border-radius: var(--r-round); background: var(--brand); margin-top: 6px; flex-shrink: 0; position: relative; }
    .activity-feed__item:not(:last-child) .activity-feed__dot::after { content: ""; position: absolute; left: 3px; top: 12px; bottom: -10px; width: 1px; background: var(--line); }
    .activity-feed__body { display: flex; flex-direction: column; gap: var(--sp-1); }
    .activity-feed__body small { color: var(--ink-3); font-size: var(--fs-sm); }

    /* ---------- Navegación / enlaces ---------- */
    .back-link { display: inline-block; font-size: var(--fs-md); color: var(--on-blue-2); text-decoration: none; margin-bottom: 8px; text-shadow: 0 1px 2px rgba(8, 28, 66, .35); }
    .back-link:hover { color: #fff; }
    .link-strong { font-weight: 700; color: var(--ink); text-decoration: none; }
    .link-strong:hover { color: var(--brand-texto); }
    .text-muted { color: var(--ink-3); }

    /* ---------- Filtros ---------- */
    .filters-bar { display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-5); align-items: flex-end; background: var(--surface); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); border: 1px solid var(--surface-border); border-radius: var(--r); padding: var(--sp-5) var(--sp-5); margin-bottom: 20px; box-shadow: var(--shadow-sm); }
    .filters-bar .form-field { margin-bottom: 0; min-width: 150px; }
    .filters-bar .form-field input[type="search"] { min-width: 200px; }
    .filters-bar__actions { display: flex; gap: var(--sp-4); align-items: flex-end; margin-left: auto; }
    /* Filtros avanzados plegables: sub-fila completa de la barra que se oculta con
       [hidden]. Mantiene el mismo gap/alineación que la barra para no romper el
       layout; solo separa filtros básicos (visibles) de avanzados (a demanda). */
    .filters-advanced { display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-5); align-items: flex-end; width: 100%; }
    .filters-advanced[hidden] { display: none; }
    /* Y la barra entera, por el mismo motivo: el atributo [hidden] del navegador
       trae `display: none` con especificidad CERO, así que cualquier regla de
       autor con `display: flex` lo gana. La barra de acciones en bloque se
       ocultaba «correctamente» y seguía ocupando sus 425 px. */
    .filters-bar[hidden] { display: none; }
    .filters-more-btn { align-self: flex-end; }

    /* Filtros plegables en móvil (#2): botón "Filtros" (lo inyecta app.js) que colapsa
       la barra de filtros. En desktop el botón se oculta y la barra se ve normal. */
    .filters-toggle { display: none; }
    @media (max-width: 760px) {
        .filters-toggle {
            display: flex; align-items: center; width: 100%; margin-bottom: 12px;
            padding: var(--sp-5) var(--sp-5); border: 1px solid var(--surface-border); border-radius: var(--r);
            background: #fff; color: var(--ink); font-weight: 700; font-size: var(--fs-base);
            box-shadow: var(--shadow-sm); cursor: pointer;
        }
        .filters-toggle::after {
            content: ""; margin-left: auto; width: 8px; height: 8px;
            border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
            transform: translateY(-2px) rotate(45deg); transition: transform .2s;
        }
        .filters-toggle.is-open::after { transform: translateY(2px) rotate(-135deg); }
        .filters-bar--collapsible { display: none; }
        .filters-bar--collapsible.is-open { display: flex; }
    }

    /* Tarjetas móviles compactas para listados (#1): cada fila se reorganiza con jerarquía
       propia (flex + order) en vez de la conversión genérica por data-label, que dejaba filas
       de ~media pantalla. Aplica a las tablas con .data-table--card. */
    @media (max-width: 760px) {
        /* --- Base común --- */
        body.app-body .data-table--card tbody tr { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-4); padding: var(--sp-5) var(--sp-5); }
        body.app-body .data-table--card td { display: inline-flex; align-items: center; gap: var(--sp-3); width: auto; padding: 0; border: 0; grid-template-columns: none; text-align: left; color: var(--ink-2); font-size: var(--fs-md); }
        body.app-body .data-table--card td::before { content: none; }
        body.app-body .data-table--card .link-strong { font-weight: 700; }
        body.app-body .data-table--card .resp-cell { display: inline-flex; gap: var(--sp-3); }
        /* Formularios inline (asignar / cambiar estado): ocultos en móvil → se gestionan en la ficha. */
        body.app-body .data-table--card .assign-form,
        body.app-body .data-table--card .inline-status { display: none; }
        /* Acento "hoy" como borde izquierdo de la tarjeta (no marca suelta en la 1ª celda). */
        body.app-body .data-table--card .row--today td:first-child { box-shadow: none; }
        .data-table--card tbody tr.row--today { border-left: 3px solid var(--brand); }


        /* ---------- El reparto, por PAPEL y no por posición ----------

           Aquí vivían 48 reglas `td:nth-child(N)`, tres mapas escritos a mano
           que decían en qué orden mostrar las celdas de cada tabla. Era el peor
           defecto de la auditoría del 27/08/2026, y no por estar desfasados:
           por el MECANISMO.

           El número de columnas de estas tablas depende de los permisos. Medido
           sobre el HTML servido de los once roles: Tareas 6 u 8, Incidencias 7,
           8 o 9, Concejos 10 u 11, Actos 9. La casilla de selección entra la
           primera, la acción la última y «Pulso» la quinta, así que cualquiera
           de las tres desplaza el mapa entero. Y el mapa era uno solo, escrito
           contra el rol con MENOS capacidades.

           Consecuencia medida a 375 px con super_admin: la tarjeta de Tareas
           abría con la casilla de selección VACÍA ocupando la línea del título,
           y el nombre de la tarea aparecía en quinta posición. El único rol que
           veía bien esa tarjeta era `lectura`. Quien podía actuar —que es quien
           de verdad usa esa pantalla desde el teléfono— veía un hueco donde
           tenía que ir el nombre.

           Ahora cada celda declara su papel en el marcado (`data-rol`) y el CSS
           ordena por papel. Insertar, quitar o reordenar una columna no rompe
           nada, porque nadie cuenta columnas. Y el arnés puede exigir lo que
           antes no era ni expresable: que toda tabla de tarjeta declare
           exactamente un `titulo` y que ese título sea el primer elemento
           VISUAL de la tarjeta (invariante R-2, verificado sobre los cuatro
           roles que cambian la composición).

           NINGUNA COLUMNA SE OCULTA. El mapa anterior escondía `Responsable` en
           las tres tablas; en Concejos ése es justo el dato que un coordinador
           busca. Se muestran todas, agrupadas por papel, que además hace
           innecesaria la lista de excepciones escritas que pedía R-4. */

        /* 1 · El nombre de la entidad. Abre la tarjeta, ocupa la línea entera y
              se lee en cuerpo mayor. Exactamente uno por fila. */
        body.app-body .data-table--card td[data-rol="titulo"] {
            order: 1;
            flex: 0 0 100%;
            font-size: var(--fs-lg);
            color: var(--ink);
        }

        /* 2 · A qué pertenece: el concejo o el acto. */
        body.app-body .data-table--card td[data-rol="contexto"] {
            order: 2;
            color: var(--ink-2);
        }

        /* 3 · Los datos de apoyo (fecha, prioridad, responsable, tipo…), que
              fluyen en la misma línea separados por puntos. El separador lo
              pone el CSS y no el marcado, así que una celda que falte no deja
              un punto huérfano. */
        body.app-body .data-table--card td[data-rol="meta"] {
            order: 3;
            color: var(--ink-3);
            font-size: var(--fs-sm);
        }
        body.app-body .data-table--card td[data-rol="meta"] ~ td[data-rol="meta"]::before {
            content: "·";
            margin-right: 6px;
            color: var(--ink-3);
        }

        /* 4 · El estado, que es lo que más se consulta de un vistazo. */
        body.app-body .data-table--card td[data-rol="estado"] {
            order: 4;
        }

        /* 5 y 6 · Selección masiva y acción, al final y a la derecha. La
              casilla va DESPUÉS del contenido a propósito: es una
              herramienta de operación en bloque, no la identidad de la fila, y
              ponerla delante es lo que ocultaba el nombre. */
        body.app-body .data-table--card td[data-rol="seleccion"] {
            order: 5;
            margin-left: auto;
        }
        body.app-body .data-table--card td[data-rol="accion"] {
            order: 6;
        }
        /* Si no hay casilla, es la acción la que se va a la derecha. */
        body.app-body .data-table--card tr:not(:has(td[data-rol="seleccion"])) td[data-rol="accion"] {
            margin-left: auto;
        }
    }

    /* ---------- Territorio 78: mapa (ficha/listado) ---------- */
    .terr-map { width: 100%; max-width: 720px; margin: 0 auto; }
    .terr-map .tmap-junta { cursor: pointer; transition: fill .15s; }
    .terr-map .tmap-junta:hover { --tmap-current: var(--tmap-hover-color); }
    .terr-map .tmap-junta:focus { outline: none; }
    .terr-map .tmap-junta:focus-visible { stroke: var(--brand); stroke-width: 2.5; }
    /* Suelo neutro para TODAS las paths del SVG (no solo .concejo): el mapa trae
       fill="var(--b-200)" en línea en algunas paths sin la clase .concejo, que de otro
       modo se verían «de otro color». Mismo enfoque que el mapa de candidaturas
       (#cand-map svg path). Los estados (.tmap-*) ganan por especificidad. */
    .terr-map svg path {
        --tmap-color: rgba(126, 144, 169, .35);
        --tmap-hover-color: rgba(126, 144, 169, .55);
        fill: var(--tmap-current, var(--tmap-color));
    }
    .terr-map svg path[fill="none"] { fill: none; }
    .terr-map .tmap-sin_iniciar {
        --tmap-color: rgba(126, 144, 169, .35);
        --tmap-hover-color: rgba(126, 144, 169, .55);
    }
    .terr-map .tmap-activo {
        --tmap-color: var(--ok);
        --tmap-hover-color: color-mix(in srgb, var(--ok) 84%, white);
    }
    .terr-map .tmap-necesita_refuerzo {
        --tmap-color: var(--warn);
        --tmap-hover-color: color-mix(in srgb, var(--warn) 84%, white);
    }
    .terr-map .tmap-bloqueado {
        --tmap-color: var(--bad);
        --tmap-hover-color: color-mix(in srgb, var(--bad) 84%, white);
    }
    .terr-map .tmap-completado {
        --tmap-color: var(--b-500);
        --tmap-hover-color: color-mix(in srgb, var(--b-500) 84%, white);
    }
    .map-tooltip.tip--sin_iniciar { --accent: var(--n-300); }
    .map-tooltip.tip--activo { --accent: var(--ok); }
    .map-tooltip.tip--necesita_refuerzo { --accent: var(--warn); }
    .map-tooltip.tip--bloqueado { --accent: var(--bad); }
    .map-tooltip.tip--completado { --accent: var(--b-500); }
    .terr-map-legend { display: flex; flex-wrap: wrap; gap: var(--sp-5); justify-content: center; margin-top: 16px; font-size: var(--fs-md); color: var(--ink-2); }
    /* [hidden] debe ganar al display:flex de arriba: el JS alterna el atributo para
       cambiar de leyenda al cambiar de modo y, sin esto, se verían las tres a la
       vez. Mismo caso que .zbadge[hidden] y .cal-days[hidden]. */
    .terr-map-legend[hidden] { display: none; }
    .terr-map-legend span { display: inline-flex; align-items: center; gap: var(--sp-3); }
    .tmap-legend { width: 12px; height: 12px; border-radius: var(--r-2xs); display: inline-block; }
    .tmap-legend--sin_iniciar { background: rgba(126, 144, 169, .55); }
    .tmap-legend--activo { background: var(--ok); }
    .tmap-legend--necesita_refuerzo { background: var(--warn); }
    .tmap-legend--bloqueado { background: var(--bad); }
    .tmap-legend--completado { background: var(--b-500); }

    /* ---------- Mapa: modos de coloreado ----------
       El mapa responde cuatro preguntas distintas sobre los mismos 78 concejos.
       Cada modo pinta con su propio prefijo de clase y gana por especificidad
       (.terr-map[data-mode] .tX = 0,3,0 frente a .terr-map .tmap-X = 0,2,0).
       La circunscripción es la capa estructural y se muestra por defecto. Los
       concejos sin clase de pulso —fuera de ámbito— caen al gris de base en
       los modos operativos.
       El selector usa .seg, el control segmentado comun de la aplicacion. */
    .terr-map[data-mode="pulso"] .tpulse-bien,
    .terr-map[data-mode="antiguedad"] .tage-fresco {
        --tmap-color: var(--ok);
        --tmap-hover-color: color-mix(in srgb, var(--ok) 84%, white);
    }
    .terr-map[data-mode="pulso"] .tpulse-regular,
    .terr-map[data-mode="antiguedad"] .tage-vencido {
        --tmap-color: var(--warn);
        --tmap-hover-color: color-mix(in srgb, var(--warn) 84%, white);
    }
    .terr-map[data-mode="pulso"] .tpulse-mal,
    .terr-map[data-mode="antiguedad"] .tage-caducado {
        --tmap-color: var(--bad);
        --tmap-hover-color: color-mix(in srgb, var(--bad) 84%, white);
    }
    .terr-map[data-mode="pulso"] .tpulse-sin_pulso {
        --tmap-color: rgba(126, 144, 169, .35);
        --tmap-hover-color: rgba(126, 144, 169, .55);
    }
    .terr-map[data-mode="antiguedad"] .tage-sin_pulso {
        --tmap-color: var(--bad-900);
        --tmap-hover-color: color-mix(in srgb, var(--bad-900) 84%, white);
    }

    .map-tooltip.tip--bien, .map-tooltip.tip--fresco { --accent: var(--ok); }
    .map-tooltip.tip--regular, .map-tooltip.tip--vencido { --accent: var(--warn); }
    .map-tooltip.tip--mal, .map-tooltip.tip--caducado { --accent: var(--bad); }
    .map-tooltip.tip--sin_pulso { --accent: var(--n-300); }

    .tmap-legend--bien, .tmap-legend--fresco { background: var(--ok); }
    .tmap-legend--regular, .tmap-legend--vencido { background: var(--warn); }
    .tmap-legend--mal, .tmap-legend--caducado { background: var(--bad); }
    .tmap-legend--sin_pulso { background: rgba(126, 144, 169, .55); }
    .tmap-legend--nunca { background: var(--bad-900); }
    .terr-map-note { margin: 10px 0 0; text-align: center; font-size: var(--fs-sm); color: var(--ink-3); }

    /* Pulso fuera de su antigua pantalla: celda del listado, resumen de la ficha
       y formulario en contexto (Mi concejo y ficha). */
    .cell-pulse { line-height: 1.35; }
    .pulse-meta { display: block; font-size: var(--fs-sm); font-weight: 500; color: var(--ink-3); }
    .pulse-meta--vencido { color: var(--warn); }
    .pulse-meta--caducado, .pulse-meta--sin_pulso { color: var(--c-rose); font-weight: 500; }
    .pulse-summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-4); margin: 0 0 10px; font-weight: 700; }
    .pulse-inline__lead { margin: 0 0 12px; font-size: var(--fs-md); color: var(--ink-2); }
    .pulse-inline .pulse-status { margin: 12px 0; }
    .pulse-inline .create-disclosure .pulse-status { margin-top: 4px; }

    /* ---------- Fichas (detalle) ---------- */
    .detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--sp-6); margin: 0; }
    .detail-item { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0; }
    .detail-item dt { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-3); font-weight: 700; }
    .detail-item dd, .detail-value { margin: 0; font-size: var(--fs-base); color: var(--ink); }
    .detail-item dd a, .detail-value a { color: var(--brand-texto); text-decoration: none; }
    .detail-item dd a:hover { text-decoration: underline; }
    .detail-meta { color: var(--ink-3); font-size: var(--fs-sm); }
    .prose { font-size: var(--fs-base); line-height: 1.6; color: var(--ink); }
    .prose-block { margin-bottom: 16px; }
    .prose-block:last-child { margin-bottom: 0; }

    /* ---------- Formularios largos ---------- */
    .form-narrow { max-width: 800px; }
    .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-7); }
    .form-field--full { grid-column: 1 / -1; }
    .form-field textarea { resize: vertical; }
    .form-actions { display: flex; gap: var(--sp-4); margin-top: 4px; }
    /* Nota de ayuda en formularios: caja sutil, legible, con un filo azul discreto.
       Fondo opaco (no translúcido) para mantener contraste sobre el tema claro. */
    .form-note { position: relative; color: var(--ink-2); font-size: var(--fs-md); line-height: 1.5; margin-top: 12px; max-width: 820px;
        background: var(--b-50); border: 1px solid var(--line);
        border-radius: var(--r-sm); padding: var(--sp-4) var(--sp-5) var(--sp-4) var(--sp-7); }
    .form-note strong { color: var(--ink); font-weight: 700; }
    .form-note a { color: var(--brand-700); font-weight: 500; }

    /* Aviso de orientación (banners de Mi día / Dashboard / Dirección): callout
       azul suave con icono. Más presencia que .form-note, mismo lenguaje visual. */
    /* La ayuda didáctica es un <details> descartable (N-31).

       Nace PLEGADA a propósito: sin JavaScript sigue estando a un clic, y un
       fallo del script no puede dejar 183 px de explicación empujando el
       contenido fuera de la pantalla —que es exactamente lo que hacía la del
       Calendario sobre una ventana de 812—. app.js la abre sola en escritorio,
       donde no estorba, y recuerda por usuario cuáles se han descartado. */
    .hint { position: relative; display: block; margin: 0 0 20px; padding: 0;
        background: var(--b-50); border: 1px solid rgba(31, 111, 224, .18);
        border-radius: var(--r-sm); color: var(--ink-2); font-size: var(--fs-base); line-height: 1.5; box-shadow: var(--shadow-sm); }
    .hint__summary { display: flex; align-items: flex-start; gap: var(--sp-5); padding: var(--sp-5) var(--sp-6) var(--sp-5) var(--sp-8);
        cursor: pointer; list-style: none; font-weight: 500; color: var(--ink-2); }
    .hint__summary::-webkit-details-marker { display: none; }
    /* El triángulo se dibuja aquí: `list-style: none` lo quita, y sin él nada
       indica que el bloque se abre. */
    .hint__summary::after { content: ""; margin-left: auto; flex-shrink: 0; width: 8px; height: 8px; align-self: center;
        border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
        transform: translateY(-2px) rotate(45deg); transition: transform .2s; }
    .hint[open] > .hint__summary::after { transform: translateY(2px) rotate(-135deg); }
    .hint__body { padding: 0 var(--sp-6) var(--sp-5) var(--sp-8); }
    .hint__body p { margin: 0 0 var(--sp-5); }
    .hint__close { border: 1px solid var(--line); background: #fff; color: var(--ink-2);
        border-radius: var(--r-sm); padding: var(--sp-3) var(--sp-5); font-size: var(--fs-sm); font-weight: 500; cursor: pointer; }
    .hint__close:hover { color: var(--ink); border-color: var(--brand); }
    .hint__icon { flex-shrink: 0; width: 18px; height: 18px; color: var(--brand-texto); margin-top: 2px; }
    .hint strong { color: var(--ink); font-weight: 700; }
    .hint a { color: var(--brand-700); font-weight: 500; text-decoration: none; }
    .hint a:hover { text-decoration: underline; }

    /* Edición concurrente: mantiene juntos el valor vigente y la propuesta
       rechazada para que el reintento sea una decisión consciente. */
    .conflict-notice {
        margin: 0 0 var(--sp-6);
        padding: var(--sp-6);
        border: 1px solid var(--warn-line);
        border-left: 4px solid var(--warn);
        border-radius: var(--r);
        background: var(--warn-bg);
    }
    .conflict-notice h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); }
    .conflict-notice p { margin: 0 0 var(--sp-4); }
    .conflict-notice__fields { display: grid; gap: var(--sp-4); margin-top: var(--sp-4); }
    .conflict-notice__field { display: grid; gap: var(--sp-2); padding-top: var(--sp-4); border-top: 1px solid var(--line); }
    .conflict-notice__field span { overflow-wrap: anywhere; }

    /* ---------- Checklists y mini-formularios (actos) ---------- */
    .check-line { display: flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-base); cursor: pointer; padding: var(--sp-2) 0; }
    .check-line input { width: 16px; height: 16px; accent-color: var(--brand); }
    .check-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-1) var(--sp-7); margin-top: 6px; }
    .checklist { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: 6px; }
    /* Variante horizontal: checkboxes en fila que envuelve (p. ej. cargos que asisten). */
    .checklist--inline { flex-direction: row; flex-wrap: wrap; gap: var(--sp-2) var(--sp-7); }
    .checklist--inline .check-line { padding: var(--sp-1) 0; }
    .checklist__item { display: flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-base); color: var(--ink-2); }
    .check { width: 16px; height: 16px; border-radius: var(--r-2xs); border: 2px solid var(--muted-line); display: inline-block; flex-shrink: 0; position: relative; }
    .check.is-done { background: var(--ok); border-color: var(--ok); }
    .check.is-done::after { content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
    .action-row { display: flex; flex-wrap: wrap; gap: var(--sp-6) var(--sp-8); align-items: flex-end; }
    .inline-status { display: flex; align-items: flex-end; gap: var(--sp-4); margin: 0; }
    .inline-status label { font-size: var(--fs-sm); color: var(--ink-3); }
    .inline-status select { padding: var(--sp-4) var(--sp-4); border: 1px solid var(--line); border-radius: var(--r-sm); background: rgba(255,255,255,.7); }
    .mini-form { margin-top: 14px; padding-top: var(--sp-5); border-top: 1px solid var(--line); }
    .mini-form .form-field { margin-bottom: 10px; }
    .mini-form .form-grid { gap: 0 var(--sp-4); }

    /* Ubicaciones: el listado manda y las tareas de alta/edición viven en
       diálogos. La acción de cada registro permanece en su propia fila. */
    .inventory-locations-panel__head,
    .inventory-locations-panel__title { display: flex; align-items: center; gap: var(--sp-4); }
    .inventory-locations-panel__head { justify-content: space-between; }
    .inventory-locations-panel__title { min-width: 0; }
    .inventory-locations-panel__head .btn svg { width: 16px; height: 16px; }
    .inventory-locations-table__actions-head,
    .inventory-locations-table__actions { width: 1%; text-align: right; white-space: nowrap; }
    .inventory-location-edit { min-width: 72px; justify-content: center; }

    dialog.inventory-location-modal { max-width: 760px; }
    .inventory-location-modal__form { display: flex; min-height: 0; flex: 1 1 auto; flex-direction: column; }
    .inventory-location-modal__subtitle { margin-top: var(--sp-1); color: var(--ink-3); font-size: var(--fs-sm); line-height: 1.35; }
    .location-edit-form__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--sp-6); }
    .location-edit-form__grid .form-field { margin-bottom: var(--sp-5); }
    .inventory-location-modal__archive { margin-top: var(--sp-2); padding-top: var(--sp-5); border-top: 1px solid var(--line); }

    /* ---------- Fichas accionables: semáforo, alertas, fases, próximo movimiento ---------- */
    .meta-chip { font-size: var(--fs-sm); font-weight: 500; color: var(--n-600); background: var(--b-100); border: 1px solid rgba(120, 150, 190, .35); border-radius: var(--r-xs); padding: var(--sp-2) var(--sp-4); }
    .panel__count { font-size: var(--fs-md); font-weight: 700; color: var(--ink-3); }

    .readiness { display: flex; align-items: center; gap: var(--sp-6); }
    .readiness__dot { width: 14px; height: 14px; border-radius: var(--r-round); flex-shrink: 0; background: var(--muted); box-shadow: 0 0 0 4px var(--muted-bg); }
    .readiness__text { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
    .readiness__text strong { font-size: var(--fs-lg); color: var(--ink); }
    .readiness__text span { font-size: var(--fs-md); color: var(--ink-2); }
    .readiness__bar { flex: 1; height: 8px; min-width: 80px; border-radius: var(--r-pill); background: var(--muted-bg); overflow: hidden; }
    .readiness__bar span { display: block; height: 100%; border-radius: var(--r-pill); background: var(--muted); }
    .readiness__pct { display: flex; flex-direction: column; align-items: flex-end; flex-shrink: 0; }
    .readiness__pct b { font-size: var(--fs-xl); color: var(--ink); line-height: 1; }
    .readiness__pct small { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-3); }
    .readiness--ok   .readiness__dot { background: var(--ok);   box-shadow: 0 0 0 4px var(--ok-bg); }
    .readiness--ok   .readiness__bar span { background: var(--ok); }
    .readiness--warn .readiness__dot { background: var(--warn); box-shadow: 0 0 0 4px var(--warn-bg); }
    .readiness--warn .readiness__bar span { background: var(--warn); }
    .readiness--bad  .readiness__dot { background: var(--bad);  box-shadow: 0 0 0 4px var(--bad-bg); }
    .readiness--bad  .readiness__bar span { background: var(--bad); }

    .alert-list { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-bottom: 20px; }
    .alert-chip { display: inline-flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-md); font-weight: 700; color: var(--warn); background: var(--gold-bg); border: 1px solid rgba(155, 96, 13, .5); border-radius: var(--r-sm); padding: var(--sp-3) var(--sp-5); }
    .alert-chip svg { width: 14px; height: 14px; flex-shrink: 0; }

    .phase-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(205px, 1fr)); gap: var(--sp-5); }
    .phase-card { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--sp-5); }
    .phase-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-bottom: 10px; }
    .phase-card__head :is(h3, h4) { font-size: var(--fs-sm); font-weight: 700; color: var(--ink); text-transform: uppercase; letter-spacing: var(--tracking-label); }
    .phase-card__count { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-3); background: var(--muted-bg); border-radius: var(--r-xs); padding: var(--sp-1) var(--sp-4); flex-shrink: 0; }
    .phase-card__count.is-complete { color: var(--ok); background: var(--ok-bg); }
    .checklist__item.is-na { color: var(--ink-3); }
    .checklist__item.is-na .check { border-style: dashed; opacity: .6; }
    .checklist__item small { color: var(--ink-3); font-size: var(--fs-xs); font-style: italic; }

    .next-move { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-5); }
    .next-move__main { min-width: 0; }
    .next-move__text { font-size: var(--fs-lg); font-weight: 500; color: var(--ink); line-height: 1.4; }
    .next-move__date { flex-shrink: 0; font-size: var(--fs-md); font-weight: 700; color: var(--info); background: var(--info-bg); border: 1px solid var(--info-line); border-radius: var(--r-sm); padding: var(--sp-3) var(--sp-5); white-space: nowrap; }
    .next-move__date.is-overdue { color: var(--bad); background: var(--bad-bg); border-color: var(--bad-line); }
    .next-move__last { margin-top: 14px; padding-top: var(--sp-5); border-top: 1px solid var(--line); }

    @media (max-width: 600px) {
        .readiness { flex-wrap: wrap; }
        .readiness__bar { order: 3; flex-basis: 100%; }
    }
    .row--today td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
    .row--tomorrow td:first-child { box-shadow: inset 3px 0 0 var(--muted-line); }

    /* ---------- KPI antiguos (compatibilidad) ---------- */
    .kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--sp-5); }
    /* En un teléfono, minmax(180px, 1fr) da UNA columna, y cuatro indicadores
       apilados ocupan 352 px de una ventana de 812 por encima de la primera
       fila de datos. A dos columnas se ven los cuatro igual de bien en 180 px.
       Es la mitad de la diferencia que dejaba la primera solicitud por debajo
       del pliegue (P-05). */
    @media (max-width: 560px) {
        /* Sólo .kpi-grid: .kpi-row no la emite ninguna vista y añadirle reglas
           sería engordar CSS muerto (lo canta el trinquete de bin/ui_debt.php).
           Se retira entera en el tramo E. */
        .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); }

        /* Y la tarjeta se compacta. A tamaño de escritorio mide 166 px de alto
           para enseñar un número: rótulo, cifra a 34 px y una pista debajo. En
           un teléfono eso son 346 px de rejilla por encima del primer dato.
           Compacta —cifra a la derecha del rótulo, pista fuera— mide 64. La
           pista no se pierde para quien la necesita: sigue en el título
           accesible de la tarjeta. */
        .kpi-card {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            align-items: baseline;
            gap: var(--sp-2) var(--sp-4);
            padding: var(--sp-5);
        }
        .kpi-card__label { font-size: var(--fs-sm); }
        .kpi-card__value { font-size: var(--fs-2xl); }
        .kpi-card__hint { display: none; }
    }
    .kpi-card { background: var(--surface); border: 1px solid var(--surface-border); border-radius: var(--r); padding: var(--sp-6) var(--sp-7); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: var(--sp-3); }
    .kpi-card__value { font-size: var(--fs-4xl); font-weight: 700; color: var(--ink); letter-spacing: var(--tracking-display); font-variant-numeric: tabular-nums; }
    /* A-23. Igual que en Adopcion (N-38): un hueco no se pinta con el cuerpo
       de una cifra, porque compite con los KPI que si tienen numero. */
    .kpi-card__value--vacio { font-size: var(--fs-md); font-weight: 500; color: var(--ink-3); letter-spacing: normal; }
    .kpi-card__label { font-size: var(--fs-md); color: var(--ink-2); }
    /* ---------- Responsive ---------- */
    @media (max-width: 1200px) {
        .stat-grid { grid-template-columns: repeat(3, 1fr); }
        .dash-row--3 { grid-template-columns: 1fr 1fr; }
    }
    @media (max-width: 1000px) {
        .dash-row--3, .dash-row--2 { grid-template-columns: 1fr; }
        .dashboard-grid { grid-template-columns: 1fr; }
    }
    @media (max-width: 620px) {
        .stat-grid { grid-template-columns: 1fr 1fr; }
        .form-grid { grid-template-columns: 1fr; }
        .check-grid { grid-template-columns: 1fr; }
        .zmap-legend { grid-template-columns: 1fr; }
        .filters-bar__actions { margin-left: 0; }
    }

    /* ---------- Tareas: asignación, motivo de bloqueo ---------- */
    .assign-form { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: 8px; }
    .assign-form select { padding: var(--sp-3) var(--sp-4); font-size: var(--fs-sm); border: 1px solid var(--line); border-radius: var(--r-sm); background: rgba(255, 255, 255, .7); max-width: 160px; }
    .inline-status { flex-wrap: wrap; }
    .inline-status .reason-input { padding: var(--sp-3) var(--sp-4); font-size: var(--fs-sm); border: 1px solid var(--line); border-radius: var(--r-sm); background: rgba(255, 255, 255, .7); min-width: 130px; }
    .block-reason { display: block; font-size: var(--fs-sm); color: var(--ink-3); margin-top: 4px; max-width: 240px; }

    /* ---------- Formulario de acto: secciones en tarjetas + modales ---------- */
    .form-subhead { margin: 24px 0 12px; }
    .form-subhead :is(h2, h3) { font-size: var(--fs-md); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink); }
    .form-subhead p { font-size: var(--fs-md); color: var(--ink-2); margin-top: 4px; }

    .section-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--sp-5); margin-bottom: 4px; }
    .section-card { text-align: left; cursor: pointer; display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-5) var(--sp-6); border-radius: var(--r-sm); border: 1px solid var(--surface-border); background: var(--surface); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); color: var(--ink); box-shadow: var(--shadow-sm); transition: background .15s, transform .15s, box-shadow .15s; }
    .section-card:hover { background: var(--surface-raised); transform: translateY(-1px); }
    .section-card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    .section-card__name { display: flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-base); font-weight: 700; color: var(--ink); }
    .section-card__hint { font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.35; }
    .section-card__meta { display: flex; align-items: center; gap: var(--sp-4); margin-top: 2px; }
    .section-card__dot { width: 8px; height: 8px; border-radius: var(--r-round); background: var(--ok); flex-shrink: 0; }
    .section-card__flag { font-size: var(--fs-xs); font-weight: 700; color: var(--ok); }
    .section-card__empty { font-size: var(--fs-xs); font-weight: 500; color: var(--ink-3); }
    .section-card.is-filled { border-color: rgba(31, 160, 110, .45); }
    .section-card__progress { display: inline-flex; align-items: center; gap: var(--sp-4); }
    .section-card__bar { width: 64px; height: 5px; border-radius: var(--r-pill); background: var(--line); overflow: hidden; }
    .section-card__barfill { display: block; height: 100%; width: 0; border-radius: var(--r-pill); background: var(--ok); transition: width .3s ease; }
    .section-card__count { font-size: var(--fs-xs); font-weight: 700; color: var(--ink-3); }
    .section-card.is-filled .section-card__count { color: var(--ok); }

    dialog.modal { width: 100%; max-width: 640px; max-height: 90vh; padding: 0; border: 1px solid var(--surface-border); border-radius: var(--r); background: var(--surface-raised); color: var(--ink); box-shadow: var(--shadow-lg); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); }
    dialog.modal[open] { display: flex; flex-direction: column; }
    dialog.modal::backdrop { background: rgba(8, 28, 66, .55); }

    /* ---------- Animación de modales nativos (<dialog>): entrada y salida ----------
       Los <dialog> con showModal()/close() no animan por defecto. @starting-style
       (estado inicial del enter) + transition-behavior: allow-discrete (sobre display
       y overlay) animan AMBOS sentidos sin JS. Apertura ~.28s, cierre ~.2s (más vivo).
       Cubre los modales de acto (.modal) y los del calendario (.cal-dialog).
       Navegadores sin soporte: el modal aparece/desaparece al instante (sin regresión). */
    dialog.modal, dialog.cal-dialog {
        opacity: 0;
        transform: translateY(8px) scale(.97);
        transform-origin: center;
        transition: opacity var(--dur-2, .2s) var(--ease-enter, ease),
                    transform var(--dur-2, .2s) var(--ease-enter, ease),
                    overlay var(--dur-2, .2s) allow-discrete,
                    display var(--dur-2, .2s) allow-discrete;
    }
    dialog.modal[open], dialog.cal-dialog[open] {
        opacity: 1;
        transform: translateY(0) scale(1);
        transition-duration: var(--dur-3, .28s);
    }
    @starting-style {
        dialog.modal[open], dialog.cal-dialog[open] {
            opacity: 0;
            transform: translateY(8px) scale(.97);
        }
    }
    dialog.modal::backdrop, dialog.cal-dialog::backdrop {
        opacity: 0;
        transition: opacity var(--dur-2, .2s) var(--ease-enter, ease),
                    overlay var(--dur-2, .2s) allow-discrete,
                    display var(--dur-2, .2s) allow-discrete;
    }
    dialog.modal[open]::backdrop, dialog.cal-dialog[open]::backdrop {
        opacity: 1;
        transition-duration: var(--dur-3, .28s);
    }
    @starting-style {
        dialog.modal[open]::backdrop, dialog.cal-dialog[open]::backdrop { opacity: 0; }
    }
    @media (prefers-reduced-motion: reduce) {
        dialog.modal, dialog.cal-dialog,
        dialog.modal::backdrop, dialog.cal-dialog::backdrop { transition: none; }
    }
    .modal__head { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-6) var(--sp-7); border-bottom: 1px solid var(--line); flex-shrink: 0; }
    .modal__head :is(h2, h3) { font-size: var(--fs-lg); font-weight: 700; color: var(--ink); }
    .modal__close { margin-left: auto; flex-shrink: 0; width: 32px; height: 32px; border: 0; border-radius: var(--r-xs); background: transparent; color: var(--ink-2); font-size: var(--fs-3xl); line-height: 1; cursor: pointer; }
    .modal__close:hover { background: var(--surface-2); color: var(--ink); }
    /* Es un fieldset y, como hijo flex, conserva min-height:auto por defecto.
       Al crecer Logística empujaba el pie dentro del contenido desplazable. */
    .modal__body { flex: 1 1 auto; min-height: 0; border: 0; margin: 0; padding: var(--sp-7); overflow-x: hidden; overflow-y: auto; }
    .modal__foot { padding: var(--sp-5) var(--sp-7); border-top: 1px solid var(--line); display: flex; justify-content: flex-end; gap: var(--sp-4); flex-shrink: 0; }

    .inventory-material-builder { margin: var(--sp-6) 0 var(--sp-5); padding: var(--sp-5); border: 1px solid var(--surface-border); border-radius: var(--r-sm); background: var(--surface-2); }
    .inventory-material-builder--error { border-color: var(--danger); }
    .inventory-material-builder__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-5); margin-bottom: var(--sp-5); }
    .inventory-material-builder__head h3 { color: var(--ink); font-size: var(--fs-base); }
    .inventory-material-builder__head p { margin-top: 2px; color: var(--ink-2); font-size: var(--fs-sm); line-height: 1.35; }
    .inventory-material-list { display: grid; gap: var(--sp-4); }
    .inventory-material-row { padding: var(--sp-5); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-raised); box-shadow: var(--shadow-sm); }
    .inventory-material-row__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-4); }
    .inventory-material-row__head strong { color: var(--ink); font-size: var(--fs-sm); }
    .inventory-material-row__grid { display: grid; grid-template-columns: minmax(180px, 1.4fr) minmax(150px, 1fr) minmax(90px, .55fr); gap: var(--sp-4); }
    .inventory-material-row__grid .form-field { min-width: 0; margin-bottom: 0; }
    .inventory-material-units { margin-top: var(--sp-4); }
    /* .form-field usa display:flex y gana al [hidden] del navegador. Esta regla
       mantiene el selector de unidades fuera del flujo hasta conocer el tipo. */
    .inventory-material-units[hidden] { display: none; }
    .inventory-material-units .form-note { margin: 0; padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-6); font-size: var(--fs-sm); }
    .inventory-availability { margin: var(--sp-4) 0; padding: var(--sp-3) var(--sp-4); border-left: 3px solid var(--line); border-radius: 0 var(--r-xs) var(--r-xs) 0; background: var(--surface-2); color: var(--ink-2); font-size: var(--fs-sm); line-height: 1.4; }
    .inventory-material-row.is-checking .inventory-availability { border-left-color: var(--brand); color: var(--b-500); }
    .inventory-material-row.is-available { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); }
    .inventory-material-row.is-available .inventory-availability { border-left-color: var(--ok); color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, var(--surface)); }
    .inventory-material-row.is-unavailable { border-color: color-mix(in srgb, var(--danger) 50%, var(--line)); }
    .inventory-material-row.is-unavailable .inventory-availability { border-left-color: var(--danger); color: var(--danger); background: color-mix(in srgb, var(--danger) 7%, var(--surface)); }
    [data-inventory-single].is-checking .inventory-availability { border-left-color: var(--brand); color: var(--b-500); }
    [data-inventory-single].is-available .inventory-availability { border-left-color: var(--ok); color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, var(--surface)); }
    [data-inventory-single].is-unavailable .inventory-availability { border-left-color: var(--danger); color: var(--danger); background: color-mix(in srgb, var(--danger) 7%, var(--surface)); }
    .inventory-material-existing { margin-bottom: var(--sp-5); padding: var(--sp-4); border-radius: var(--r-xs); background: var(--surface); }
    .inventory-material-existing > strong { color: var(--ink); font-size: var(--fs-sm); }
    .inventory-material-existing ul { display: grid; gap: var(--sp-2); margin: var(--sp-3) 0; padding: 0; list-style: none; }
    .inventory-material-existing li { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); color: var(--ink-2); font-size: var(--fs-sm); }
    .inventory-material-empty { margin: 0; padding: var(--sp-4); }
    @media (max-width: 620px) {
        .section-cards { grid-template-columns: 1fr; }
        .inventory-material-builder { padding: var(--sp-4); }
        .inventory-material-builder__head { align-items: stretch; flex-direction: column; }
        .inventory-material-row__grid { grid-template-columns: 1fr; }
        .inventory-material-existing li { align-items: flex-start; flex-direction: column; gap: var(--sp-2); }
    }

    /* =====================================================================
       UX refresh 2026 - modulos de campana
       Jerarquia de mando primero, listas mas limpias y controles progresivos.
       ===================================================================== */
    body.app-body .stat-grid {
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: var(--sp-5);
    }

    body.app-body .stat-card {
        min-height: 132px;
        border-radius: var(--r);
        padding: var(--sp-6);
        gap: var(--sp-4);
    }

    body.app-body .stat-card:hover {
        transform: none;
        box-shadow: var(--shadow);
    }

    body.app-body .stat-card__chip {
        width: 38px;
        height: 38px;
        border-radius: var(--r-sm);
    }

    body.app-body .stat-card__chip svg {
        width: 20px;
        height: 20px;
    }

    body.app-body .stat-card__value {
        font-size: var(--fs-4xl);
        letter-spacing: var(--tracking-display);
    }

    body.app-body .stat-card__label {
        color: var(--ink);
    }

    body.app-body .command-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: var(--sp-5);
    }

    /* Tarjetas de mando/avisos: sin franja superior de color (parecía plantilla). El
       estado se lee en el punto del título y en el contador teñido; tarjeta limpia. */
    body.app-body .cmd-panel {
        border-top: 0;
    }

    .cmd-panel .panel__head { margin-bottom: 12px; }
    .cmd-panel .panel__title { font-size: var(--fs-base); letter-spacing: -.01em; }
    .cmd-panel .cmd-list { flex: 1; }

    body.app-body .cmd-panel .panel__count {
        background: var(--muted-bg);
        /* El contador vive sobre el tinte del panel, no sobre blanco: la
           tinta terciaria ahí queda justa. La secundaria es la correcta para
           una cifra en negrita (P-12). */
        color: var(--ink-2);
        border-radius: var(--r-pill);
        min-width: 24px;
        padding: var(--sp-1) var(--sp-4);
        text-align: center;
        font-variant-numeric: tabular-nums;
    }
    body.app-body .cmd-panel:has(.cmd-dot--ok) .panel__count   { background: var(--ok-bg);   color: var(--ok); }
    body.app-body .cmd-panel:has(.cmd-dot--info) .panel__count { background: var(--info-bg); color: var(--brand-700); }
    body.app-body .cmd-panel:has(.cmd-dot--warn) .panel__count { background: var(--warn-bg); color: var(--warn); }
    body.app-body .cmd-panel:has(.cmd-dot--bad) .panel__count  { background: var(--bad-bg);  color: var(--bad); }

    /* ===================== Centro de avisos — consola de triaje ===================== */

    /* Píldora de severidad reutilizable. */
    .aviso-pill { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); padding: var(--sp-2) var(--sp-4); border-radius: var(--r-pill); flex-shrink: 0; }
    .aviso-pill--bad { background: var(--bad-bg); color: var(--bad); }
    .aviso-pill--warn { background: var(--warn-bg); color: var(--warn); }
    .aviso-pill--info { background: var(--info-bg); color: var(--info); }



    body.app-body .cmd-item {
        position: relative;
        padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-6);
        --accent: transparent;
    }

    body.app-body .cmd-item:hover {
        background: var(--b-50);
    }

    body.app-body .cmd-item--static:hover {
        background: transparent;
    }

    /* Código de color por urgencia, legible de un vistazo: barra lateral + fondo
       tenue por asunto (no solo el punto). info = informativo, warn = atención,
       bad = crítico, ok = resuelto. El hover intensifica el MISMO tono. */
    body.app-body .cmd-item:has(.cmd-dot--info) { background: var(--info-bg); --accent: var(--info); }
    body.app-body .cmd-item:has(.cmd-dot--warn) { background: var(--warn-bg); --accent: var(--warn); }
    body.app-body .cmd-item:has(.cmd-dot--bad)  { background: var(--bad-bg);  --accent: var(--bad); }
    body.app-body .cmd-item:has(.cmd-dot--ok)   { background: var(--ok-bg);   --accent: var(--ok); }
    body.app-body .cmd-item:has(.cmd-dot--info):hover { background: rgba(31, 111, 224, .2); }
    body.app-body .cmd-item:has(.cmd-dot--warn):hover { background: rgba(155, 96, 13, .26); }
    body.app-body .cmd-item:has(.cmd-dot--bad):hover  { background: rgba(199, 35, 57, .24); }
    body.app-body .cmd-item:has(.cmd-dot--ok):hover   { background: rgba(22, 124, 69, .22); }

    /* N-05. Recortaba la etiqueta canonica con puntos suspensivos al 42 %, y
       ese recorte era la mitad del problema: la misma «Incidencia sin
       responsable» salia entera en Direccion y cortada aqui. Se mantiene el
       tope de anchura —la celda no puede comerse el titulo— pero el texto
       envuelve en vez de perderse. Una fila un poco mas alta cuesta menos que
       un rotulo que no se puede leer. */
    body.app-body .cmd-item__meta {
        /* El 42 % ya limita la PISTA. Repetirlo aquí lo aplicaba otra vez
           sobre la celda (17,6 % efectivo) y hacía desbordar sus badges. */
        max-width: none;
        white-space: normal;
        overflow-wrap: anywhere;
    }

    body.app-body .bento {
        gap: var(--sp-5);
    }

    body.app-body .evt-item,
    body.app-body .shortcut,
    body.app-body .phase-card {
        background: var(--n-50);
        border-color: var(--line);
        border-radius: var(--r-sm);
    }

    body.app-body .evt-item:hover,
    body.app-body .shortcut:hover {
        background: #fff;
    }

    body.app-body .evt-date {
        border-radius: var(--r-xs);
    }

    body.app-body .filters-bar {
        align-items: end;
        padding: var(--sp-5);
    }

    body.app-body .filters-bar .form-field {
        flex: 1 1 160px;
    }

    body.app-body .filters-bar .form-field input[type="search"] {
        min-width: 0;
    }

    body.app-body .filters-bar__actions {
        margin-left: 0;
    }

    .quick-filters {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-4);
        margin: -4px 0 16px;
    }

    .quick-filters__link {
        display: inline-flex;
        align-items: center;
        gap: var(--sp-4);
        min-height: 34px;
        padding: var(--sp-4) var(--sp-5);
        border: 1px solid rgba(255, 255, 255, .36);
        border-radius: var(--r-sm);
        color: var(--on-blue);
        background: rgba(255, 255, 255, .1);
        text-decoration: none;
        font-size: var(--fs-md);
        font-weight: 700;
    }

    .quick-filters__link:hover {
        background: rgba(255, 255, 255, .18);
    }

    body.app-body .quick-filters__link {
        color: var(--ink-2);
        background: #fff;
        border-color: var(--surface-border);
        box-shadow: var(--shadow-sm);
    }

    body.app-body .quick-filters__link:hover {
        color: var(--ink);
        background: var(--n-50);
    }


    /* ================================================================
       N-09 / A-34 · Un componente por modelo mental

       `.quick-filters` significaba tres cosas distintas con el mismo aspecto:
       la pestaña de sección en Dirección y Analítica, la pestaña de tipo en
       Avisos, y el filtro rápido de Tareas, Incidencias y Solicitudes. Y en
       Avisos convivía con `.notif-filters`, un segundo componente de filtro con
       otro aspecto, en la misma pantalla y a cuarenta píxeles.

       Dos modelos, y sólo dos:

         · `.section-tabs`  — «en qué sección estoy». Cambia de pantalla o de
           fuente de datos. Se dibuja como pestañas, con subrayado: es el gesto
           que todo el mundo lee como navegación.
         · `.quick-filters` — «qué parte de ESTA lista veo». Píldoras, que es lo
           que ya era.

       El aspecto distinto no es adorno: es lo que impide que un clic que cambia
       de pantalla se lea igual que uno que quita tres filas de la tabla.
       ================================================================ */
    .section-tabs {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-5);
        margin: -4px 0 16px;
        border-bottom: 1px solid var(--surface-border);
    }

    .section-tabs__link {
        display: inline-flex;
        align-items: center;
        gap: var(--sp-3);
        min-height: 34px;
        padding: var(--sp-3) var(--sp-2);
        margin-bottom: -1px;
        border-bottom: 2px solid transparent;
        color: var(--ink-2);
        text-decoration: none;
        font-size: var(--fs-md);
        font-weight: 500;
    }

    .section-tabs__link:hover {
        color: var(--ink);
        border-bottom-color: var(--line);
    }

    .section-tabs__link.is-active {
        color: var(--b-600);
        border-bottom-color: var(--b-600);
        font-weight: 700;
    }

    /* Sobre el azul de la portada, donde el texto va en claro. */
    .section-tabs:not(body.app-body .section-tabs) { border-bottom-color: rgba(255, 255, 255, .28); }
    .section-tabs:not(body.app-body .section-tabs) .section-tabs__link { color: var(--on-blue); }
    .section-tabs:not(body.app-body .section-tabs) .section-tabs__link.is-active {
        color: #fff;
        border-bottom-color: #fff;
    }

    /* Contador dentro de una pestaña. Los dos números del centro de avisos son
       deliberadamente distintos —uno cuenta entregas personales y el otro
       condiciones del sistema— y verlos juntos es lo que enseña que son cosas
       distintas.

       `tabular-nums` no es adorno: sin él, un contador que pasa de 9 a 10
       ensancha la pestaña y desplaza la de al lado. */
    .section-tabs__n {
        display: inline-block;
        min-width: 20px;
        padding: 0 var(--sp-2);
        border-radius: var(--r-pill);
        background: var(--muted-bg);
        color: var(--ink-2);
        font-size: var(--fs-xs);
        font-weight: 700;
        font-variant-numeric: tabular-nums;
        text-align: center;
    }
    .section-tabs__link.is-active .section-tabs__n { background: var(--b-50); color: var(--b-600); }

    .create-disclosure {
        margin-bottom: 20px;
    }

    .create-disclosure > summary {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--sp-4);
        min-height: 38px;
        padding: var(--sp-4) var(--sp-5);
        border-radius: var(--r-sm);
        border: 1px solid rgba(255, 255, 255, .36);
        color: var(--on-blue);
        background: rgba(255, 255, 255, .1);
        font-size: var(--fs-base);
        font-weight: 700;
        cursor: pointer;
        list-style: none;
    }

    .create-disclosure > summary::-webkit-details-marker {
        display: none;
    }

    .create-disclosure > summary::before {
        content: "+";
        width: 18px;
        height: 18px;
        display: grid;
        place-items: center;
        border-radius: var(--r-xs);
        background: rgba(255, 255, 255, .18);
        line-height: 1;
    }

    .create-disclosure[open] > summary::before {
        content: "-";
    }

    body.app-body .create-disclosure > summary {
        color: #fff;
        border-color: var(--b-600);
        background: var(--b-600);
        box-shadow: 0 12px 22px -16px rgba(26, 94, 188, .75);
    }

    body.app-body .create-disclosure > summary::before {
        background: rgba(255, 255, 255, .2);
    }

    .create-disclosure .form-section {
        margin-top: 12px;
    }

    @media (max-width: 640px) {
        .inventory-locations-panel__head { align-items: stretch; flex-direction: column; }
        .inventory-locations-panel__head .btn { width: 100%; justify-content: center; }
        .inventory-locations-table__actions { white-space: normal; }
        .inventory-location-edit { width: 100%; }
        .inventory-location-modal__form .modal__head,
        .inventory-location-modal__form .modal__body,
        .inventory-location-modal__form .modal__foot { padding-right: var(--sp-5); padding-left: var(--sp-5); }
        .inventory-location-modal__form .modal__foot { display: grid; grid-template-columns: 1fr 1fr; }
        .inventory-location-modal__form .modal__foot .btn { justify-content: center; }
        .location-edit-form__grid { grid-template-columns: 1fr; }
    }

    body.app-body .readiness {
        position: relative;
        padding-left: var(--sp-6);
        --accent: var(--muted);
    }

    .readiness--ok { --accent: var(--ok); }
    .readiness--warn { --accent: var(--warn); }
    .readiness--bad { --accent: var(--bad); }

    body.app-body .alert-chip {
        border-radius: var(--r-xs);
    }

    body.app-body .section-card {
        background: #fff;
        border-color: var(--surface-border);
        border-radius: var(--r-sm);
    }

    body.app-body .section-card:hover {
        background: var(--n-50);
        transform: none;
    }

    body.app-body dialog.modal {
        background: #fff;
        border-radius: var(--r);
    }

    @media (max-width: 1200px) {
        body.app-body .stat-grid {
            grid-template-columns: repeat(3, minmax(0, 1fr));
        }

        body.app-body .command-grid {
            grid-template-columns: minmax(0, 1fr);
        }
    }

    @media (max-width: 760px) {
        body.app-body .stat-grid {
            grid-template-columns: 1fr;
        }

        body.app-body .stat-card {
            min-height: auto;
            display: grid;
            grid-template-columns: 42px 1fr auto;
            align-items: center;
            column-gap: var(--sp-5);
        }

        body.app-body .stat-card__chip {
            grid-row: 1 / span 2;
        }

        body.app-body .stat-card__value {
            grid-column: 3;
            grid-row: 1 / span 2;
            font-size: var(--fs-4xl);
        }

        body.app-body .stat-card__sub {
            grid-column: 2;
        }

        /* En un teléfono no caben tres cosas en la primera línea sin que alguna
           se quede sin sitio. Se reparten en tres filas: punto y título arriba,
           etiqueta de la regla debajo, acción esperada al final. Así el nombre
           del asunto —que es el dato que se venía perdiendo— manda. */
        .cmd-item,
        .cmd-item:has(> .cmd-dot) {
            align-items: start;
            grid-template-columns: auto minmax(0, 1fr);
           grid-template-areas:
                "punto titulo"
                ".     meta"
                ".     accion"
                ".     clears";
        }

        /* El prefijo body.app-body NO es adorno: la regla base de la línea 1140
           lo lleva, y sin él esta anulación tiene menos especificidad y PIERDE.
           Ése es el motivo real de que la etiqueta se viera recortada al 42 %
           en móvil pese a existir esta regla desde hace dos iteraciones: nunca
           llegó a aplicarse. Es el mismo mecanismo que produjo P-04. */
        body.app-body .cmd-item__meta {
            grid-column: 2;
            max-width: none;
            white-space: normal;
            overflow: visible;
            /* A la derecha tenía sentido cuando compartía línea con el título.
               Ahora vive en su propia fila, debajo, y ahí alinear a la derecha
               separa el rótulo de lo que nombra. */
            text-align: left;
        }

        .cmd-item__action {
            grid-column: 2;
        }

        .evt-item {
            flex-wrap: wrap;
        }

        .evt-body {
            flex-basis: calc(100% - 118px);
        }

        .evt-tag {
            margin-left: 64px;
        }

        .filters-bar .form-field,
        .filters-bar__actions,
        .filters-bar__actions .btn {
            width: 100%;
        }

        /* Los filtros rápidos pasan a una sola fila que se desplaza en
           horizontal en vez de envolver en tres.

           Medido a 375 px: seis filtros en tres filas de dos ocupaban 132 px
           de una ventana de 812, por encima del contenido y sin que ninguno de
           los seis fuera más importante que la lista que empujaban hacia
           abajo. En una fila desplazable ocupan 44, que es su altura táctil.

           `scroll-snap` para que un filtro nunca quede cortado a medias, y los
           márgenes negativos para que la fila llegue al borde de la pantalla:
           si no, el desplazamiento parece terminar antes de tiempo. */
        .quick-filters {
            margin-top: 0;
            flex-wrap: nowrap;
            overflow-x: auto;
            scroll-snap-type: x proximity;
            -webkit-overflow-scrolling: touch;
            margin-inline: calc(var(--sp-6) * -1);
            padding-inline: var(--sp-6);
            scrollbar-width: none;
        }
        .quick-filters::-webkit-scrollbar { display: none; }

        .quick-filters__link {
            flex: 0 0 auto;
            justify-content: center;
            scroll-snap-align: start;
        }
    }

    /* ---------- Vista/filtro activo (quick-filters) ---------- */
    .quick-filters__link.is-active { color: #fff; background: var(--brand); border-color: var(--brand); }
    body.app-body .quick-filters__link.is-active { color: #fff; background: var(--b-600); border-color: var(--b-600); box-shadow: 0 12px 22px -16px rgba(26, 94, 188, .75); }

    /* ---------- Formulario de acto en rejilla (datos principales + secciones) ---------- */
    .event-form .form-subhead { margin-top: 0; }
    .event-form .form-actions { margin-top: 20px; }
    .event-form .section-cards { margin-bottom: 0; }

    /* ---------- Formularios apilados (acciones en fichas) ---------- */
    .stack-form { display: flex; flex-direction: column; gap: var(--sp-4); }
    .stack-form .form-field { margin-bottom: 0; }
    .stack-form .btn { align-self: flex-start; }
    .stack-form--sep { margin-top: 14px; padding-top: var(--sp-5); border-top: 1px solid var(--line); }

    /* ---------- Comentarios internos ---------- */
    .comment-list { display: flex; flex-direction: column; gap: var(--sp-5); margin-bottom: 16px; }
    .comment { display: flex; gap: var(--sp-4); }
    .comment .avatar-sm { flex-shrink: 0; }
    .comment__main { flex: 1; min-width: 0; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--sp-4) var(--sp-5); }
    .comment__meta { display: flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-sm); color: var(--ink-3); margin-bottom: 4px; }
    .comment__meta strong { color: var(--ink); font-size: var(--fs-md); }
    .comment__del { margin: 0 0 0 auto; }
    .comment__del-btn { border: 0; background: transparent; color: var(--ink-3); font-size: var(--fs-sm); cursor: pointer; padding: var(--sp-1) var(--sp-2); }
    .comment__del-btn:hover { color: var(--bad); }
    .comment__text { font-size: var(--fs-base); color: var(--ink); line-height: 1.45; word-break: break-word; }
    .comment-form { display: flex; flex-direction: column; gap: var(--sp-4); }
    .comment-form textarea { resize: vertical; padding: var(--sp-4) var(--sp-5); border: 1px solid var(--line); border-radius: var(--r); background: rgba(255, 255, 255, .7); width: 100%; color: var(--ink); }
    .comment-form .btn { align-self: flex-start; }
    body.app-body .comment__main { background: var(--b-50); }
    body.app-body .comment-form textarea { background: #fff; border-color: var(--c-blue-bg); border-radius: var(--r-sm); }

    /* ---------- Menciones (@persona / @area) ---------- */
    .mention-field { position: relative; }
    .mention-pop { position: absolute; left: 0; right: 0; top: 100%; z-index: 50; margin-top: 2px; list-style: none; padding: var(--sp-2); background: #fff; border: 1px solid var(--surface-border); border-radius: var(--r-sm); box-shadow: var(--shadow); max-height: 220px; overflow-y: auto; }
    .mention-pop__item { padding: var(--sp-4) var(--sp-4); font-size: var(--fs-md); color: var(--ink); cursor: pointer; border-radius: var(--r-xs); }
    .mention-pop__item.is-active, .mention-pop__item:hover { background: var(--brand-soft); }

    /* ---------- Dirección: briefing, semana, métricas ---------- */
    /* N-26. `.paginacion` comparte aspecto con `.date-nav` porque son la misma
       fila de controles, pero se llama por lo que es. Seis listados usaban la
       clase de la navegacion por fechas del calendario para paginar. */
    .paginacion,
    .date-nav { display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: center; margin-bottom: 20px; }

    .briefing-card__head { display: flex; gap: var(--sp-5); align-items: flex-start; margin-bottom: 14px; padding-bottom: var(--sp-5); border-bottom: 1px solid var(--line); }
    .briefing-time { font-size: var(--fs-xl); font-weight: 700; color: var(--brand-texto); font-variant-numeric: tabular-nums; flex-shrink: 0; min-inline-size: 3.6em; white-space: nowrap; }
    .briefing-card__title h3 { font-size: var(--fs-xl); color: var(--ink); }
    .briefing-card__title p { font-size: var(--fs-md); color: var(--ink-2); margin-top: 4px; display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }


    .metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: var(--sp-5); }
    .metric { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-5) var(--sp-5); border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--line); }
    .metric__value { font-size: var(--fs-4xl); font-weight: 700; color: var(--ink); line-height: 1.05; letter-spacing: var(--tracking-display); font-variant-numeric: tabular-nums; }
    .metric__value--bad { color: var(--bad); }
    .metric__value--warn { color: var(--warn); }
    .metric__label { font-size: var(--fs-sm); color: var(--ink-2); }


    .zbars { display: flex; flex-direction: column; gap: var(--sp-5); }
    .zbar { display: grid; grid-template-columns: 92px 1fr auto; gap: var(--sp-4); align-items: center; }
    .zbar__label { font-size: var(--fs-md); font-weight: 500; color: var(--ink); }
    .zbar__track { height: 10px; border-radius: var(--r-pill); background: var(--muted-bg); overflow: hidden; }
    .zbar__fill--occidental { background: var(--c-green); }
    .zbar__fill--central { background: var(--c-blue); }
    .zbar__fill--oriental { background: var(--c-violet); }
    .zbar__val { font-size: var(--fs-md); font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; }
    /* Variante compacta (dashboard · tarjeta Concejos): solo nombre + barra. */
    .zbars--coverage { margin: 10px 0 2px; }
    .zbar--compact { grid-template-columns: 104px 1fr; }
    .zbars--coverage .zbar__fill { transition: width .5s var(--ease-enter, cubic-bezier(.22, 1, .36, 1)); }
    @media (prefers-reduced-motion: reduce) { .zbars--coverage .zbar__fill { transition: none; } }

    @media (max-width: 1000px) { .week-grid { grid-template-columns: repeat(3, 1fr); } }
    @media (max-width: 620px) { .week-grid { grid-template-columns: 1fr 1fr; } }

    /* ---------- Impresión: solo el contenido ---------- */
    @media print {
        .sidebar, .topbar, .sidebar-backdrop, .no-print { display: none !important; }
        .app-shell, .main-content { display: block; }
        body.app-body .page { display: block; margin: 0; padding: 0; max-width: none; }
        body.app-body { background: #fff; }
        .panel, .briefing-card { box-shadow: none; border-color: var(--n-300); break-inside: avoid; }
        .page-header__title, body.app-body .page-header__title { color: #000; }
    }

    /* ---------- Estado del sistema ---------- */
    .status-list { display: flex; flex-direction: column; }
    .status-item { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) 0; border-bottom: 1px solid var(--line); font-size: var(--fs-base); }
    .status-item:last-child { border-bottom: 0; }
    .status-item__label { color: var(--ink); font-weight: 500; }
    .status-item__detail { margin-left: auto; color: var(--ink-3); font-size: var(--fs-md); text-align: right; }
    .log-box { margin: 0; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--sp-5) var(--sp-5); font-size: var(--fs-sm); line-height: 1.55; color: var(--ink-2); white-space: pre-wrap; word-break: break-word; max-height: 320px; overflow: auto; font-family: ui-monospace, "Cascadia Code", Consolas, monospace; }

    /* ---------- Badges del cargo asistente (ficha de acto y drawer) ---------- */
    .role-badge--presidente                 { background: var(--c-blue-bg); color: var(--b-700); border-color: rgba(31, 111, 224, .45); }
    .role-badge--secretaria_general         { background: var(--c-green-bg); color: var(--ok); border-color: rgba(22, 124, 69, .45); }
    .role-badge--parlamentarios_nacionales  { background: var(--bad-bg); color: var(--bad); border-color: rgba(199, 35, 57, .45); }
    .role-badge--parlamentarios_autonomicos { background: var(--gold-bg); color: var(--gold-ink); border-color: rgba(217, 164, 6, .5); }
    .role-badge--parlamentaria_europea      { background: #fff; color: var(--n-600); border-color: var(--n-400); }
    .role-badge--custom                     { background: var(--n-100); color: var(--n-600); border-color: var(--n-300); }

    /* ---------- Mapa de calor de cobertura (Centro de Mando) ---------- */

    /* Niveles de calor sobre el SVG del mapa: gradiente azul → naranja → rojo */
    .zmap svg path.h-0 { fill: rgba(120, 150, 190, .35); stroke: rgba(97, 119, 152, .55); }
    .zmap svg path.h-1 { fill: rgba(31, 111, 224, .35); stroke: rgba(31, 111, 224, .6); }
    .zmap svg path.h-2 { fill: rgba(22, 124, 69, .45); stroke: rgba(22, 124, 69, .7); }
    .zmap svg path.h-3 { fill: rgba(155, 96, 13, .55); stroke: rgba(155, 96, 13, .8); }
    .zmap svg path.h-4 { fill: rgba(199, 35, 57, .65); stroke: rgba(199, 35, 57, .85); }
    .zmap.is-heat svg path:hover { filter: brightness(1.1); }

    .zmap-legend--heat .zmap-legend__item { padding-right: var(--sp-3); }
    .heat-dot { display: inline-block; width: 10px; height: 10px; border-radius: var(--r-round); margin-right: 6px; vertical-align: -1px; }
    .heat-dot--0 { background: rgba(120, 150, 190, .55); }
    .heat-dot--1 { background: rgba(31, 111, 224, .65); }
    .heat-dot--2 { background: rgba(22, 124, 69, .75); }
    .heat-dot--3 { background: rgba(155, 96, 13, .8); }
    .heat-dot--4 { background: rgba(199, 35, 57, .85); }

    /* Bloque de alertas de cobertura debajo del mapa */
    .coverage-alerts { display: flex; flex-direction: column; gap: var(--sp-4); margin-top: 12px; }
    .coverage-alert { position: relative; padding: var(--sp-4) var(--sp-5) var(--sp-4) var(--sp-7); border-radius: var(--r); border: 1px solid var(--line); background: var(--surface-2); font-size: var(--fs-md); line-height: 1.5; --accent: transparent; }
    .coverage-alert b { display: block; font-size: var(--fs-md); color: var(--ink); margin-bottom: 6px; }
    .coverage-alert--warn { --accent: var(--warn); }
    .coverage-alert--danger { --accent: var(--bad); }
    .coverage-zone { display: inline-block; margin-right: 12px; color: var(--ink-2); font-size: var(--fs-sm); }
    .coverage-zone b { display: inline; color: var(--ink); font-weight: 700; }


    /* ---------- Mi día — hero del saludo + countdown-card ---------- */

    /* HERO: tarjeta con icono institucional, saludo grande y meta con iconos. */
    /* HERO «Mi día» — fondo azul oscuro premium (degradado, sin foto), con chips de
       estado del día y CTA. Texto en blanco (superficie azul, como el sidebar). */
    .myday-hero {
        position: relative; overflow: hidden;
        display: flex; align-items: center; gap: var(--sp-8);
        padding: var(--sp-8) var(--sp-9); margin-bottom: 16px;
        border-radius: var(--r-xl);
        background:
            radial-gradient(120% 160% at 6% 0%, rgba(74, 147, 255, .38), transparent 52%),
            radial-gradient(120% 150% at 100% 100%, rgba(8, 26, 64, .55), transparent 56%),
            linear-gradient(125deg, var(--b-500) 0%, var(--b-600) 46%, var(--b-800) 100%);
        border: 1px solid rgba(120, 170, 255, .22);
        box-shadow: 0 24px 54px -30px rgba(8, 30, 80, .85), inset 0 1px 0 rgba(255, 255, 255, .12);
    }
    .myday-hero__glow {
        position: absolute; right: -60px; top: -90px; width: 360px; height: 360px;
        border-radius: var(--r-round); pointer-events: none;
        background: radial-gradient(circle, rgba(94, 160, 255, .3), transparent 64%);
    }
    .myday-hero__dots {
        position: absolute; top: 16px; right: 24%; width: 150px; height: 80px;
        background-image: radial-gradient(circle, rgba(255, 255, 255, .22) 1px, transparent 2px);
        background-size: 13px 13px; opacity: .5; pointer-events: none;
        -webkit-mask-image: linear-gradient(135deg, #000, transparent 75%);
                mask-image: linear-gradient(135deg, #000, transparent 75%);
    }
    .myday-hero__icon {
        position: relative; z-index: 1; flex-shrink: 0; display: grid; place-items: center;
        width: 76px; height: 76px; border-radius: var(--r-round);
        background: linear-gradient(160deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, .06));
        border: 1px solid rgba(255, 255, 255, .25);
        color: #fff;
        box-shadow: inset 0 1px 2px rgba(255, 255, 255, .35), 0 10px 22px -10px rgba(4, 18, 50, .6);
    }
    .myday-hero__icon svg { width: 38px; height: 38px; }
    .myday-hero__body { flex: 1; min-width: 0; position: relative; z-index: 1; }
    .myday-hero__title { font-size: clamp(26px, 3.4vw, 40px); font-weight: 700; letter-spacing: var(--tracking-hero); color: #fff; line-height: 1.06; margin-bottom: 14px; text-shadow: 0 2px 10px rgba(4, 18, 50, .4); }
    .myday-hero__chips { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-bottom: 14px; }
    .hchip { display: inline-flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) var(--sp-5) var(--sp-4) var(--sp-4); border-radius: var(--r-pill); font-size: var(--fs-md); font-weight: 700; color: var(--b-100); text-decoration: none; background: rgba(255, 255, 255, .09); border: 1px solid rgba(255, 255, 255, .18); transition: transform .14s ease, background .14s ease; }
    a.hchip:hover { transform: translateY(-1px); background: rgba(255, 255, 255, .16); }
    .hchip__ic { flex-shrink: 0; display: grid; place-items: center; width: 24px; height: 24px; border-radius: var(--r-round); background: rgba(255, 255, 255, .16); }
    .hchip__ic svg { width: 15px; height: 15px; }
    .hchip--danger { background: rgba(199, 35, 57, .26); border-color: rgba(255, 120, 142, .5); color: var(--bad-soft); }
    .hchip--danger .hchip__ic { background: rgba(199, 35, 57, .5); color: #fff; }
    .hchip--warn { background: rgba(155, 96, 13, .26); border-color: rgba(255, 196, 106, .5); color: var(--warn-soft); }
    .hchip--warn .hchip__ic { background: rgba(155, 96, 13, .55); color: #fff; }
    .hchip--neutral { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .22); color: var(--b-100); }
    .hchip--neutral .hchip__ic { background: rgba(255, 255, 255, .18); color: #fff; }
    .hchip--phase { background: rgba(35, 168, 104, .26); border-color: rgba(108, 230, 168, .5); color: var(--ok-soft); }
    .hchip--phase .hchip__ic { background: rgba(35, 168, 104, .55); color: #fff; }
    .myday-hero__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-5); font-size: var(--fs-base); color: rgba(226, 236, 255, .82); font-weight: 500; }
    .hmeta { display: inline-flex; align-items: center; gap: var(--sp-4); }
    .hmeta svg { width: 15px; height: 15px; color: rgba(160, 195, 255, .9); flex-shrink: 0; }
    .hmeta__sep { color: rgba(255, 255, 255, .3); font-weight: 400; }
    /* Pill de acceso a Avisos (blanca, resalta sobre el hero azul) con el conteo. */
    .myday-hero__avisos {
        position: relative; z-index: 1; flex-shrink: 0;
        display: inline-flex; align-items: center; gap: var(--sp-5);
        padding: var(--sp-5) var(--sp-7) var(--sp-5) var(--sp-5); border-radius: var(--r-lg); text-decoration: none;
        background: #fff; border: 1px solid rgba(255, 255, 255, .6);
        box-shadow: var(--shadow);
        transition: transform .14s ease, box-shadow .14s ease;
    }
    .myday-hero__avisos:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
    /* La anilla de este aviso vive en la capa `accesibilidad` de app.css, no
       aquí: su contorno cae sobre el degradado azul oscuro del hero, donde el
       azul del suelo de foco daría 1,17 : 1. Es la única discrepancia con el
       suelo en todo el producto y está donde se ve. */
    .myday-hero__avisos-ic { position: relative; flex-shrink: 0; width: 44px; height: 44px; border-radius: var(--r); display: grid; place-items: center; background: var(--brand-soft); color: var(--brand-texto); }
    .myday-hero__avisos-ic svg { width: 22px; height: 22px; }
    .myday-hero__avisos-badge { position: absolute; top: -7px; right: -7px; min-width: 21px; height: 21px; padding: 0 var(--sp-3); border-radius: var(--r-pill); background: var(--bad); color: #fff; font-size: var(--fs-sm); font-weight: 700; display: grid; place-items: center; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(199, 35, 57, .5); font-variant-numeric: tabular-nums; }
    .myday-hero__avisos.is-alert .myday-hero__avisos-badge { animation: aviso-pulse 2.2s ease-in-out infinite; }
    .myday-hero__avisos-txt { display: flex; flex-direction: column; line-height: 1.2; }
    .myday-hero__avisos-txt b { font-size: var(--fs-lg); color: var(--ink); }
    .myday-hero__avisos-txt small { font-size: var(--fs-sm); color: var(--ink-3); }
    @media (prefers-reduced-motion: reduce) { .myday-hero__avisos.is-alert .myday-hero__avisos-badge { animation: none; } }

    /* ROADMAP electoral de «Mi día»: dos bloques de cuenta atrás (elecciones /
       campaña oficial) + línea de fases. Sustituye a la antigua countdown-card.
       Solo se muestra si está configurada campaign.election_date. */
    .roadmap {
        display: grid;
        grid-template-columns: auto auto minmax(0, 1fr);
        gap: var(--sp-6); margin-bottom: 24px;
    }
    .roadmap__stat {
        position: relative; overflow: hidden;
        display: flex; flex-direction: column; justify-content: center; align-items: center;
        min-width: 158px; padding: var(--sp-7) var(--sp-8); border-radius: var(--r-lg); text-align: center;
    }
    .roadmap__num { font-size: clamp(40px, 5vw, 56px); font-weight: 700; line-height: .9; letter-spacing: var(--tracking-hero); }
    .roadmap__unit { margin-top: 8px; font-size: var(--fs-md); font-weight: 700; line-height: 1.3; }
    .roadmap__sub { margin-top: 12px; display: inline-flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-sm); font-weight: 500; }
    .roadmap__sub svg { width: 14px; height: 14px; flex-shrink: 0; }

    .roadmap__stat--primary {
        color: #fff;
        background:
            radial-gradient(120% 95% at 24% 12%, rgba(255, 255, 255, .26), transparent 54%),
            linear-gradient(152deg, var(--b-400) 0%, var(--b-500) 46%, var(--b-700) 100%);
        border: 1px solid rgba(11, 49, 107, .4);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), inset 0 -20px 34px -20px rgba(7, 28, 66, .55), 0 14px 30px -16px rgba(22, 85, 176, .6);
    }
    .roadmap__stat--primary .roadmap__num { color: #fff; text-shadow: 0 2px 10px rgba(5, 24, 60, .35); }
    .roadmap__stat--primary .roadmap__unit { color: rgba(255, 255, 255, .88); }
    .roadmap__stat--primary .roadmap__sub { color: rgba(255, 255, 255, .8); }
    .roadmap__stat--primary .roadmap__sub svg { color: rgba(255, 255, 255, .85); }

    .roadmap__stat--soft {
        color: var(--ink-2);
        background: linear-gradient(158deg, var(--b-100) 0%, var(--c-blue-bg) 100%);
        border: 1px solid rgba(31, 111, 224, .16);
    }
    .roadmap__stat--soft .roadmap__num { color: var(--brand-700); }
    .roadmap__stat--soft .roadmap__sub { color: var(--ink-3); }
    .roadmap__stat--soft .roadmap__sub svg { color: var(--brand-texto); opacity: .8; }

    /* Tarjeta de la línea de fases */
    .roadmap__phase {
        display: flex; flex-direction: column; gap: var(--sp-6);
        padding: var(--sp-7) var(--sp-8); border-radius: var(--r-lg);
        background: linear-gradient(180deg, #fff 0%, var(--b-50) 100%);
        border: 1px solid rgba(31, 111, 224, .14);
        box-shadow: 0 16px 40px -28px rgba(31, 111, 224, .4);
    }
    .roadmap__phase-head { font-size: var(--fs-base); font-weight: 500; color: var(--ink-2); }
    .roadmap__phase-head b { color: var(--brand-700); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); }

    .rsteps { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); }
    .rsteps__track { position: absolute; top: 18px; left: 12.5%; right: 12.5%; height: 3px; border-radius: var(--r-2xs); background: var(--line); }
    /* El ancho del relleno lo fija JS (data-w + initBars en campaign.js) según el
       progreso continuo; la transición lo anima desde 0 al cargar. */
    .rsteps__fill { position: absolute; left: 0; top: 0; height: 100%; width: 0; border-radius: var(--r-2xs); background: var(--brand); transition: width .6s ease; }

    .rstep { display: flex; flex-direction: column; align-items: center; gap: var(--sp-4); text-align: center; padding: 0 var(--sp-2); }
    .rstep__dot {
        position: relative; z-index: 1; display: grid; place-items: center;
        width: 38px; height: 38px; border-radius: var(--r-round);
        background: #fff; border: 2px solid var(--line); color: var(--ink-3);
        transition: background .2s ease, color .2s ease, border-color .2s ease;
    }
    .rstep__dot svg { width: 18px; height: 18px; }
    .rstep__label { font-size: var(--fs-md); font-weight: 700; color: var(--ink); }
    /* --ink-3 se queda en 4,24 sobre el tinte de la tarjeta del calendario
       electoral, por debajo del mínimo AA. A 11px el texto necesita el peldaño
       siguiente de tinta. */
    .rstep__range { font-size: var(--fs-xs); color: var(--ink-2); font-weight: 500; }

    .rstep--done .rstep__dot { background: var(--brand); border-color: var(--brand); color: #fff; }
    .rstep--active .rstep__dot {
        background: var(--brand); border-color: #fff; color: #fff;
        box-shadow: 0 0 0 4px rgba(31, 111, 224, .2), 0 8px 18px -8px rgba(31, 111, 224, .6);
    }
    .rstep--active .rstep__label { color: var(--brand-700); }
    .rstep--upcoming .rstep__dot { background: #fff; border-color: var(--line); color: var(--ink-3); }

    /* Jornada de reflexión: verde (día de descanso) en lugar del azul de campaña. */
    .rstep--rest.rstep--done .rstep__dot { background: var(--ok); border-color: var(--ok); color: #fff; }
    .rstep--rest.rstep--active .rstep__dot {
        background: var(--ok); border-color: #fff; color: #fff;
        box-shadow: 0 0 0 4px var(--ok-bg), 0 8px 18px -8px rgba(22, 124, 69, .6);
    }
    .rstep--rest.rstep--active .rstep__label { color: var(--ok); }

    /* Responsive: empila columnas y oculta urna en pantallas estrechas */
    @media (max-width: 900px) {
        .myday-hero { flex-direction: column; align-items: stretch; gap: var(--sp-7); padding: var(--sp-8) var(--sp-8); }
        .myday-hero__icon { align-self: flex-start; }
        .myday-hero__dots { display: none; }
        .myday-hero__avisos { justify-content: flex-start; }

        .roadmap { grid-template-columns: 1fr 1fr; }
        .roadmap__phase { grid-column: 1 / -1; }
        .roadmap__stat { min-width: 0; }
    }

    .myday-grid {
        display: grid;
        grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
        grid-template-areas: "agenda tasks" "mentions shortcuts";
        gap: var(--sp-7);
    }
    .myday-panel--agenda    { grid-area: agenda; }
    .myday-panel--tasks     { grid-area: tasks; }
    .myday-panel--mentions  { grid-area: mentions; }
    .myday-panel--shortcuts { grid-area: shortcuts; }

    .myday-list { list-style: none; display: flex; flex-direction: column; gap: var(--sp-5); }
    .myday-list--compact { gap: var(--sp-4); }

    .myday-event { display: flex; gap: var(--sp-5); align-items: flex-start; padding: var(--sp-4) var(--sp-5); border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--line); }
    .myday-event__time { min-width: 50px; font-size: var(--fs-base); font-weight: 700; color: var(--brand-700); }
    .myday-event__date { min-width: 130px; font-size: var(--fs-sm); color: var(--ink-3); font-weight: 500; }
    .myday-event__title { font-size: var(--fs-base); font-weight: 700; color: var(--ink); text-decoration: none; }
    .myday-event__title:hover { color: var(--brand-700); }
    .myday-event__meta { font-size: var(--fs-sm); color: var(--ink-2); display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; }
    .myday-event__cand { color: var(--warn); font-weight: 700; }
    .myday-event--compact { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-3) 0; background: transparent; border: 0; }
    .myday-event--compact .myday-event__title { font-size: var(--fs-md); }

    .myday-tasks { position: relative; margin-bottom: 14px; padding-left: var(--sp-6); --accent: var(--line); }
    .myday-tasks--danger { --accent: var(--bad); }
    .myday-tasks--warn   { --accent: var(--warn); }
    .myday-tasks--info   { --accent: var(--brand); }
    .myday-tasks__head { font-size: var(--fs-sm); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-2); margin-bottom: 8px; display: flex; align-items: center; gap: var(--sp-4); }
    .myday-tasks__head span { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 var(--sp-3); border-radius: var(--r-pill); background: var(--muted-bg); color: var(--ink-2); font-size: var(--fs-xs); font-weight: 700; }
    .myday-tasks--danger .myday-tasks__head span { background: rgba(199, 35, 57, .14); color: var(--bad-800); }
    .myday-tasks--warn   .myday-tasks__head span { background: rgba(155, 96, 13, .16); color: var(--warn-800); }
    .myday-task-list { list-style: none; display: flex; flex-direction: column; gap: var(--sp-3); }
    .myday-task { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); padding: var(--sp-3) var(--sp-4); border-radius: var(--r-sm); background: #fff; border: 1px solid var(--line); }
    .myday-task__title { flex: 1; font-size: var(--fs-md); font-weight: 700; color: var(--ink); text-decoration: none; min-width: 0; }
    .myday-task__title:hover { color: var(--brand-700); }
    .myday-task__meta { font-size: var(--fs-sm); color: var(--ink-3); white-space: nowrap; }

    .myday-mentions { list-style: none; display: flex; flex-direction: column; gap: var(--sp-4); }
    .myday-mention { padding: var(--sp-4) var(--sp-5); border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--line); }
    .myday-mention__body { display: block; font-size: var(--fs-md); color: var(--ink); text-decoration: none; line-height: 1.45; margin-bottom: 4px; }
    .myday-mention__body:hover { color: var(--brand-700); }
    .myday-mention__meta { font-size: var(--fs-xs); color: var(--ink-3); }

    .myday-shortcuts { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-4); }
    .myday-shortcut { display: flex; align-items: center; justify-content: center; padding: var(--sp-5) var(--sp-5); border-radius: var(--r); background: #fff; border: 1px solid var(--line); color: var(--ink-2); font-weight: 700; font-size: var(--fs-md); text-decoration: none; transition: background var(--dur-2, .2s), color var(--dur-2, .2s), border-color var(--dur-2, .2s), transform var(--dur-1, .12s); }
    .myday-shortcut:hover { background: var(--brand-soft); color: var(--brand-700); border-color: rgba(31, 111, 224, .3); transform: translateY(-1px); }
    .myday-shortcut--primary { background: var(--brand-grad); color: #fff; border-color: rgba(255, 255, 255, .35); box-shadow: var(--shadow); }
    .myday-shortcut--primary:hover {
        color: #fff;
        background: linear-gradient(145deg, var(--b-400) 0%, var(--b-500) 56%, var(--b-600) 100%);
        border-color: rgba(255, 255, 255, .46);
        box-shadow: 0 13px 26px -13px rgba(15, 83, 176, .8), inset 0 1px 0 rgba(255, 255, 255, .28);
    }

    .myday-foot-link { display: inline-block; margin-top: 12px; font-size: var(--fs-md); font-weight: 700; color: var(--brand-700); text-decoration: none; }
    .myday-foot-link:hover { text-decoration: underline; }

    @media (max-width: 1080px) {
        .myday-grid {
            grid-template-columns: 1fr;
            grid-template-areas: "agenda" "tasks" "mentions" "shortcuts";
        }
    }

    /* ---------- Invitaciones por enlace ---------- */
    .invite-created { background: var(--ok-bg); border: 1px solid var(--ok-line); border-radius: var(--r-sm); padding: var(--sp-5) var(--sp-5); margin-bottom: 16px; }
    .invite-created p { font-size: var(--fs-md); color: var(--ink); margin-bottom: 8px; }
    .invite-link-input { width: 100%; padding: var(--sp-4) var(--sp-5); border: 1px solid var(--line); border-radius: var(--r-sm); background: #fff; font-size: var(--fs-md); color: var(--ink); font-family: ui-monospace, Consolas, monospace; }
    .invite-link-row .invite-link-input { flex: 1; min-width: 220px; width: auto; }
    [data-copy].is-copied { background: var(--ok-bg); color: var(--ok); border-color: var(--ok-line); }
    .role-help { margin: 4px 0 0; padding: 0 0 0 var(--sp-1); list-style: none; display: grid; gap: var(--sp-3); }
    .role-help li { font-size: var(--fs-md); line-height: 1.45; color: var(--ink-2); }
    .role-help strong { color: var(--ink); }

    /* N-10. `.qa-toast` vivía aquí y `.cal-toast` en calendar.css: dos
       componentes para el mismo trabajo. La definición única está en app.css,
       que es donde vive el armazón que comparten los dos módulos. */

    /* ---------- Sugerencias del buscador global (typeahead, creado por JS) ---------- */
    .topbar__search { position: relative; }
    .search-suggest {
        position: absolute;
        top: calc(100% + 6px);
        left: 0;
        right: 0;
        z-index: 250;
        margin: 0;
        padding: var(--sp-3);
        list-style: none;
        background: #fff;
        border: 1px solid var(--line);
        border-radius: var(--r-sm);
        box-shadow: var(--shadow);
        max-height: 60vh;
        overflow: auto;
    }
    .search-suggest__item {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: var(--sp-5);
        padding: var(--sp-4) var(--sp-4);
        border-radius: var(--r-xs);
        font-size: var(--fs-base);
        color: var(--ink);
        cursor: pointer;
    }
    .search-suggest__item.is-active { background: var(--b-50); }
    .search-suggest__meta { color: var(--ink-3); font-size: var(--fs-sm); white-space: nowrap; flex-shrink: 0; }



    /* ---------- Step-up de administración (re-autenticación) ---------- */
    .stepup { max-width: 460px; }
    .stepup-form { margin-top: 6px; }
    .stepup-form .form-actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: 16px; }

    /* ---------- Candidatos ---------- */
    .cand-progress { height: 14px; border-radius: var(--r-pill); background: var(--muted-bg); overflow: hidden; }
    .cand-progress__fill { height: 100%; width: 0; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--b-400), var(--b-500)); transition: width .6s ease; }
    .cand-layout { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: var(--sp-7); align-items: start; }
    .cand-form__actions { margin-top: 14px; }
    /* Uniforma TODOS los rellenos del mapa de candidatos (el SVG trae colores
       nativos por concejo); los bordes (fill="none") se mantienen y el candidato
       gana por especificidad (#cand-map .tmap-candidate). */
    #cand-map svg path {
        --tmap-color: rgba(126, 144, 169, .3);
        --tmap-hover-color: rgba(126, 144, 169, .5);
        transition: fill .2s;
    }
    #cand-map svg path[fill="none"] { fill: none; }
    #cand-map .tmap-candidate {
        --tmap-color: var(--b-700);
        --tmap-hover-color: color-mix(in srgb, var(--b-700) 84%, white);
    }
    #cand-map .tmap-junta { cursor: default; }
    #cand-map.is-clickable .tmap-junta { cursor: pointer; }
    #cand-map .tmap-junta.is-selected { stroke: var(--b-800); stroke-width: 2.2; }
    #cand-map .tmap-junta:focus { outline: none; }
    #cand-map .tmap-junta:focus-visible { stroke: var(--brand); stroke-width: 2.2; }
    .tmap-legend--candidate { background: var(--b-700); }
    .tmap-legend--empty { background: rgba(126, 144, 169, .55); }
    .map-tooltip.tip--candidate { --accent: var(--b-700); }
    /* U-1. La columna derecha agrupa mapa y formulario para que el LISTADO
       pueda ir primero en el marcado sin perder la vista a dos columnas.
       Apilados y sin hueco extra: cada .panel ya trae su margen inferior. */
    .cand-side { display: block; min-width: 0; }
    .cand-map-print__header { display: none; }
    @media (max-width: 900px) { .cand-layout { grid-template-columns: 1fr; } }

    /* Hoja de Candidatos: se activa de forma temporal al imprimir el mapa.
       El aislamiento por clase permite añadir después título institucional,
       fecha de corte o métricas sin volver a tocar la vista de trabajo. */
    @media print {
        body.app-body.is-printing-candidates-map .page > :not(.cand-layout),
        body.app-body.is-printing-candidates-map .cand-layout > :not(.cand-side),
        body.app-body.is-printing-candidates-map .cand-side > :not(.cand-map-print),
        body.app-body.is-printing-candidates-map .cand-map-print > .panel__head,
        body.app-body.is-printing-candidates-map .cand-map-print .panel__link,
        body.app-body.is-printing-candidates-map .cand-map-print .map-tooltip { display: none !important; }
        body.app-body.is-printing-candidates-map .cand-layout,
        body.app-body.is-printing-candidates-map .cand-side { display: block; margin: 0; }
        body.app-body.is-printing-candidates-map .cand-map-print { width: 100%; margin: 0; padding: 0; border: 0; background: #fff; box-shadow: none; }
        body.app-body.is-printing-candidates-map .cand-map-print__header { display: grid; grid-template-columns: 156px 1px minmax(250px, 1fr) auto; align-items: center; gap: var(--sp-7); margin-bottom: var(--sp-10); color: var(--b-700); }
        body.app-body.is-printing-candidates-map .cand-map-print__header img { width: 156px; height: auto; }
        body.app-body.is-printing-candidates-map .cand-map-print__divider { width: 1px; height: 70px; background: var(--b-500); }
        body.app-body.is-printing-candidates-map .cand-map-print__title { margin: 0; font-size: var(--fs-3xl); font-weight: 700; line-height: 1; letter-spacing: var(--tracking-heading); text-transform: uppercase; }
        body.app-body.is-printing-candidates-map .cand-map-print__date { justify-self: end; font-size: var(--fs-2xl); font-weight: 700; font-variant-numeric: tabular-nums; }
        body.app-body.is-printing-candidates-map #cand-map { width: 100%; max-width: none; }
        body.app-body.is-printing-candidates-map #cand-map svg { width: 100%; height: auto; max-height: 155mm; }
        body.app-body.is-printing-candidates-map .terr-map-legend { margin-top: 20px; color: var(--n-600); font-size: var(--fs-lg); }
        body.app-body.is-printing-candidates-map .tmap-legend { width: 14px; height: 14px; border: 5px solid currentColor; background: transparent !important; border-radius: 0; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
        body.app-body.is-printing-candidates-map .tmap-legend--candidate { color: var(--b-700); }
        body.app-body.is-printing-candidates-map .tmap-legend--empty { color: var(--n-300); }
    }

    /* =====================================================================
       DIRECCIÓN — Rediseño ejecutivo (Hoy · Briefing · Semana · Métricas)
       Inventario maestro §2 del blueprint. Todo bajo body.app-body (R-CSS-2),
       solo tokens de :root. Prefijos sin colisión: .dir-* (Hoy/Semana),
       .dir-brief* (Briefing), .dir-mx-* (Métricas). Reusa .panel/.badge/.btn/
       .meta-chip/.empty-state/.quick-filters/.stat-card/.cmd-list/.dash-row.
       ===================================================================== */

    /* ---------- Común a Dirección ---------- */
    .dir-block { margin-bottom: 20px; }
    .dir-block:last-child { margin-bottom: 0; }

    /* N-37. Encabezado de ambito sobre una fila de indicadores. Es un titulo de
       verdad y no un `span`: separa dos grupos que antes eran uno, y esa
       separacion tiene que existir tambien para quien navega por encabezados.
       Discreto a proposito: manda la cifra, no el rotulo. */
    .dir-ambito__title {
        font-size: var(--fs-sm);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
        color: var(--ink-3);
        margin: 0 0 var(--sp-3);
    }
    /* El grupo global tiene dos tarjetas: sin tope, se estiran a media pantalla
       cada una y pesan mas que las cuatro de la semana, que es justo lo
       contrario de lo que se queria decir. */
    .stat-grid--global { max-width: 640px; }

    /* Chip "Sin responsable" (modificador de .meta-chip) */
    /* A-3. `--bad` sobre su propio tinte daba 3,86 sobre la superficie del panel.
       Solo se ve cuando la agenda tiene alertas, que es un estado que el banco
       normal no produce: lo canto el banco saturado. */
    .meta-chip--alert { color: var(--bad-800); background: var(--bad-bg); border-color: var(--bad-line); }

    /* ---------- HOY ---------- */
    /* Statusbar: píldoras de estado del día */
    .dir-statusbar { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-bottom: 20px; }
    .dir-status-pill {
        display: inline-flex; align-items: center; gap: var(--sp-4);
        padding: var(--sp-4) var(--sp-5); border-radius: var(--r-pill);
        font-size: var(--fs-md); font-weight: 700; color: var(--ink-2);
        background: var(--surface); border: 1px solid var(--surface-border);
        -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur);
        box-shadow: var(--shadow-sm);
    }
    body.app-body .dir-status-pill b { color: var(--ink); font-variant-numeric: tabular-nums; }
    .dir-status-pill__dot { background: var(--muted); box-shadow: 0 0 0 3px var(--muted-bg); }
    .dir-status-pill--ok    { color: var(--ok); background: var(--ok-bg); border-color: var(--ok-line); }
    .dir-status-pill--ok    .dir-status-pill__dot,
    body.app-body .dir-status-pill--ok    b { color: var(--ok); }
    .dir-status-pill--ok    .dir-status-pill__dot { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-bg); }
    .dir-status-pill--warn  { color: var(--warn-800); background: var(--warn-bg); border-color: var(--warn-line); }
    .dir-status-pill--warn  .dir-status-pill__dot,
    body.app-body .dir-status-pill--warn  b { color: var(--warn-800); }
    .dir-status-pill--warn  .dir-status-pill__dot { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-bg); }
    .dir-status-pill--bad   { color: var(--bad-800); background: var(--bad-bg); border-color: var(--bad-line); }
    .dir-status-pill--bad   .dir-status-pill__dot,
    body.app-body .dir-status-pill--bad   b { color: var(--bad-800); }
    .dir-status-pill--bad   .dir-status-pill__dot { background: var(--bad); box-shadow: 0 0 0 3px var(--bad-bg); }
    .dir-status-pill--muted { color: var(--muted); background: var(--muted-bg); border-color: var(--muted-line); }
    .dir-status-pill--muted .dir-status-pill__dot { background: var(--muted); }

    /* Requiere decisión */
    .dir-decision-list { gap: var(--sp-4); }
    .dir-decision {
        display: grid; grid-template-columns: 138px 1fr auto; gap: var(--sp-4) var(--sp-5); align-items: center;
        padding: var(--sp-5) var(--sp-5); border-radius: var(--r-sm);
        background: var(--surface-2); border: 1px solid var(--line);
    }
    /* Solo colocacion: la tipografia la pone .rule-label (N-05). */
    .dir-decision__type { align-self: start; }
    .dir-decision__body { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
    .dir-decision__title { text-decoration: none; }
    a.dir-decision__title:hover { color: var(--brand-700); }
    .dir-decision__meta { font-size: var(--fs-sm); color: var(--ink-3); display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center; }
    .dir-decision__cta { flex-shrink: 0; white-space: nowrap; }

    /* Riesgos abiertos */
    .dir-risk-list { gap: var(--sp-1); }
    .dir-risk { display: flex; gap: var(--sp-5); align-items: flex-start; padding: var(--sp-5) var(--sp-2); border-top: 1px solid var(--line); }
    .dir-risk:first-child { border-top: 0; }
    .dir-risk__sev { width: 10px; height: 10px; border-radius: var(--r-round); flex-shrink: 0; margin-top: 6px; background: var(--muted); box-shadow: 0 0 0 3px var(--muted-bg); }
    .dir-risk__sev--bad   { background: var(--bad);   box-shadow: 0 0 0 3px var(--bad-bg); }
    .dir-risk__sev--warn  { background: var(--warn);  box-shadow: 0 0 0 3px var(--warn-bg); }
    .dir-risk__sev--muted { background: var(--muted); box-shadow: 0 0 0 3px var(--muted-bg); }
    .dir-risk__body { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: var(--sp-2); }
    .dir-risk__head { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-4); align-items: baseline; }
    .dir-risk__title {
        font-size: var(--fs-base); font-weight: 700; color: var(--ink); text-decoration: none;
        min-width: 0; overflow: hidden; text-overflow: ellipsis;
    }
    a.dir-risk__title:hover { color: var(--brand-700); }
    .dir-risk__meta { font-size: var(--fs-sm); color: var(--ink-3); display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center; }

    /* Agenda crítica */
    .dir-agenda-list { gap: var(--sp-4); }
    .dir-agenda {
        position: relative;
        display: flex; gap: var(--sp-5); align-items: flex-start;
        padding: var(--sp-5) var(--sp-5) var(--sp-5) var(--sp-7); border-radius: var(--r-sm);
        background: var(--surface-2); border: 1px solid var(--line);
        --accent: var(--line);
    }
    .dir-agenda--alert { --accent: var(--warn); background: var(--warn-bg); }
    .dir-agenda__time { min-inline-size: 3.6em; white-space: nowrap; flex-shrink: 0; font-size: var(--fs-base); font-weight: 700; color: var(--brand-700); font-variant-numeric: tabular-nums; }
    .dir-agenda__title { text-decoration: none; }
    a.dir-agenda__title:hover { color: var(--brand-700); }
    .dir-agenda__meta { font-size: var(--fs-sm); color: var(--ink-2); display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center; }
    .dir-agenda__gaps { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
    .dir-agenda__owner { font-size: var(--fs-sm); color: var(--ink-3); }

    /* Responsables y carga */
    .dir-load { display: flex; flex-direction: column; gap: var(--sp-1); }
    .dir-load__subhead { margin: 16px 0 6px; }
    .dir-load__subhead:first-child { margin-top: 0; }
    /* A-25. La cola que dice cuantos quedaron fuera del panel de carga. Va
       apagada: es contexto, no un dato mas de la lista. */
    .dir-load__resto { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); color: var(--ink-3); }
    .dir-load__row {
        display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-5);
        padding: var(--sp-4) var(--sp-2); border-top: 1px solid var(--line);
    }
    .dir-load__row:first-child { border-top: 0; }
    .dir-load__row--alert { position: relative; padding-left: var(--sp-5); }
    .dir-load__name {
        flex: 1; min-width: 0; font-size: var(--fs-base); font-weight: 700; color: var(--ink);
        text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    a.dir-load__name:hover { color: var(--brand-700); }
    body.app-body .dir-load__name small { display: block; font-size: var(--fs-sm); font-weight: 500; color: var(--ink-3); }
    .dir-load__stats { display: flex; flex-wrap: wrap; gap: var(--sp-3); flex-shrink: 0; }
    .dir-load__stat {
        font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2);
        background: var(--muted-bg); border: 1px solid var(--muted-line);
        border-radius: var(--r-xs); padding: var(--sp-1) var(--sp-4); font-variant-numeric: tabular-nums;
    }
    .dir-load__stat--warn { color: var(--warn); background: var(--warn-bg); border-color: var(--warn-line); }
    .dir-load__stat--bad  { color: var(--bad); background: var(--bad-bg); border-color: var(--bad-line); }

    /* ---------- BRIEFING ---------- */
    /* El panel contiene cabecera + rejilla. La regla flex heredada de la
       primera versión los ponía en la misma fila y encogía `.metric-grid` a
       una columna de 156 px, dejando vacío casi todo el panel. La rejilla ya
       gobierna su propia composición: cuatro columnas en escritorio y dos en
       móvil. */
    .dir-brief__summary { display: block; }
    .dir-brief__sub { font-size: var(--fs-md); color: var(--ink-3); }
    .dir-brief__open { flex-shrink: 0; white-space: nowrap; }
    /* Barra lateral de triaje del briefing: riesgo (rojo) > falta (ámbar) > listo (verde).
       Permite leer la columna de actos de un vistazo sin entrar en cada tarjeta. */
    body.app-body .briefing-card { position: relative; padding-left: var(--sp-9); --accent: var(--line); }
    .briefing-card--ready   { --accent: var(--ok); }
    .briefing-card--pending { --accent: var(--warn); }
    .briefing-card--risk { border-color: var(--bad-line); --accent: var(--bad); box-shadow: 0 12px 34px -16px rgba(199, 35, 57, .3); }
    body.app-body .briefing-card--risk .briefing-card__head { border-bottom-color: var(--bad-line); }
    .dir-brief__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--sp-5); }
    .detail-value--risk { color: var(--bad); font-weight: 500; }
    .dir-brief__missing {
        margin-top: 14px; padding: var(--sp-5) var(--sp-5); border-radius: var(--r-sm);
        background: var(--warn-bg); border: 1px solid var(--warn-line);
    }
    .dir-brief__missing-list { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin: 8px 0 0; padding: 0; list-style: none; }
    body.app-body .dir-brief__missing-list li {
        font-size: var(--fs-sm); font-weight: 500; color: var(--warn);
        background: #fff; border: 1px solid var(--warn-line);
        border-radius: var(--r-pill); padding: var(--sp-2) var(--sp-4);
    }
    .dir-brief__missing-tag {
        font-size: var(--fs-sm); font-weight: 700; color: var(--warn);
        background: #fff; border: 1px solid var(--warn-line);
        border-radius: var(--r-xs); padding: var(--sp-1) var(--sp-4);
    }

    /* ---------- SEMANA ---------- */
    .dir-week-days { display: flex; flex-direction: column; gap: var(--sp-4); }
    .dir-day {
        display: grid; grid-template-columns: 88px 1fr; gap: var(--sp-2) var(--sp-5); align-items: start;
        padding: var(--sp-5) var(--sp-5); border-radius: var(--r-sm);
        background: var(--surface-2); border: 1px solid var(--line);
    }
    .dir-day--today { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
    .dir-day__head { display: flex; flex-direction: column; gap: var(--sp-1); }
    .dir-day__dow { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-3); }
    .dir-day--today .dir-day__dow { color: var(--brand-texto); }
    .dir-day__num { font-size: var(--fs-3xl); font-weight: 700; color: var(--ink); line-height: 1; font-variant-numeric: tabular-nums; }
    .dir-day__badge {
        align-self: start; margin-top: 6px; font-size: var(--fs-xs); font-weight: 700;
        color: var(--ink-3); background: var(--muted-bg); border: 1px solid var(--muted-line);
        border-radius: var(--r-pill); padding: var(--sp-1) var(--sp-4); width: fit-content;
    }
    .dir-day__body { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
    .dir-day__empty { color: var(--ink-3); font-size: var(--fs-md); }
    .dir-evt { display: flex; gap: var(--sp-4); align-items: baseline; width: 100%; min-width: 0; overflow: hidden; }
    .dir-evt__time { min-inline-size: 3.6em; white-space: nowrap; flex-shrink: 0; font-size: var(--fs-md); font-weight: 700; color: var(--brand-texto); font-variant-numeric: tabular-nums; }
    .dir-evt__main { overflow: hidden; }
    .dir-evt__title {
        display: block; max-width: 100%;
        font-size: var(--fs-base); font-weight: 700; color: var(--ink); text-decoration: none;
        min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    a.dir-evt__title:hover { color: var(--brand-700); }
    .dir-evt__meta { font-size: var(--fs-sm); color: var(--ink-3); display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); align-items: center; }
    /* A-3. `--c-amber` sobre el fondo claro de la ficha del dia daba 3,29. La
       galeria lo canto: ninguna pantalla del banco pinta un acto con candidato
       dentro de la semana de campana. */
    .dir-evt__cand { color: var(--warn-800); font-weight: 700; }

    /* ---------- MÉTRICAS ---------- */
    .dir-mx-range { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-bottom: 14px; }
    .dir-mx-compare-note { font-size: var(--fs-md); color: var(--ink-2); margin-bottom: 16px; }
    body.app-body .dir-mx-compare-note strong { color: var(--ink); font-weight: 700; }
    .dir-mx-block { margin-bottom: 20px; }
    .dir-mx-block:last-child { margin-bottom: 0; }
    .dir-mx-block__interpret {
        position: relative;
        font-size: var(--fs-md); line-height: 1.5; color: var(--ink-2);
        margin-bottom: 14px; padding: var(--sp-4) var(--sp-5) var(--sp-4) var(--sp-7); border-radius: var(--r-sm);
        background: var(--surface-2); border: 1px solid var(--line);
        --accent: var(--muted);
    }
    .dir-mx-block__interpret--ok   { --accent: var(--ok); background: var(--ok-bg); }
    .dir-mx-block__interpret--warn { --accent: var(--warn); background: var(--warn-bg); }
    .dir-mx-block__interpret--bad  { --accent: var(--bad); background: var(--bad-bg); }
    .dir-mx-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--sp-5); }
    .dir-mx-card {
        position: relative; display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--sp-3) var(--sp-4);
        padding: var(--sp-5) var(--sp-6); border-radius: var(--r-sm);
        background: var(--surface-2); border: 1px solid var(--line);
    }
    .dir-mx-card--ok    { border-color: var(--ok-line); }
    .dir-mx-card--warn  { border-color: var(--warn-line); }
    .dir-mx-card--bad   { border-color: var(--bad-line); background: var(--bad-bg); }
    .dir-mx-card--muted { opacity: .92; }
    .dir-mx-card__dot { width: 9px; height: 9px; border-radius: var(--r-round); flex-shrink: 0; margin-top: 6px; background: var(--muted); }
    .dir-mx-card--ok   .dir-mx-card__dot { background: var(--ok); }
    .dir-mx-card--warn .dir-mx-card__dot { background: var(--warn); }
    .dir-mx-card--bad  .dir-mx-card__dot { background: var(--bad); }
    .dir-mx-card__main { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: var(--sp-2); }
    .dir-mx-card__value { font-size: var(--fs-4xl); font-weight: 700; color: var(--ink); line-height: 1; letter-spacing: var(--tracking-display); font-variant-numeric: tabular-nums; }
    /* N-38. Un hueco sin datos no es una cifra: no se pinta con el cuerpo de
       una. Al tamano de la etiqueta, «Sin datos todavia» se lee como lo que es
       —una ausencia— y deja de competir visualmente con los KPI que si tienen
       numero. */
    .dir-mx-card__value--vacio { font-size: var(--fs-md); font-weight: 500; color: var(--ink-3); line-height: 1.3; }
    .dir-mx-card__label { font-size: var(--fs-md); color: var(--ink-2); font-weight: 500; min-width: 0; overflow-wrap: break-word; }
    .dir-mx-card__delta { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-3); display: inline-flex; align-items: center; gap: var(--sp-2); font-variant-numeric: tabular-nums; }
    .dir-mx-card__delta--up    { }
    .dir-mx-card__delta--down  { }
    .dir-mx-card__delta--flat  { color: var(--ink-3); }
    .dir-mx-card__delta--muted { color: var(--ink-3); }
    .dir-mx-card__delta--ok    { color: var(--ok); }
    .dir-mx-card__delta--warn  { color: var(--warn); }
    .dir-mx-card__delta--bad   { color: var(--bad); }
    .dir-mx-card__note { flex-basis: 100%; width: 100%; margin: 2px 0 0; font-size: var(--fs-sm); color: var(--ink-3); line-height: 1.45; }
    .dir-mx-card__drill { flex-basis: 100%; width: 100%; font-size: var(--fs-sm); font-weight: 700; color: var(--brand-700); text-decoration: none; margin-top: 2px; }
    .dir-mx-card__drill:hover { text-decoration: underline; }

    /* =========================================================
       DIRECCIÓN — Responsive
       Componentes compartidos UNA sola vez (R-CSS-3): .zbar/.metric-grid/.week-grid.
       ========================================================= */
    @media (max-width: 520px) {
        body.app-body .week-grid { grid-template-columns: 1fr; }
        body.app-body .zbar, body.app-body .zbar--compact { grid-template-columns: 1fr auto; }
        body.app-body .zbar__label { grid-column: 1 / -1; }
        body.app-body .metric-grid { grid-template-columns: 1fr 1fr; }
    }

    /* 620px — colapso intermedio por pantalla */
    @media (max-width: 620px) {
        .dir-decision { grid-template-columns: 1fr; }
        .dir-decision__cta { justify-self: start; }
        body.app-body .briefing-card__head { flex-direction: column; }
        .dir-brief__open { align-self: flex-start; }
        .dir-day { grid-template-columns: 1fr; }
        .dir-day__head { flex-direction: row; align-items: baseline; gap: var(--sp-4); }
        .dir-day__num { font-size: var(--fs-xl); }
        .dir-day__badge { margin-top: 0; margin-left: auto; }
        .dir-mx-grid { grid-template-columns: 1fr 1fr; }
    }

    /* 480px — Hoy a una columna */
    @media (max-width: 480px) {
        .dir-risk__sev { display: none; }
        .dir-load__row { align-items: flex-start; }
        .dir-load__stats { width: 100%; }
    }

    /* 430px — Métricas a una columna, switch de rango con scroll-x */
    @media (max-width: 430px) {
        .dir-mx-grid { grid-template-columns: 1fr; }
        .dir-mx-range { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
        body.app-body .dir-mx-range .quick-filters__link { white-space: nowrap; flex-shrink: 0; }
    }

    /* 390px — corte crítico anti-overflow */
    @media (max-width: 390px) {
        .dir-evt { flex-direction: column; gap: var(--sp-1); }
        .dir-statusbar { gap: var(--sp-4); }
        .dir-status-pill { padding: var(--sp-3) var(--sp-5); font-size: var(--fs-md); }
    }

    /* prefers-reduced-motion: anula transiciones de hover/elevación de Dirección */
    @media (prefers-reduced-motion: reduce) {
        .dir-status-pill,
        .dir-decision__title,
        .dir-risk__title,
        .dir-agenda__title,
        .dir-evt__title,
        .dir-load__name,
        .dir-mx-card__drill { transition: none; }
    }

    /* Impresión: hereda el @media print global (.no-print, .panel sin sombra).
       Añadidos mínimos de Dirección. */
    @media print {
        .dir-statusbar { gap: var(--sp-3); }
        .dir-status-pill { box-shadow: none; border-color: var(--n-300); -webkit-backdrop-filter: none; backdrop-filter: none; }
        .dir-decision,
        .dir-agenda,
        .dir-day,
        .dir-mx-card,
        .dir-mx-block__interpret { break-inside: avoid; border-color: var(--n-300); }
        .dir-decision__title,
        .dir-risk__title,
        .dir-agenda__title,
        .dir-evt__title,
        .dir-day__num,
        .dir-mx-card__value { color: #000; }
        .dir-mx-grid { grid-template-columns: repeat(3, 1fr); }
        .dir-mx-card__dot,
        .dir-risk__sev { display: none; }
    }

    /* ---------- Asistentes al acto (selector, ficha y catálogo) ---------- */

    /* Acciones en línea dentro de una fila de tabla (Personas). */
    .row-actions form { margin: 0; }

    /* Selector de asistentes del formulario de acto. */
    .attendee-picker__search { width: 100%; margin-bottom: 8px; }
    .attendee-picker__list {
        max-height: 260px; overflow-y: auto;
        border: 1px solid var(--line); border-radius: var(--r-sm);
        padding: var(--sp-4) var(--sp-4); background: var(--surface-2);
    }
    .attendee-picker__group + .attendee-picker__group { margin-top: 10px; }
    .attendee-picker__group-name {
        display: block; margin-bottom: 4px;
        font-size: var(--fs-xs); font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase;
        color: var(--ink-3);
    }
    .attendee-picker__item { display: flex; align-items: baseline; gap: var(--sp-4); padding: var(--sp-2) 0; }
    .attendee-picker__name { font-weight: 500; }
    .attendee-picker__role { color: var(--ink-3); font-size: var(--fs-sm); }
    .attendee-picker__empty { margin: 8px 0 0; color: var(--ink-3); font-size: var(--fs-md); }

    /* Lista de asistentes en la ficha del acto. */
    .attendee-list__item {
        display: flex; align-items: baseline; gap: var(--sp-4); flex-wrap: wrap;
        padding: var(--sp-4) 0; border-bottom: 1px solid var(--line); font-size: var(--fs-base);
    }
    .attendee-list__item:last-child { border-bottom: 0; }
    .attendee-list__name { font-weight: 500; color: var(--ink); }
    .attendee-list__role { color: var(--ink-3); font-size: var(--fs-md); }
    .attendee-list__other { margin: 10px 0 0; padding-top: var(--sp-4); border-top: 1px solid var(--line); font-size: var(--fs-md); color: var(--ink-2); }

    /* ---------- Personas: catálogo accesible y alta en modal ---------- */
    .people-panel__note {
        margin-top: 4px;
        color: var(--ink-3);
        font-size: var(--fs-md);
        line-height: 1.45;
    }

    .people-empty {
        padding: var(--sp-4) 0 var(--sp-1);
    }

    .people-empty .empty-state {
        margin-bottom: 10px;
    }

    .people-table th:nth-child(2),
    .people-table td:nth-child(2) {
        width: 170px;
    }

    .people-table th:last-child,
    .people-table td:last-child {
        width: 220px;
    }

    .people-table th:last-child {
        text-align: right;
    }

    .people-table__person-cell {
        color: var(--ink);
        font-size: var(--fs-base);
        font-weight: 500;
        letter-spacing: 0;
        text-transform: none;
    }

    .people-person {
        display: flex;
        align-items: center;
        gap: var(--sp-5);
        min-width: 0;
    }

    .people-person__icon {
        display: grid;
        place-items: center;
        width: 36px;
        height: 36px;
        flex: 0 0 36px;
        border: 1px solid var(--c-blue-bg);
        border-radius: var(--r);
        background: var(--b-100);
        color: var(--brand-700);
    }

    .people-person__icon svg {
        width: 19px;
        height: 19px;
    }

    .people-person__identity {
        display: flex;
        align-items: center;
        gap: var(--sp-4);
        min-width: 0;
        flex-wrap: wrap;
    }

    .people-person__name {
        overflow-wrap: anywhere;
    }

    .people-table .row-actions {
        justify-content: flex-end;
    }

    .people-edit__form .form-actions {
        margin-top: 2px;
    }

    .people-field-note {
        display: block;
        color: var(--ink-3);
        font-size: var(--fs-sm);
        line-height: 1.4;
    }

    dialog.people-modal {
        width: min(560px, calc(100vw - 32px));
        max-width: 560px;
    }

    .people-modal__form {
        display: flex;
        flex-direction: column;
        min-height: 0;
        max-height: 90vh;
    }

    .people-modal__intro {
        margin-bottom: 20px;
        color: var(--ink-2);
        font-size: var(--fs-md);
        line-height: 1.5;
    }

    @media (max-width: 760px) {
        body.app-body .people-table tbody th[scope="row"] {
            display: block;
            width: 100%;
            padding: var(--sp-5) var(--sp-5) var(--sp-5);
            text-align: left;
            border-bottom: 1px solid var(--line);
        }

        body.app-body .people-table td {
            grid-template-columns: minmax(96px, 31%) minmax(0, 1fr);
        }

        .people-table .row-actions {
            justify-content: flex-start;
        }
    }

    @media (max-width: 430px) {
        .people-person__identity {
            align-items: flex-start;
            flex-direction: column;
            gap: var(--sp-3);
        }

        .people-table .row-actions .btn {
            min-height: 38px;
        }
    }
    /* Centro de solicitudes territoriales */
    .request-header { align-items: flex-end; }
    .request-queue-owner { margin: -6px 0 16px; padding: var(--sp-4) var(--sp-5); border: 1px solid var(--c-blue-bg); border-radius: var(--r-sm); background: var(--b-50); color: var(--n-600); font-size: var(--fs-md); }
    .request-queue-owner.is-unassigned { border-color: var(--gold-bg); background: var(--c-amber-bg); color: var(--gold-ink); }

    .request-kpis { margin-bottom: 16px; }
    .request-row-meta { margin-top: 6px; color: var(--ink-3); font-size: var(--fs-sm); }
    .request-metrics { margin-bottom: 16px; }
    .request-metrics > summary { cursor: pointer; font-weight: 700; }
    .request-metrics__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-6); margin-top: 16px; }
    .request-metrics__grid :is(h2, h3) { margin: 0 0 12px; font-size: var(--fs-base); }
    .request-compose { max-width: 880px; padding: clamp(16px, 3vw, 32px); }
    .form-section__head { display: flex; gap: var(--sp-5); align-items: flex-start; margin-bottom: 20px; }
    .form-section__head h3, .form-section__head p { margin: 0; }
    .form-section__head p { margin-top: 4px; color: var(--ink-3); font-size: var(--fs-base); }
    .request-step { display: grid; flex: 0 0 38px; height: 38px; place-items: center; border-radius: var(--r-round); background: var(--b-100); color: var(--b-700); font-size: var(--fs-sm); font-weight: 700; }
    .request-category { margin: 16px 0 0; padding: 0; border: 0; }
    .request-category legend { margin-bottom: 10px; font-size: var(--fs-base); font-weight: 700; }
    .request-category__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); }
    .request-category label { position: relative; cursor: pointer; }
    .request-category input { position: absolute; opacity: 0; pointer-events: none; }
    .request-category span { display: grid; min-height: 52px; place-items: center; padding: var(--sp-4); border: 1px solid var(--n-200); border-radius: var(--r-sm); background: var(--n-50); color: var(--n-600); font-size: var(--fs-md); font-weight: 700; text-align: center; transition: border-color .15s ease, background .15s ease, color .15s ease; }
    .request-category input:checked + span { border-color: var(--b-700); background: var(--b-100); color: var(--b-700); box-shadow: inset 0 0 0 1px var(--b-700); }
    .request-category input:focus-visible + span { outline: 3px solid rgba(23, 105, 170, .22); outline-offset: 2px; }
    .request-detail-badges { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: 10px; }
    .request-detail-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 360px); gap: var(--sp-6); align-items: start; }
    .request-detail-main, .request-actions { display: grid; gap: var(--sp-6); }
    .request-actions { position: sticky; top: 16px; }
    .request-description { font-size: var(--fs-xl); line-height: 1.7; white-space: normal; }
    .request-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5) var(--sp-7); margin-top: 24px; }
    .request-facts > div { border-top: 1px solid var(--n-200); padding-top: var(--sp-5); }
    .request-facts dt { color: var(--ink-3); font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: var(--tracking-label); }
    .request-facts dd { margin: 4px 0 0; font-weight: 700; }
    .request-callout { margin-top: 16px; padding: var(--sp-5) var(--sp-6); border-left: 3px solid var(--warn); border-radius: var(--r-xs); background: var(--c-amber-bg); }
    .request-callout--success { border-color: var(--c-green); background: var(--ok-bg); }
    .request-callout p { margin: 6px 0 0; }
    .request-linked-list { display: grid; gap: var(--sp-4); margin: 0; padding: 0; list-style: none; }
    .request-linked-list li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-3) var(--sp-5); align-items: center; padding: var(--sp-5) 0; border-bottom: 1px solid var(--n-200); }
    .request-linked-list small { grid-column: 1 / -1; color: var(--ink-3); }
    .stack-form { display: grid; gap: var(--sp-5); margin-top: 14px; }
    .request-escalate { border-color: var(--bad-line); }
    .request-timeline ol { display: grid; gap: 0; margin: 16px 0 0; padding: 0; list-style: none; }
    .request-timeline li { position: relative; display: grid; grid-template-columns: 16px 1fr; gap: var(--sp-4); padding-bottom: var(--sp-6); }
    .request-timeline li:not(:last-child)::before { content: ''; position: absolute; left: 5px; top: 12px; bottom: 0; width: 1px; background: var(--n-200); }
    .request-timeline__dot { position: relative; z-index: 1; width: 11px; height: 11px; margin-top: 4px; border: 2px solid #fff; border-radius: var(--r-round); background: var(--b-400); box-shadow: 0 0 0 1px var(--n-400); }
    .request-timeline small { display: block; margin-top: 2px; color: var(--ink-3); }
    .request-timeline p { margin: 6px 0 0; font-size: var(--fs-base); line-height: 1.5; }
    .notif-center { margin: 16px 0; }
    .notif-center__head, .notif-center__actions, .notif-item__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: center; }
    .notif-center__head { justify-content: space-between; }
    .notif-center__head p { margin: 4px 0 0; }
    .notif-category-read { display: flex; justify-content: flex-end; margin-bottom: 10px; }
    .notif-list { display: grid; gap: var(--sp-4); }
    .notif-item { display: grid; grid-template-columns: 8px minmax(0, 1fr); gap: var(--sp-5); padding: var(--sp-5); border: 1px solid var(--n-200); border-radius: var(--r); background: #fff; }
    .notif-item.is-unread { box-shadow: 0 5px 16px rgba(16, 52, 82, .06); }
    .notif-item__signal { width: 7px; height: 100%; min-height: 40px; border-radius: var(--r-pill); background: var(--n-400); }
    .notif-item--bad .notif-item__signal { background: var(--c-rose); }
    .notif-item--warn .notif-item__signal { background: var(--warn); }
    .notif-item--info .notif-item__signal { background: var(--b-400); }
    .notif-item__meta { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5); align-items: center; color: var(--ink-3); font-size: var(--fs-sm); }
    .notif-item__body p { margin: 10px 0 12px; line-height: 1.5; }
    @media (max-width: 900px) {
        .request-detail-grid { grid-template-columns: 1fr; }
        .request-actions { position: static; }
        .request-metrics__grid { grid-template-columns: 1fr; }
    }
    @media (max-width: 640px) {
        .request-header, .request-detail-head { align-items: stretch; }
        .request-header .btn, .request-detail-head .btn { width: 100%; justify-content: center; }
        .request-facts { grid-template-columns: 1fr; }
        .request-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
        .request-category__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
        .notif-center__actions, .notif-item__actions { width: 100%; }
    }

    /* Fases 4–6 · operativa avanzada. Dirección visual: cuaderno de campo limpio,
       denso en información pero con controles grandes y táctiles. */

    /* =====================================================================
       MÓDULOS POR FASES
       Bloques añadidos por cada fase del proyecto. Estaban minificados en una
       sola línea y con rem cuando el resto de la hoja usa px; ahora siguen el
       mismo formato y las mismas unidades. Los colores propios de este tramo
       siguen sin pasar por los tokens de app.css: unificarlos cambia el aspecto
       de las pantallas y es una decisión de diseño, no de formato.
       ===================================================================== */
    .ops-form {
        max-width: 920px;
        margin-inline: auto;
    }
    .commitment-row {
        display: grid;
        grid-template-columns: 2fr 1fr 150px;
        gap: var(--sp-4);
        margin: 10px 0;
    }
    .notice-strip {
        padding: var(--sp-5) var(--sp-6);
        border-radius: var(--r-sm);
        background: var(--ok-bg);
        color: var(--ok);
    }
    .pulse-status {
        display: grid;
        grid-template-columns: repeat(3,1fr);
        gap: var(--sp-4);
        border: 0;
        padding: 0;
        margin: 16px 0;
    }
    .pulse-status legend {
        font-weight: 700;
        margin-bottom: 8px;
    }
    .pulse-status input {
        position: absolute;
        opacity: 0;
    }
    .pulse-choice {
        display: block;
        padding: var(--sp-6) var(--sp-4);
        text-align: center;
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        font-weight: 700;
        cursor: pointer;
    }
    .pulse-status input:checked+.pulse-choice {
        outline: 3px solid var(--b-700);
        outline-offset: 2px;
    }
    .pulse-choice--bien {
        background: var(--c-green-bg);
        color: var(--ok);
    }
    .pulse-choice--regular {
        background: var(--gold-bg);
        color: var(--warn);
    }
    .pulse-choice--mal {
        background: var(--c-rose-bg);
        color: var(--bad);
    }
    .value-return {
        background: linear-gradient(135deg,var(--b-50),#fff 70%);
        border-color: var(--b-200);
    }
    .eyebrow {
        display: block;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
        font-size: var(--fs-sm);
        font-weight: 700;
        color: var(--n-500);
    }
    .pulse-dot {
        display: inline-flex;
        align-items: center;
        gap: var(--sp-3);
    }
    .pulse-dot:before {
        content: "";
        width: 10px;
        height: 10px;
        border-radius: var(--r-round);
        background: var(--n-400);
    }
    .pulse-dot--bien:before {
        background: var(--ok);
    }
    .pulse-dot--regular:before {
        background: var(--warn);
    }
    .pulse-dot--mal:before {
        background: var(--bad);
    }

    /* Cabeceras de mapa con selector + alternativa accesible: pueden sumar
       tres grupos de controles y deben formar líneas, no crear scroll interno
       en el panel a 360/390 px. */
    .map-panel__head { flex-wrap: wrap; }
    .milestone {
        display: grid;
        grid-template-columns: 130px 1fr auto;
        gap: var(--sp-6);
        padding: var(--sp-6) 0;
        border-bottom: 1px solid var(--muted-bg);
        align-items: center;
    }
    .milestone:last-child {
        border-bottom: 0;
    }
    .milestone h3,
    .milestone p {
        margin: 0;
    }
    .milestone time {
        font-weight: 700;
        color: var(--gold-ink);
    }
    /* N-04. La lista de hitos que contradicen al calendario electoral. */
    .milestone-conflictos { margin: var(--sp-3) 0 0; padding-left: var(--sp-6); }
    .milestone-conflictos li { margin-bottom: var(--sp-2); }

    .milestone-strip {
        display: flex;
        gap: var(--sp-5);
        align-items: center;
        overflow: auto;
        padding: var(--sp-4) var(--sp-5);
        margin-bottom: 16px;
        border: 1px solid var(--gold-line);
        background: var(--gold-bg);
        border-radius: var(--r-sm);
    }
    .milestone-strip a {
        display: flex;
        gap: var(--sp-3);
        white-space: nowrap;
        padding: var(--sp-3) var(--sp-4);
        background: #fff;
        border-radius: var(--r-xs);
        text-decoration: none;
    }
    .document-shelf {
        display: grid;
        grid-template-columns: repeat(2,minmax(0,1fr));
        gap: var(--sp-6);
    }
    .document-card {
        display: grid;
        grid-template-columns: 64px 1fr;
        gap: var(--sp-6);
        padding: var(--sp-7);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: #fff;
        box-shadow: 0 6px 18px rgba(30,60,90,.05);
    }
    .document-card h3,
    .document-card p {
        margin: 4px 0;
    }
    .document-card__mark {
        width: 58px;
        height: 70px;
        display: grid;
        place-items: center;
        background: var(--b-100);
        color: var(--b-700);
        border-radius: var(--r-xs) var(--r-xs) var(--r) var(--r-xs);
        font-size: var(--fs-xs);
        font-weight: 700;
    }
    .upload-drop {
        display: grid;
        gap: var(--sp-3);
        padding: var(--sp-8);
        border: 2px dashed var(--n-300);
        border-radius: var(--r);
        background: var(--n-50);
        margin: 16px 0;
    }
    .version-stack {
        display: grid;
    }
    .version-row {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-6);
        padding: var(--sp-6) 0;
        border-bottom: 1px solid var(--muted-bg);
    }
    .version-row div {
        display: grid;
        gap: var(--sp-2);
    }
    .version-row code {
        font-size: var(--fs-sm);
        color: var(--n-500);
    }
    .template-preview {
        padding: var(--sp-5) 0;
        border-bottom: 1px solid var(--muted-bg);
    }
    .template-preview:last-child {
        border-bottom: 0;
    }
    .template-preview ul {
        margin: 8px 0 0;
        padding-left: var(--sp-7);
        color: var(--n-500);
    }
    @media(max-width: 800px) {
        .document-shelf,
        .commitment-row,
        .milestone {
            grid-template-columns: 1fr;
        }
        .version-row {
            align-items: flex-start;
        }
        .ops-form {
            padding: var(--sp-6);
        }
    }

    .document-ack-config {
        display: grid;
        grid-template-columns: minmax(0,1fr) minmax(190px,260px);
        gap: var(--sp-6);
        align-items: end;
        margin: 16px 0;
        padding: var(--sp-6);
        border: 1px solid var(--b-200);
        border-radius: var(--r);
        background: linear-gradient(135deg,var(--b-50),#fff);
    }
    .document-ack-config .check-line {
        margin: 0;
    }
    .document-ack-config .check-line span {
        display: grid;
        gap: var(--sp-2);
    }
    .document-ack-config .check-line small {
        color: var(--n-500);
        font-weight: 400;
        line-height: 1.45;
    }
    .document-ack-banner {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-7);
        align-items: center;
        margin-bottom: 16px;
        padding: var(--sp-6) var(--sp-7);
        border: 1px solid var(--c-amber);
        border-left: 5px solid var(--warn);
        border-radius: var(--r);
        background: var(--c-amber-bg);
        box-shadow: 0 8px 22px rgba(87,63,13,.07);
    }
    .document-ack-banner.is-done {
        border-color: var(--ok-line);
        border-left-color: var(--ok);
        background: var(--ok-bg);
    }
    .document-ack-banner h3,
    .document-ack-banner p {
        margin: 4px 0;
    }
    .document-ack-banner p {
        color: var(--n-600);
    }
    .day-focus {
        margin: 16px 0 20px;
        padding: var(--sp-6);
        border: 1px solid var(--n-200);
        border-radius: var(--r-lg);
        background: linear-gradient(145deg,var(--n-50),var(--n-100));
        box-shadow: 0 12px 32px rgba(20,55,84,.06);
    }
    .day-focus__head {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-6);
        align-items: end;
        margin-bottom: 14px;
    }
    .day-focus__head h2 {
        margin: 2px 0 0;
        font-size: clamp(18px,2vw,23px);
    }
    .day-focus__total {
        padding: var(--sp-4) var(--sp-5);
        border: 1px solid var(--n-300);
        border-radius: var(--r-pill);
        background: #fff;
        color: var(--n-600);
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    /* auto-fit y no un número fijo de columnas: el bloque pasó de cuatro
       tarjetas a cinco al añadir la proyección canónica de atención (E-e), y
       una rejilla de «repeat(4, …)» habría dejado la quinta sola en una fila
       nueva a cualquier anchura. Con auto-fit el reparto lo decide el espacio,
       que es lo que debería haber decidido siempre. */
    .day-focus__grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: var(--sp-5);
    }
    .day-focus-card {
        position: relative;
        display: flex;
        min-height: 210px;
        flex-direction: column;
        overflow: hidden;
        padding: var(--sp-6);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: #fff;
        box-shadow: 0 6px 16px rgba(24,53,77,.04);
    }
    .day-focus-card:before {
        content: "";
        position: absolute;
        inset: 0 auto 0 0;
        width: 3px;
        background: var(--b-600);
    }
    /* La proyección canónica abre el bloque, así que lleva el color de marca:
       es lo que de verdad requiere una acción, frente a las otras cuatro
       tarjetas, que son bandejas. */
    .day-focus-card--attention:before {
        background: var(--brand);
    }
    .day-focus-card--incidents:before {
        background: var(--c-rose);
    }
    .day-focus-card--territory:before {
        background: var(--ok);
    }
    .day-focus-card--documents:before {
        background: var(--c-amber);
    }
    .day-focus-card__head {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-5);
        align-items: center;
        margin-bottom: 10px;
        color: var(--n-600);
        font-size: var(--fs-sm);
        font-weight: 700;
        letter-spacing: var(--tracking-label);
        text-transform: uppercase;
    }
    .day-focus-card__head strong {
        display: grid;
        width: 32px;
        height: 32px;
        place-items: center;
        border-radius: var(--r-round);
        background: var(--n-100);
        color: var(--b-700);
        font-size: var(--fs-base);
    }
    .day-focus-list li {
        display: grid;
        gap: var(--sp-2);
        padding: var(--sp-4) 0;
        border-bottom: 1px solid var(--muted-bg);
    }
    .day-focus-list li:last-child {
        border-bottom: 0;
    }
    .day-focus-list a {
        overflow: hidden;
        color: var(--b-900);
        font-size: var(--fs-md);
        font-weight: 700;
        text-decoration: none;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .day-focus-list a:hover {
        text-decoration: underline;
    }
    .day-focus-list span {
        overflow: hidden;
        color: var(--ink-3);
        font-size: var(--fs-sm);
        line-height: 1.35;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    /* La condición de desaparición es una FRASE, no un rótulo: recortarla con
       puntos suspensivos la deja inservible, porque lo que hay que leer es
       justamente el final («…se completa, se cancela o cambia de fecha»). Por
       eso ésta es la única línea de la tarjeta que ajusta en varias líneas. */
    .day-focus-list__clears {
        color: var(--ink-3);
        font-size: var(--fs-xs);
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
    }
    .day-focus-card .empty-state {
        margin: auto 0;
        color: var(--ink-3);
        font-size: var(--fs-md);
    }
    .day-focus-card .myday-foot-link {
        margin-top: auto;
        padding-top: var(--sp-4);
    }
    .substitution-strip {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-4) var(--sp-5);
        align-items: center;
        margin: -3px 0 16px;
        padding: var(--sp-5) var(--sp-5);
        border: 1px solid var(--c-blue-bg);
        border-radius: var(--r-sm);
        background: var(--b-50);
        color: var(--n-600);
        font-size: var(--fs-sm);
    }
    .substitution-strip strong {
        color: var(--b-900);
    }
    .substitution-strip span:not(:last-child):after {
        content: "·";
        margin-left: 12px;
        color: var(--n-300);
    }
    .territory-workbench-head {
        align-items: end;
    }
    .territory-switcher {
        display: grid;
        min-width: min(100%,270px);
        gap: var(--sp-2);
    }
    .territory-switcher label {
        color: var(--n-500);
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    /* El 42 px de aqui era una altura elegida a ojo, que es exactamente lo que
       el contrato dimensional viene a terminar. Se retira: el selector cae en
       --control-h como cualquier otro `select`. */
    .territory-empty {
        display: flex;
        gap: var(--sp-7);
        align-items: center;
        min-height: 170px;
    }
    .territory-empty__mark {
        display: grid;
        flex: 0 0 82px;
        height: 82px;
        place-items: center;
        border-radius: var(--r-round);
        background: var(--b-800);
        color: #fff;
        font-size: var(--fs-4xl);
        font-weight: 700;
        box-shadow: 0 0 0 8px var(--n-100);
    }
    .territory-empty :is(h2, h3),
    .territory-empty p {
        margin: 4px 0;
    }
    .territory-empty p {
        color: var(--n-500);
    }
    .territory-dossier {
        position: relative;
        display: grid;
        grid-template-columns: minmax(0,1.3fr) minmax(170px,.65fr) minmax(240px,.9fr);
        gap: var(--sp-6);
        overflow: hidden;
        margin-bottom: 12px;
        padding: clamp(20px,2.5vw,28px);
        border-radius: var(--r-lg);
        background: linear-gradient(120deg, var(--b-800), var(--b-700) 65%, var(--b-600));
        color: #fff;
        box-shadow: 0 16px 35px rgba(4,48,81,.2);
    }
    .territory-dossier:after {
        content: "78";
        position: absolute;
        right: -.04em;
        bottom: -.38em;
        color: rgba(255,255,255,.045);
        font-size: 192px;
        font-weight: 700;
        line-height: 1;
        pointer-events: none;
    }
    .territory-dossier__identity,
    .territory-dossier__status,
    .territory-dossier__pulse {
        position: relative;
        z-index: 1;
    }
    .territory-dossier__identity h2 {
        margin: 4px 0;
        font-size: clamp(29px,4vw,48px);
        line-height: 1;
    }
    .territory-dossier__identity p {
        margin: 8px 0 0;
        opacity: .78;
    }
    .territory-dossier__status {
        align-self: center;
        padding-left: var(--sp-6);
        border-left: 1px solid rgba(255,255,255,.2);
    }
    .territory-dossier__status span,
    .territory-dossier__status small,
    .territory-dossier__pulse span,
    .territory-dossier__pulse small {
        display: block;
        font-size: var(--fs-sm);
        opacity: .72;
    }
    .territory-dossier__status strong,
    .territory-dossier__pulse strong {
        display: block;
        margin: 4px 0;
        font-size: var(--fs-xl);
    }
    .territory-dossier__pulse {
        display: grid;
        grid-template-columns: 38px minmax(0,1fr);
        gap: var(--sp-5);
        align-items: center;
        padding: var(--sp-6);
        border: 1px solid rgba(255,255,255,.18);
        border-radius: var(--r);
        background: rgba(2,30,49,.2);
        backdrop-filter: blur(4px);
    }
    .territory-dossier__pulse .btn {
        grid-column: 1/-1;
        justify-self: start;
    }
    .pulse-orbit {
        position: relative;
        display: block;
        width: 28px;
        height: 28px;
        border: 7px solid rgba(255,255,255,.18);
        border-radius: var(--r-round);
        opacity: 1!important;
    }
    .pulse-orbit:after {
        content: "";
        position: absolute;
        inset: 3px;
        border-radius: var(--r-round);
        background: var(--n-300);
    }
    .territory-dossier--bien .pulse-orbit:after {
        background: var(--c-green);
    }
    .territory-dossier--regular .pulse-orbit:after {
        background: var(--warn);
    }
    .territory-dossier--mal .pulse-orbit:after {
        background: var(--c-rose);
    }
    .territory-quick-actions {
        display: grid;
        grid-template-columns: repeat(4,minmax(0,1fr));
        gap: var(--sp-4);
        margin-bottom: 12px;
    }
    .territory-quick-actions a {
        display: grid;
        gap: var(--sp-2);
        padding: var(--sp-5) var(--sp-6);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: #fff;
        color: var(--n-600);
        text-decoration: none;
        transition: transform .16s ease,border-color .16s ease,box-shadow .16s ease;
    }
    .territory-quick-actions a:hover {
        transform: translateY(-2px);
        border-color: var(--b-300);
        box-shadow: 0 8px 18px rgba(20,59,89,.08);
    }
    .territory-quick-actions strong {
        font-size: var(--fs-md);
    }
    .territory-quick-actions span {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .territory-next-action {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-6);
        align-items: center;
        margin-bottom: 12px;
        padding: var(--sp-6) var(--sp-7);
        border: 1px solid var(--b-200);
        border-radius: var(--r);
        background: var(--b-50);
    }
    .territory-next-action h2 {
        margin: 2px 0 0;
        color: var(--b-900);
        font-size: var(--fs-xl);
    }
    .territory-next-action time {
        flex: 0 0 auto;
        color: var(--b-700);
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    .territory-next-action.is-empty {
        border-style: dashed;
        background: var(--n-50);
    }
    .territory-signal-grid {
        display: grid;
        grid-template-columns: repeat(4,minmax(0,1fr));
        gap: var(--sp-4);
        margin-bottom: 16px;
    }
    .territory-signal {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-5);
        align-items: center;
        padding: var(--sp-5) var(--sp-6);
        border-radius: var(--r-sm);
        background: var(--muted-bg);
        color: var(--n-600);
        text-decoration: none;
    }
    .territory-signal strong {
        color: var(--b-800);
        font-size: var(--fs-3xl);
    }
    .territory-signal span {
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    .territory-work-grid {
        display: grid;
        grid-template-columns: repeat(2,minmax(0,1fr));
        gap: var(--sp-6);
    }
    .territory-work-panel {
        min-height: 220px;
    }
    .territory-work-list li {
        display: grid;
        gap: var(--sp-2);
        padding: var(--sp-5) 0;
        border-bottom: 1px solid var(--muted-bg);
    }
    .territory-work-list li:last-child {
        border-bottom: 0;
    }
    .territory-work-list a {
        color: var(--b-900);
        font-size: var(--fs-base);
        font-weight: 700;
        text-decoration: none;
    }
    .territory-work-list span {
        color: var(--ink-3);
        font-size: var(--fs-sm);
    }
    .scope-invite-result {
        margin-bottom: 16px;
    }
    .scope-gap {
        margin-bottom: 16px;
        border-left: 4px solid var(--warn);
    }
    .scope-gap .panel__count {
        background: var(--gold-bg);
        color: var(--gold-ink);
    }
    .scope-action-grid {
        display: grid;
        grid-template-columns: minmax(0,1.35fr) minmax(320px,.85fr);
        gap: var(--sp-6);
        margin-bottom: 16px;
    }
    .scope-action-card {
        align-self: start;
    }
    .scope-action-card .panel__head {
        margin-bottom: 14px;
    }
    .scope-action-card--invite {
        border-top: 4px solid var(--ok);
    }
    .territory-picker-head {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-6);
        align-items: center;
        margin-top: 2px;
    }
    .territory-picker-head label {
        font-size: var(--fs-md);
        font-weight: 700;
    }
    .territory-picker-head span {
        color: var(--b-700);
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    .territory-picker-search {
        width: 100%;
        margin: 6px 0 8px;
    }
    .territory-picker {
        display: grid;
        grid-template-columns: repeat(3,minmax(0,1fr));
        gap: var(--sp-3);
        max-height: 330px;
        overflow: auto;
        padding: var(--sp-3);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: var(--n-50);
    }
    .territory-picker--compact {
        grid-template-columns: repeat(2,minmax(0,1fr));
        max-height: 250px;
    }
    .territory-picker-disclosure {
        border: 1px solid var(--n-200);
        border-radius: var(--r-sm);
        background: #fff;
    }
    .territory-picker-disclosure > summary {
        display: flex;
        align-items: center;
        gap: var(--sp-4);
        min-height: 44px;
        padding: var(--sp-4) var(--sp-5);
        color: var(--ink);
        font-size: var(--fs-md);
        font-weight: 700;
        cursor: pointer;
        list-style: none;
    }
    .territory-picker-disclosure > summary::-webkit-details-marker { display: none; }
    .territory-picker-disclosure > summary > :last-child { margin-left: auto; color: var(--b-700); font-size: var(--fs-sm); }
    .territory-picker-disclosure > summary::after {
        content: "";
        width: 8px;
        height: 8px;
        margin-left: var(--sp-2);
        border-right: 2px solid var(--ink-3);
        border-bottom: 2px solid var(--ink-3);
        transform: translateY(-2px) rotate(45deg);
        transition: transform var(--dur-2) var(--ease);
    }
    .territory-picker-disclosure[open] > summary { border-bottom: 1px solid var(--n-200); }
    .territory-picker-disclosure[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
    .territory-picker-disclosure__body { padding: var(--sp-5); background: var(--n-50); }
    .territory-picker-disclosure__body .territory-picker { max-height: min(320px, 42vh); background: #fff; }
    .territory-option {
        position: relative;
        min-width: 0;
        cursor: pointer;
    }
    .territory-option input {
        position: absolute;
        opacity: 0;
        pointer-events: none;
    }
    .territory-option span {
        display: grid;
        min-height: 56px;
        align-content: center;
        padding: var(--sp-4) var(--sp-4);
        border: 1px solid var(--n-200);
        border-radius: var(--r-sm);
        background: #fff;
        transition: border-color .14s ease,background .14s ease,box-shadow .14s ease;
    }
    .territory-option strong {
        overflow: hidden;
        color: var(--n-600);
        font-size: var(--fs-sm);
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .territory-option small {
        overflow: hidden;
        margin-top: 2px;
        color: var(--ink-3);
        font-size: var(--fs-xs);
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .territory-option input:checked+span {
        border-color: var(--b-600);
        background: var(--b-50);
        box-shadow: inset 0 0 0 1px var(--b-600);
    }
    .territory-option input:focus-visible+span {
        outline: 3px solid rgba(25,105,164,.22);
        outline-offset: 1px;
    }
    .territory-picker-actions {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-3);
        align-items: center;
        justify-content: flex-end;
    }
    .territory-picker-actions button {
        padding: 0;
        border: 0;
        background: transparent;
        color: var(--n-600);
        font: inherit;
        font-size: var(--fs-xs);
        font-weight: 700;
        text-decoration: underline;
        cursor: pointer;
    }
    .territory-picker-actions button:hover {
        color: var(--b-700);
    }
    .scope-coverage {
        margin-bottom: 16px;
    }
    .scope-coverage>.panel__head {
        align-items: end;
    }
    .scope-coverage__filters {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-4);
        align-items: center;
    }
    .scope-coverage__filters input[type="search"] {
        min-width: 220px;
    }
    .scope-coverage__filters label {
        display: flex;
        gap: var(--sp-3);
        align-items: center;
        color: var(--n-500);
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    .scope-coverage-grid {
        display: grid;
        grid-template-columns: repeat(4,minmax(0,1fr));
        gap: var(--sp-4);
    }
    .scope-coverage-card {
        min-height: 126px;
        padding: var(--sp-5);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: #fff;
    }
    .scope-coverage-card.is-empty {
        border-style: dashed;
        background: var(--n-50);
    }
    .scope-coverage-card header {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-4);
        padding-bottom: var(--sp-4);
        border-bottom: 1px solid var(--muted-bg);
    }
    .scope-coverage-card header div {
        display: grid;
        min-width: 0;
    }
    .scope-coverage-card header strong {
        overflow: hidden;
        color: var(--b-900);
        font-size: var(--fs-md);
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .scope-coverage-card header small,
    .scope-coverage-card header a {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .scope-coverage-card p {
        margin: 14px 0 0;
        color: var(--gold-ink);
        font-size: var(--fs-sm);
    }
    .scope-coverage-card ul {
        display: grid;
        gap: var(--sp-3);
        margin: 10px 0 0;
        padding: 0;
        list-style: none;
    }
    .scope-coverage-card li {
        display: grid;
        gap: var(--sp-1);
    }
    .scope-coverage-card li a {
        overflow: hidden;
        color: var(--n-600);
        font-size: var(--fs-sm);
        font-weight: 700;
        text-decoration: none;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .scope-coverage-card li span {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .scope-people-directory {
        margin-bottom: 16px;
    }
    @media(max-width: 1100px) {
        .day-focus__grid,
        .scope-coverage-grid {
            grid-template-columns: repeat(2,minmax(0,1fr));
        }
        .territory-dossier {
            grid-template-columns: minmax(0,1fr) minmax(220px,.8fr);
        }
        .territory-dossier__status {
            grid-row: 2;
        }
        .territory-dossier__pulse {
            grid-row: 1/3;
            grid-column: 2;
        }
        .scope-action-grid {
            grid-template-columns: 1fr;
        }
        .territory-picker {
            grid-template-columns: repeat(4,minmax(0,1fr));
        }
    }

    @media(max-width: 800px) {
        .document-ack-config,
        .territory-work-grid {
            grid-template-columns: 1fr;
        }
        .document-ack-banner {
            align-items: stretch;
            flex-direction: column;
        }
        .territory-dossier {
            grid-template-columns: 1fr;
        }
        .territory-dossier__status {
            grid-row: auto;
            padding: var(--sp-5) 0 0;
            border-top: 1px solid rgba(255,255,255,.2);
            border-left: 0;
        }
        .territory-dossier__pulse {
            grid-row: auto;
            grid-column: auto;
        }
        .territory-quick-actions,
        .territory-signal-grid {
            grid-template-columns: repeat(2,minmax(0,1fr));
        }
        .territory-picker {
            grid-template-columns: repeat(3,minmax(0,1fr));
        }
        .scope-coverage>.panel__head {
            align-items: stretch;
            flex-direction: column;
        }
        .scope-coverage__filters {
            width: 100%;
        }
        .scope-coverage__filters input[type="search"] {
            flex: 1;
            min-width: 0;
        }
    }

    @media(max-width: 560px) {
        .day-focus__head {
            align-items: flex-start;
            flex-direction: column;
        }
        .day-focus__grid,
        .scope-coverage-grid {
            grid-template-columns: 1fr;
        }
        .day-focus-card {
            min-height: 0;
        }
        .territory-workbench-head {
            align-items: stretch;
        }
        .territory-switcher {
            width: 100%;
        }
        .territory-empty {
            align-items: flex-start;
            flex-direction: column;
        }
        .territory-quick-actions,
        .territory-signal-grid {
            grid-template-columns: 1fr;
        }
        .territory-next-action {
            align-items: flex-start;
            flex-direction: column;
        }

        .territory-picker,
        .territory-picker--compact {
            grid-template-columns: repeat(2,minmax(0,1fr));
        }
        .document-ack-banner form,
        .document-ack-banner .btn {
            width: 100%;
        }
        .scope-coverage__filters {
            align-items: stretch;
            flex-direction: column;
        }
    }

    @media(max-width: 390px) {
        .territory-picker,
        .territory-picker--compact {
            grid-template-columns: 1fr;
        }
        .substitution-strip {
            align-items: flex-start;
            flex-direction: column;
        }
        .substitution-strip span:not(:last-child):after {
            content: none;
        }
    }

    @media(prefers-reduced-motion:reduce) {
        .territory-quick-actions a {
            transition: none;
        }
        .territory-quick-actions a:hover {
            transform: none;
        }
    }

    .adoption-date {
        padding: var(--sp-4) var(--sp-5);
        border: 1px solid var(--n-200);
        border-radius: var(--r-pill);
        background: #fff;
        color: var(--n-500);
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    .adoption-hero {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-8);
        align-items: center;
        margin: 16px 0;
        padding: var(--sp-7) var(--sp-8);
        border-radius: var(--r-lg);
        background: linear-gradient(125deg,var(--b-800),var(--n-600));
        color: #fff;
        box-shadow: 0 13px 30px rgba(4,50,82,.17);
    }
    .adoption-hero :is(h2, h3),
    .adoption-hero p {
        margin: 4px 0;
    }
    .adoption-hero p {
        max-width: 760px;
        color: var(--b-200);
        line-height: 1.5;
    }
    .adoption-hero .eyebrow {
        color: var(--b-200);
    }
    .adoption-hero__privacy {
        flex: 0 0 auto;
        padding: var(--sp-4) var(--sp-5);
        border: 1px solid rgba(255,255,255,.22);
        border-radius: var(--r-pill);
        background: rgba(255,255,255,.08);
        font-size: var(--fs-xs);
        font-weight: 700;
    }
    /* Adopción reutiliza .dir-mx-card; aquí solo va lo que añade. */
    .adoption-kpis { margin-bottom: 16px; }
    .adoption-kpi { color: inherit; text-decoration: none; transition: border-color var(--dur-1) var(--ease); }
    .adoption-kpi:hover { border-color: var(--brand); }
    /* La tarjeta crítica no tiñe el fondo como la canónica: el anillo necesita un
       hueco de color plano para no verse recortado. El borde y el propio anillo ya
       señalan el estado de sobra. */
    .adoption-kpi.dir-mx-card--bad { background: var(--surface-2); }
    .adoption-kpi__ring {
        display: grid;
        flex: 0 0 46px;
        width: 46px;
        height: 46px;
        place-items: center;
        border-radius: var(--r-round);
        background: conic-gradient(var(--ok) var(--progress), var(--muted-bg) 0);
    }
    .dir-mx-card--warn .adoption-kpi__ring { background: conic-gradient(var(--warn) var(--progress), var(--muted-bg) 0); }
    .dir-mx-card--bad .adoption-kpi__ring { background: conic-gradient(var(--bad) var(--progress), var(--muted-bg) 0); }
    .adoption-kpi__ring::before {
        content: "";
        grid-area: 1/1;
        width: 36px;
        height: 36px;
        border-radius: var(--r-round);
        background: var(--surface-2);
    }
    body.app-body .adoption-kpi__ring strong {
        grid-area: 1/1;
        z-index: 1;
        font-size: var(--fs-sm);
        font-weight: 700;
        color: var(--ink);
        font-variant-numeric: tabular-nums;
    }
    .adoption-layout {
        display: grid;
        grid-template-columns: minmax(0,1.35fr) minmax(300px,.65fr);
        gap: var(--sp-6);
        margin-bottom: 16px;
    }
    .adoption-funnel__row {
        display: grid;
        grid-template-columns: minmax(155px,1fr) minmax(150px,2fr) 42px;
        gap: var(--sp-5);
        align-items: center;
        padding: var(--sp-4) 0;
    }
    .adoption-funnel__row>div {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-4);
        align-items: center;
    }
    .adoption-funnel__row span,
    .adoption-funnel__row small {
        color: var(--n-500);
        font-size: var(--fs-sm);
    }
    .adoption-funnel__row strong {
        color: var(--b-900);
    }
    .adoption-funnel__track {
        height: 9px;
        overflow: hidden;
        border-radius: var(--r-pill);
        background: var(--muted-bg);
    }
    /* La anchura la pone `initBarras()` desde `data-barra`. Aqui parte de
       cero: sin JavaScript una barra vacia es honrada —el porcentaje va escrito
       al lado— y una barra llena mintiendo no lo es. Esto ultimo es lo que
       pasaba de verdad, porque la CSP descarta el atributo `style` y la barra
       se quedaba con el 100 % de la pista: TODAS salian llenas. */
    .adoption-funnel__track i {
        display: block;
        width: 0;
        height: 100%;
        border-radius: inherit;
        background: linear-gradient(90deg,var(--b-800),var(--c-green));
    }
    .adoption-gaps {
        display: grid;
        align-content: start;
        gap: var(--sp-4);
    }
    .adoption-gaps .panel__head {
        margin-bottom: 4px;
    }
    .adoption-gaps>a {
        display: grid;
        grid-template-columns: 42px minmax(0,1fr);
        gap: var(--sp-4);
        align-items: center;
        padding: var(--sp-4);
        border: 1px solid var(--n-200);
        border-radius: var(--r-sm);
        background: var(--n-50);
        color: var(--n-500);
        text-decoration: none;
    }
    .adoption-gaps>a strong {
        color: var(--c-rose);
        font-size: var(--fs-xl);
    }
    .adoption-gaps>a span {
        font-size: var(--fs-sm);
    }
    .adoption-constituencies {
        margin-bottom: 16px;
    }
    .adoption-constituencies td,
    .adoption-constituencies th {
        vertical-align: middle;
    }
    .adoption-constituencies td strong {
        display: inline-block;
        min-width: 35px;
        margin-left: 6px;
        font-size: var(--fs-sm);
    }
    .adoption-inline {
        display: inline-block;
        width: 78px;
        height: 7px;
        overflow: hidden;
        border-radius: var(--r-pill);
        background: var(--muted-bg);
    }
    .adoption-inline i {
        display: block;
        width: 0;
        height: 100%;
        border-radius: inherit;
        background: var(--c-green);
    }
    .adoption-inline--warn i {
        background: var(--c-amber);
    }
    .adoption-inline--bad i {
        background: var(--c-rose);
    }
    .adoption-legend {
        display: flex;
        gap: var(--sp-5);
        color: var(--n-500);
        font-size: var(--fs-xs);
        font-weight: 700;
    }
    .adoption-legend span {
        display: flex;
        gap: var(--sp-3);
        align-items: center;
    }
    .adoption-legend span:before {
        content: "";
        width: 8px;
        height: 8px;
        border-radius: var(--r-2xs);
        background: var(--n-500);
    }
    .adoption-legend .is-pulse:before {
        background: var(--c-green);
    }
    .adoption-trend__grid {
        display: grid;
        grid-template-columns: repeat(6,minmax(60px,1fr));
        gap: var(--sp-4);
        min-height: 190px;
        padding-top: var(--sp-4);
    }
    .adoption-week {
        display: grid;
        grid-template-rows: 130px auto auto;
        gap: var(--sp-2);
        text-align: center;
    }
    .adoption-week__bars {
        display: flex;
        gap: var(--sp-3);
        align-items: end;
        justify-content: center;
        border-bottom: 1px solid var(--n-200);
    }
    /* Igual que las pistas: el alto lo pone el JS desde `data-barra-alto`. */
    .adoption-week__bars i {
        display: block;
        height: 0;
        width: min(28%,22px);
        min-height: 2px;
        border-radius: var(--r-2xs) var(--r-2xs) 0 0;
        background: var(--n-500);
    }
    .adoption-week__bars .is-pulse {
        background: var(--c-green);
    }
    .adoption-week>strong {
        font-size: var(--fs-xs);
    }
    .adoption-week>small {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .adoption-note {
        margin: 16px 0 0;
        padding-top: var(--sp-5);
        border-top: 1px solid var(--n-200);
        color: var(--n-500);
        font-size: var(--fs-sm);
        line-height: 1.5;
    }
    @media(max-width: 1050px) {
        .adoption-layout {
            grid-template-columns: 1fr;
        }
    }

    @media(max-width: 680px) {
        .adoption-hero {
            align-items: flex-start;
            flex-direction: column;
        }
        .adoption-hero__privacy {
            flex: auto;
        }
        .adoption-funnel__row {
            grid-template-columns: minmax(125px,1fr) minmax(90px,1fr) 38px;
        }
        .adoption-trend__grid {
            gap: var(--sp-3);
            overflow-x: auto;
        }
        .adoption-week {
            min-width: 56px;
        }
        .adoption-legend {
            align-items: flex-end;
            flex-direction: column;
            gap: var(--sp-2);
        }
    }

    .form-stack {
        display: grid;
        gap: var(--sp-5);
    }
    .input-suffix {
        display: flex;
        align-items: stretch;
    }
    .input-suffix input {
        min-width: 0;
        border-radius: var(--r-xs) 0 0 var(--r-xs);
    }
    .input-suffix span {
        display: flex;
        align-items: center;
        padding: 0 var(--sp-4);
        border: 1px solid var(--n-200);
        border-left: 0;
        border-radius: 0 var(--r-xs) var(--r-xs) 0;
        background: var(--n-100);
        color: var(--n-500);
        font-size: var(--fs-xs);
        font-weight: 700;
        white-space: nowrap;
    }
    .milestone-page-head {
        align-items: center;
    }
    .milestone-head-stats span {
        display: grid;
        min-width: 100px;
        padding: var(--sp-5) var(--sp-6);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: var(--b-50);
        color: var(--n-500);
        font-size: var(--fs-xs);
        text-align: center;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
    }
    .milestone-head-stats strong {
        color: var(--b-800);
        font-size: var(--fs-4xl);
        line-height: 1;
    }
    .milestone-create {
        margin-bottom: 16px;
    }
    .milestone-ledger {
        position: relative;
        display: grid;
        gap: var(--sp-4);
        padding-left: var(--sp-9);
    }
    .milestone-ledger:before {
        content: "";
        position: absolute;
        top: 16px;
        bottom: 16px;
        left: 14px;
        width: 2px;
        background: var(--n-200);
    }
    .milestone-ledger__empty {
        margin-left: -34px;
        text-align: center;
    }
    .milestone-record {
        position: relative;
        display: grid;
        grid-template-columns: 118px minmax(0,1fr) auto;
        gap: var(--sp-6);
        align-items: start;
        padding: var(--sp-6) var(--sp-7);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: #fff;
        box-shadow: 0 6px 18px rgba(20,52,76,.045);
    }
    .milestone-record:before {
        content: "";
        position: absolute;
        left: -28px;
        top: 23px;
        width: 12px;
        height: 12px;
        border: 4px solid var(--n-50);
        border-radius: var(--r-round);
        background: var(--n-500);
        box-shadow: 0 0 0 1px var(--n-400);
    }
    .milestone-record.is-past {
        background: var(--n-50);
    }
    .milestone-record.is-past:before,
    .milestone-record.is-archived:before {
        background: var(--n-400);
    }
    .milestone-record.is-archived {
        border-style: dashed;
        background: var(--n-50);
    }
    .milestone-record__date {
        display: grid;
        gap: var(--sp-4);
        align-content: start;
    }
    .milestone-record__date time {
        display: flex;
        gap: var(--sp-4);
        align-items: baseline;
        color: var(--b-800);
    }
    .milestone-record__date time strong {
        font-size: var(--fs-4xl);
        line-height: 1;
    }
    .milestone-record__date time span {
        font-size: var(--fs-sm);
        font-weight: 700;
        letter-spacing: .08em;
    }
    .milestone-record__date b {
        color: var(--n-500);
        font-size: var(--fs-xs);
        text-transform: uppercase;
    }
    .milestone-record__body :is(h2, h3),
    .milestone-record__body p {
        margin: 4px 0;
    }
    .milestone-record__body :is(h2, h3) {
        color: var(--b-900);
        font-size: var(--fs-xl);
    }
    .milestone-record__body p,
    .milestone-record__body>small {
        color: var(--n-500);
        font-size: var(--fs-sm);
        line-height: 1.5;
    }
    .milestone-record__meta {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-3);
    }
    .milestone-record__meta span {
        padding: var(--sp-2) var(--sp-4);
        border-radius: var(--r-2xs);
        background: var(--n-100);
        color: var(--n-600);
        font-size: var(--fs-xs);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
    }
    .milestone-record__actions {
        display: flex;
        gap: var(--sp-3);
        align-items: flex-start;
    }
    .milestone-record__actions details {
        position: relative;
    }
    .milestone-record__actions summary {
        list-style: none;
    }
    .milestone-record__actions summary::-webkit-details-marker {
        display: none;
    }
    .milestone-edit-form {
        position: absolute;
        z-index: 20;
        top: calc(100% + 6px);
        right: 0;
        display: grid;
        width: min(460px,calc(100vw - 48px));
        gap: var(--sp-4);
        padding: var(--sp-6);
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: #fff;
        box-shadow: 0 18px 42px rgba(16,46,69,.18);
    }
    .task-recurrence-config {
        display: grid;
        grid-template-columns: minmax(180px,.65fr) minmax(0,1.35fr);
        gap: var(--sp-6);
        margin: 14px 0;
        padding: var(--sp-6);
        border: 1px solid var(--n-200);
        border-left: 4px solid var(--n-500);
        border-radius: var(--r);
        background: var(--n-50);
    }
    .task-recurrence-config small {
        display: block;
        margin-top: 6px;
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .task-recurrence-fields {
        display: grid;
        grid-template-columns: repeat(3,minmax(0,1fr));
        gap: var(--sp-4);
        align-items: end;
    }
    .task-recurrence-fields[hidden] {
        display: none;
    }
    .task-series-mark {
        display: inline-flex;
        margin-left: 6px;
        color: var(--n-500);
        font-size: var(--fs-xs);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
    }
    .dependency-warning {
        display: block;
        margin-top: 4px;
        color: var(--warn);
        font-weight: 700;
    }
    .dependency-block-banner {
        display: flex;
        gap: var(--sp-6);
        align-items: center;
        margin-bottom: 16px;
        padding: var(--sp-6) var(--sp-7);
        border: 1px solid var(--c-amber);
        border-left: 5px solid var(--c-amber);
        border-radius: var(--r);
        background: var(--c-amber-bg);
        box-shadow: 0 8px 22px rgba(91,59,6,.06);
    }
    .dependency-block-banner__mark {
        display: grid;
        flex: 0 0 42px;
        height: 40px;
        place-items: center;
        border-radius: var(--r-round);
        background: var(--c-amber);
        color: #fff;
        font-size: var(--fs-3xl);
        font-weight: 700;
    }
    .dependency-block-banner h3,
    .dependency-block-banner p {
        margin: 2px 0;
    }
    .dependency-block-banner p {
        color: var(--gold-ink);
        font-size: var(--fs-md);
    }
    .task-dependencies {
        border-top: 3px solid var(--n-500);
    }
    .dependency-list {
        display: grid;
        gap: var(--sp-4);
        margin: 0;
        padding: 0;
        list-style: none;
    }
    .dependency-list li {
        display: grid;
        grid-template-columns: 32px minmax(0,1fr) auto;
        gap: var(--sp-4);
        align-items: center;
        padding: var(--sp-4);
        border: 1px solid var(--n-200);
        border-radius: var(--r-sm);
    }
    .dependency-list li.is-blocking {
        border-color: var(--gold-line);
        background: var(--warn-bg);
    }
    .dependency-list__state {
        display: grid;
        width: 30px;
        height: 28px;
        place-items: center;
        border-radius: var(--r-round);
        background: var(--ok-bg);
        color: var(--ok);
        font-weight: 700;
    }
    .is-blocking .dependency-list__state {
        background: var(--gold-bg);
        color: var(--warn);
    }
    .dependency-list li>div {
        display: grid;
        min-width: 0;
        gap: var(--sp-1);
    }
    .dependency-list a {
        overflow: hidden;
        color: var(--b-900);
        font-size: var(--fs-md);
        font-weight: 700;
        text-decoration: none;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .dependency-list small {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .dependency-add {
        display: grid;
        grid-template-columns: minmax(0,1fr) auto;
        gap: var(--sp-4);
        align-items: end;
        margin-top: 12px;
        padding-top: var(--sp-5);
        border-top: 1px solid var(--n-200);
    }
    .dependency-add .form-field {
        margin: 0;
    }
    .dependency-downstream {
        margin-top: 12px;
        padding-top: var(--sp-4);
        border-top: 1px solid var(--n-200);
        color: var(--n-500);
        font-size: var(--fs-sm);
    }
    .dependency-downstream summary {
        cursor: pointer;
        font-weight: 700;
    }
    .dependency-downstream ul {
        display: grid;
        gap: var(--sp-3);
        margin: 10px 0 0;
        padding-left: var(--sp-7);
    }
    .dependency-downstream a {
        color: var(--n-600);
    }
    .task-series-panel {
        background: linear-gradient(145deg,var(--b-50),#fff);
        border-top: 3px solid var(--c-green);
    }
    .checklist-library-head {
        align-items: end;
    }
    .checklist-library {
        display: grid;
        gap: var(--sp-6);
    }
    .checklist-library__empty {
        text-align: center;
    }
    .checklist-template-card {
        overflow: hidden;
        border: 1px solid var(--n-200);
        border-radius: var(--r-lg);
        background: #fff;
        box-shadow: 0 10px 26px rgba(17,51,77,.06);
    }
    .checklist-template-card>header {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-6);
        align-items: flex-start;
        padding: var(--sp-7) var(--sp-7);
        background: linear-gradient(115deg,var(--b-50),#fff);
    }
    .checklist-template-card>header>div {
        display: flex;
        gap: var(--sp-5);
    }
    .checklist-template-card>header :is(h2, h3),
    .checklist-template-card>header p {
        margin: 2px 0;
    }
    .checklist-template-card>header :is(h2, h3) {
        color: var(--b-900);
        font-size: var(--fs-xl);
    }
    .checklist-template-card>header p {
        max-width: 760px;
        color: var(--n-500);
        font-size: var(--fs-sm);
    }
    .checklist-template-card__number {
        display: grid;
        flex: 0 0 44px;
        width: 44px;
        height: 44px;
        place-items: center;
        border-radius: var(--r-sm);
        background: var(--b-800);
        color: #fff;
        font-size: var(--fs-base);
        font-weight: 700;
        letter-spacing: var(--tracking-label);
    }
    .checklist-procedure {
        position: relative;
        display: grid;
        gap: 0;
        margin: 0;
        padding: 0 var(--sp-7);
        list-style: none;
        counter-reset: procedure;
    }
    .checklist-procedure:before {
        content: "";
        position: absolute;
        top: 16px;
        bottom: 16px;
        left: 60px;
        width: 1px;
        background: var(--n-200);
    }
    .checklist-procedure li {
        position: relative;
        display: grid;
        grid-template-columns: 78px minmax(0,1fr) auto;
        gap: var(--sp-5);
        align-items: start;
        padding: var(--sp-5) 0;
        border-bottom: 1px solid var(--muted-bg);
    }
    .checklist-procedure li:last-child {
        border-bottom: 0;
    }
    .checklist-procedure__offset {
        position: relative;
        z-index: 1;
        justify-self: start;
        padding: var(--sp-2) var(--sp-4);
        border: 1px solid var(--n-300);
        border-radius: var(--r-xs);
        background: var(--b-50);
        color: var(--n-600);
        font-size: var(--fs-xs);
        font-weight: 700;
        text-transform: uppercase;
    }
    .checklist-procedure li>div {
        display: grid;
        gap: var(--sp-1);
    }
    .checklist-procedure strong {
        color: var(--b-900);
        font-size: var(--fs-md);
    }
    .checklist-procedure small,
    .checklist-procedure p {
        margin: 0;
        color: var(--ink-3);
        font-size: var(--fs-xs);
        line-height: 1.45;
    }
    .checklist-procedure .is-empty {
        grid-template-columns: 78px 1fr;
        color: var(--ink-3);
    }
    .checklist-template-card__workbench {
        border-top: 1px solid var(--n-200);
        background: var(--n-50);
    }
    .checklist-apply {
        display: grid;
        grid-template-columns: minmax(175px,1.1fr) repeat(3,minmax(130px,1fr)) auto;
        gap: var(--sp-4);
        align-items: end;
        padding: var(--sp-6) var(--sp-7);
    }
    .checklist-apply>div:first-child {
        align-self: center;
        display: grid;
    }
    .checklist-apply>div:first-child strong {
        color: var(--b-900);
    }
    .checklist-apply .form-field {
        margin: 0;
    }
    .checklist-template-manage {
        border-top: 1px solid var(--n-200);
        padding: var(--sp-5) var(--sp-7);
    }
    .checklist-template-manage>summary {
        color: var(--n-600);
        font-size: var(--fs-sm);
        font-weight: 700;
        cursor: pointer;
    }
    .checklist-template-manage__grid {
        display: grid;
        grid-template-columns: minmax(240px,.7fr) minmax(0,1.3fr);
        gap: var(--sp-6);
        margin-top: 14px;
    }
    .checklist-template-manage__grid>form {
        align-content: start;
        padding: var(--sp-6);
        border: 1px solid var(--n-200);
        border-radius: var(--r-sm);
        background: #fff;
    }
    .checklist-archive {
        margin-top: 12px;
    }
    .checklist-template-card.is-archived {
        opacity: .78;
        border-style: dashed;
    }
    .checklist-template-card__restore {
        padding: var(--sp-6) var(--sp-7);
        border-top: 1px solid var(--n-200);
    }
    .checklist-library.is-archive .checklist-procedure:before {
        background: var(--n-200);
    }
    @media(max-width: 1050px) {
        .checklist-apply {
            grid-template-columns: repeat(3,minmax(0,1fr));
        }
        .checklist-apply>div:first-child {
            grid-column: 1/-1;
        }
        .checklist-apply .btn {
            align-self: end;
        }
        .task-recurrence-config {
            grid-template-columns: 1fr;
        }
    }

    @media(max-width: 760px) {
        .milestone-record {
            grid-template-columns: 90px minmax(0,1fr);
        }
        .milestone-record__actions {
            grid-column: 1/-1;
            justify-content: flex-end;
        }
        .task-recurrence-fields,
        .checklist-template-manage__grid {
            grid-template-columns: 1fr;
        }
        .checklist-apply {
            grid-template-columns: repeat(2,minmax(0,1fr));
        }
        .dependency-add {
            grid-template-columns: 1fr;
        }
        .dependency-add .btn {
            justify-self: start;
        }
    }

    @media(max-width: 520px) {
        .milestone-page-head {
            align-items: flex-start;
        }
        .milestone-head-stats,
        .milestone-head-stats span {
            width: 100%;
        }
        .milestone-ledger {
            padding-left: 0;
        }
        .milestone-ledger:before,
        .milestone-record:before {
            display: none;
        }
        .milestone-record {
            grid-template-columns: 1fr;
        }
        .milestone-record__date {
            grid-template-columns: auto 1fr;
            align-items: center;
        }
        .milestone-record__actions {
            justify-content: flex-start;
        }
        .milestone-record__actions {
            flex-wrap: wrap;
        }
        .milestone-edit-form {
            position: relative;
            inset: auto;
            width: calc(100vw - 48px);
            margin-top: 6px;
        }
        .task-recurrence-fields,
        .checklist-apply {
            grid-template-columns: 1fr;
        }
        .checklist-template-card>header {
            flex-direction: column;
        }
        .checklist-procedure {
            padding: 0 var(--sp-5);
        }
        .checklist-procedure:before {
            display: none;
        }
        .checklist-procedure li {
            grid-template-columns: 68px minmax(0,1fr) auto;
        }
        .dependency-block-banner {
            align-items: flex-start;
        }
        .dependency-list li {
            grid-template-columns: 30px minmax(0,1fr);
        }
        .dependency-list li form {
            grid-column: 2;
        }
    }

    .territorial-command {
        position: relative;
        display: flex;
        justify-content: space-between;
        gap: var(--sp-9);
        align-items: center;
        overflow: hidden;
        margin: 16px 0;
        padding: var(--sp-8) var(--sp-8);
        border-radius: var(--r-lg);
        background: var(--b-900);
        color: #fff;
        box-shadow: 0 16px 38px rgba(8,43,68,.18);
    }
    .territorial-command__copy {
        position: relative;
        z-index: 1;
    }
    .territorial-command :is(h2, h3),
    .territorial-command p {
        margin: 4px 0;
    }
    .territorial-command :is(h2, h3) {
        font-size: var(--fs-3xl);
        letter-spacing: var(--tracking-heading);
    }
    .territorial-command p {
        max-width: 680px;
        color: var(--n-200);
        font-size: var(--fs-md);
        line-height: 1.55;
    }
    .territorial-command .eyebrow {
        color: var(--b-300);
    }
    .territorial-command__stats {
        position: relative;
        z-index: 1;
        display: flex;
        gap: var(--sp-4);
    }
    .territorial-command__stats span {
        display: grid;
        min-width: 94px;
        padding: var(--sp-5) var(--sp-5);
        border: 1px solid rgba(255,255,255,.16);
        border-radius: var(--r);
        background: rgba(255,255,255,.07);
        text-align: center;
    }
    .territorial-command__stats strong {
        font-size: var(--fs-3xl);
    }
    .territorial-command__stats small {
        color: var(--n-300);
        font-size: var(--fs-xs);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
    }
    .territorial-command__stats .is-alert {
        border-color: rgba(238,183,72,.5);
        background: rgba(179,118,21,.2);
    }
    .territorial-atlas {
        display: grid;
        grid-template-columns: minmax(0,1.5fr) minmax(350px,.72fr);
        gap: var(--sp-6);
        margin-bottom: 16px;
    }
    .territorial-map-panel,
    .territorial-desk {
        border: 1px solid var(--n-200);
        border-radius: var(--r-lg);
        background: #fff;
        box-shadow: 0 10px 30px rgba(17,51,76,.065);
    }
    .territorial-map-panel {
        overflow: hidden;
    }
    .territorial-map-panel>header,
    .territorial-desk>header {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-6);
        align-items: flex-start;
        padding: var(--sp-6) var(--sp-7);
        border-bottom: 1px solid var(--n-200);
    }
    .territorial-map-panel h3,
    .territorial-map-panel p,
    .territorial-desk h3,
    .territorial-desk p {
        margin: 2px 0;
    }
    .territorial-map-panel>header small {
        padding: var(--sp-2) var(--sp-4);
        border-radius: var(--r-xs);
        background: var(--gold-bg);
        color: var(--gold-ink);
        font-size: var(--fs-xs);
        font-weight: 700;
    }
    .territorial-map-wrap {
        /* Venia de app.css (N-17): las capas del mapa se posicionan contra el. */
        position: relative;
        min-height: 420px;
        padding: var(--sp-7);
        background-color: var(--b-50);
        background-image: linear-gradient(rgba(30,82,115,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(30,82,115,.045) 1px,transparent 1px);
        background-size: 22px 22px;
    }
    .territorial-map {
        height: 390px;
    }
    .territorial-map svg {
        width: 100%;
        height: 100%;
    }
    .territorial-map__council {
        fill: var(--territorial-map-fill, var(--area-color))!important;
        stroke: none!important;
        cursor: pointer;
        transition: fill .16s ease,fill-opacity .16s ease;
    }
    .territorial-map__council:hover,
    .territorial-map__council:focus-visible,
    .territorial-map__council.is-selected {
        --territorial-map-fill: color-mix(in srgb, var(--area-color) 84%, white);
        stroke: none!important;
        outline: none;
    }
    .territorial-map__council.is-muted {
        fill-opacity: .3;
    }
    .territorial-map-legend {
        display: grid;
        grid-template-columns: repeat(3,minmax(0,1fr));
        gap: 0;
        border-top: 1px solid var(--n-200);
    }
    .territorial-map-legend button {
        display: flex;
        gap: var(--sp-4);
        align-items: center;
        min-height: 40px;
        padding: var(--sp-4) var(--sp-4);
        border: 0;
        border-right: 1px solid var(--n-200);
        border-bottom: 1px solid var(--n-200);
        background: #fff;
        color: var(--n-600);
        font: inherit;
        font-size: var(--fs-xs);
        font-weight: 700;
        text-align: left;
        cursor: pointer;
    }
    .territorial-map-legend button:hover,
    .territorial-map-legend button.is-active {
        background: var(--n-100);
        color: var(--b-900);
    }
    .territorial-map-legend i {
        flex: 0 0 10px;
        width: 10px;
        height: 10px;
        border-radius: var(--r-2xs);
        background: var(--area-color);
    }
    .territorial-map__boundary {
        fill: none!important;
        stroke: #fff!important;
        stroke-width: 1!important;
        stroke-linecap: round;
        stroke-linejoin: round;
        pointer-events: none;
    }
    .territorial-desk {
        align-self: start;
        overflow: hidden;
    }
    .territorial-desk>header {
        display: block;
        background: var(--n-50);
    }
    .territorial-desk>header p {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .territorial-area-card[hidden] {
        display: none;
    }
    .territorial-area-card {
        padding: var(--sp-7);
    }
    .territorial-area-card__identity {
        display: flex;
        gap: var(--sp-5);
        align-items: center;
        padding-bottom: var(--sp-5);
        border-bottom: 1px solid var(--n-200);
    }
    .territorial-area-card__identity>span {
        display: grid;
        flex: 0 0 44px;
        height: 44px;
        place-items: center;
        border-radius: var(--r-sm);
        background: var(--area-color);
        color: #fff;
        font-size: var(--fs-sm);
        font-weight: 700;
    }
    .territorial-area-card__identity h4,
    .territorial-area-card__identity p {
        margin: 2px 0;
    }
    .territorial-area-card__identity h4 {
        color: var(--b-900);
        font-size: var(--fs-xl);
    }
    .territorial-area-card__identity p {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .territorial-area-card__current {
        display: grid;
        gap: var(--sp-1);
        margin: 14px 0;
        padding: var(--sp-5);
        border-left: 4px solid var(--ok);
        border-radius: 0 var(--r-xs) var(--r-xs) 0;
        background: var(--ok-bg);
    }
    .territorial-area-card.is-vacant .territorial-area-card__current {
        border-left-color: var(--c-amber);
        background: var(--c-amber-bg);
    }
    .territorial-area-card__current span {
        color: var(--n-500);
        font-size: var(--fs-xs);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: var(--tracking-label);
    }
    .territorial-area-card__current strong {
        color: var(--b-900);
        font-size: var(--fs-base);
    }
    .territorial-area-card__current small {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .territorial-area-card__councils {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-2);
        max-height: 108px;
        overflow: auto;
        margin-bottom: 14px;
    }
    .territorial-area-card__councils span {
        padding: var(--sp-2) var(--sp-3);
        border: 1px solid var(--n-200);
        border-radius: var(--r-2xs);
        background: var(--n-50);
        color: var(--n-500);
        font-size: var(--fs-xs);
    }
    .territorial-assign-form {
        display: grid;
        gap: var(--sp-5);
        padding-top: var(--sp-5);
        border-top: 1px solid var(--n-200);
    }
    .territorial-assign-form .form-field {
        margin: 0;
    }
    .territorial-assign-form .btn {
        justify-self: start;
    }
    .scope-advanced {
        margin: 16px 0;
        border: 1px solid var(--n-200);
        border-radius: var(--r);
        background: #fff;
    }
    .scope-advanced>summary {
        display: flex;
        justify-content: space-between;
        gap: var(--sp-6);
        align-items: center;
        padding: var(--sp-5) var(--sp-6);
        color: var(--b-900);
        cursor: pointer;
        list-style: none;
    }
    .scope-advanced>summary::-webkit-details-marker {
        display: none;
    }
    .scope-advanced>summary>span:first-child {
        display: grid;
        gap: var(--sp-1);
    }
    .scope-advanced>summary small,
    .scope-advanced>summary>span:last-child {
        color: var(--ink-3);
        font-size: var(--fs-xs);
    }
    .scope-advanced>summary>span:last-child {
        font-weight: 700;
    }
    .scope-advanced[open]>summary {
        border-bottom: 1px solid var(--n-200);
        background: var(--n-50);
    }
    .scope-advanced__body {
        padding: var(--sp-6);
    }
    @media(max-width: 1120px) {
        .territorial-atlas {
            grid-template-columns: 1fr;
        }
        .territorial-desk {
            display: grid;
            grid-template-columns: 280px minmax(0,1fr);
        }
        .territorial-desk>header {
            border-right: 1px solid var(--n-200);
            border-bottom: 0;
        }
        .territorial-area-card {
            min-width: 0;
        }
        .territorial-map-wrap {
            min-height: 380px;
        }
        .territorial-map {
            height: 350px;
        }
    }

    @media(max-width: 780px) {
        .territorial-command {
            align-items: flex-start;
            flex-direction: column;
        }
        .territorial-desk {
            display: block;
        }
        .territorial-desk>header {
            border-right: 0;
            border-bottom: 1px solid var(--n-200);
        }
        .territorial-map-legend {
            grid-template-columns: repeat(2,minmax(0,1fr));
        }
        .territorial-map-wrap {
            min-height: 310px;
            padding: var(--sp-5);
        }
        .territorial-map {
            height: 290px;
        }
        .scope-advanced>summary {
            align-items: flex-start;
            flex-direction: column;
        }
    }

    @media(max-width: 520px) {
        .territorial-command__stats {
            width: 100%;
        }
        .territorial-command__stats span {
            flex: 1;
            min-width: 0;
        }
        .territorial-map-legend {
            grid-template-columns: 1fr;
        }
        .territorial-map-wrap {
            min-height: 250px;
        }
        .territorial-map {
            height: 230px;
        }
        .territorial-map-panel>header {
            align-items: flex-start;
            flex-direction: column;
        }
        .territorial-area-card__councils {
            max-height: 145px;
        }
    }

    @media(prefers-reduced-motion:reduce) {
        .territorial-map__council {
            transition: none;
        }
    }

}

@layer legacy {
    .inventory-label-sheet {
        --gap-inventory-label-print: 6mm;
        --pad-inventory-label-screen: clamp(var(--sp-8), 5vw, var(--sp-11));
        --pad-inventory-label-print: 8mm;
        --pad-inventory-label-compact: 6mm;
        --pad-inventory-label-qr: 2.5mm;
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
        gap: var(--sp-5);
    }
    .inventory-label {
        --inventory-label-blue: var(--b-700);
        display: flex;
        min-height: 0;
        aspect-ratio: 1.42;
        flex-direction: column;
        align-items: center;
        justify-content: space-between;
        padding: var(--pad-inventory-label-screen);
        border: 0;
        border-radius: var(--r-sm);
        background: var(--inventory-label-blue);
        color: #fff;
        text-align: center;
        break-inside: avoid;
        box-shadow: var(--shadow-sm);
    }
    .inventory-label__logo { display: block; width: min(48%, 172px); height: auto; object-fit: contain; }
    .inventory-label__id { margin: var(--sp-5) 0 var(--sp-2); color: #fff; font-size: clamp(48px, 12vw, 104px); font-weight: 700; line-height: .88; letter-spacing: var(--tracking-display); }
    .inventory-label__item { max-width: 100%; overflow-wrap: anywhere; color: #fff; font-size: var(--fs-sm); font-weight: 700; letter-spacing: .08em; }
    /* Un roll-up se fotografia de pie. Recortar a un rectangulo apaisado
       dejaba fuera justo lo que identifica la pieza, asi que la foto conserva
       su proporcion y solo se limita por el lado mas largo. */
    .inventory-item-photo { width: auto; max-width: min(100%, 420px); height: auto; max-height: min(70vh, 520px); margin-bottom: var(--sp-5); border-radius: var(--r); background: var(--surface-2); object-fit: contain; }

    @media print {
        body:has(.inventory-label-sheet) .sidebar,
        body:has(.inventory-label-sheet) .topbar,
        body:has(.inventory-label-sheet) .page > :not(.inventory-label-sheet) { display: none; }
        body:has(.inventory-label-sheet) .main-content,
        body:has(.inventory-label-sheet) .page { margin: 0; padding: 0; background: #fff; }
        .inventory-label-sheet { grid-template-columns: repeat(2, 1fr); gap: var(--gap-inventory-label-print); }
        .inventory-label { min-height: 0; padding: var(--pad-inventory-label-print); border-radius: 0; box-shadow: none; print-color-adjust: exact; -webkit-print-color-adjust: exact; }
        .inventory-label__logo { width: 43mm; }
        .inventory-label__id { margin: 5mm 0 2mm; font-size: 25mm; }
    }
}

@layer migrado {
    .inventory-scan-card {
        --pad-inventory-scan: clamp(var(--sp-5), 4vw, var(--sp-8));
        display: grid;
        grid-template-columns: minmax(210px, .8fr) minmax(280px, 1.2fr);
        gap: var(--sp-5) var(--sp-7);
        margin-bottom: var(--sp-6);
        padding: var(--pad-inventory-scan);
        border: 1px solid color-mix(in srgb, var(--b-700) 22%, var(--line));
        border-radius: var(--r);
        background: linear-gradient(135deg, color-mix(in srgb, var(--b-700) 9%, #fff), #fff 58%);
        box-shadow: var(--shadow-sm);
    }
    .inventory-scan-card--retired { border-color: color-mix(in srgb, var(--danger) 35%, var(--line)); background: linear-gradient(135deg, color-mix(in srgb, var(--danger) 7%, #fff), #fff 58%); }
    .inventory-scan-card__identity { display: flex; min-width: 0; flex-direction: column; justify-content: center; }
    .inventory-scan-card__eyebrow { color: var(--muted); font-size: var(--fs-xs); font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase; }
    .inventory-scan-card__code { margin-block: var(--sp-2); color: var(--b-800); font-size: clamp(44px, 9vw, 86px); line-height: .9; letter-spacing: var(--tracking-display); overflow-wrap: anywhere; }
    .inventory-scan-card__item { color: var(--ink); font-size: var(--fs-lg); font-weight: 700; }
    .inventory-scan-card__alias { margin: var(--sp-3) 0 0; color: var(--gold-ink); font-size: var(--fs-sm); }
    .inventory-scan-card__facts { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: var(--sp-4); align-content: center; }
    .inventory-scan-card__facts>div { display: flex; min-width: 0; flex-direction: column; gap: var(--sp-1); padding-bottom: var(--sp-3); border-bottom: 1px solid var(--line); }
    .inventory-scan-card__facts span:not(.badge) { color: var(--muted); font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; }
    .inventory-scan-card__facts strong { overflow-wrap: anywhere; }
    .inventory-scan-card__operations { display: flex; grid-column: 1/-1; flex-wrap: wrap; gap: var(--sp-2); }
    .inventory-scan-card__operations span { padding: var(--sp-2) var(--sp-3); border-radius: var(--r-pill); background: var(--surface-2); color: var(--muted); font-size: var(--fs-sm); }
    .inventory-scan-card__operations .has-warning { background: var(--alert-warning-bg); color: var(--gold-ink); font-weight: 700; }
    .inventory-scan-card__actions { display: flex; grid-column: 1/-1; flex-wrap: wrap; gap: var(--sp-2); }
    .inventory-scan-card__notice { display: flex; grid-column: 1/-1; flex-direction: column; gap: var(--sp-1); padding: var(--sp-4); border-radius: var(--r-sm); background: var(--alert-error-bg); }
    .inventory-scan-card__return { grid-column: 1/-1; padding-top: var(--sp-2); border-top: 1px solid var(--line); }
    .inventory-scan-card__history { grid-column: 1/-1; padding-top: var(--sp-3); border-top: 1px solid var(--line); }
    .inventory-scan-card__history h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-base); }
    .inventory-scan-card__history ul { display: grid; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
    .inventory-scan-card__history li { display: flex; justify-content: space-between; gap: var(--sp-4); padding-block: var(--sp-2); color: var(--muted); font-size: var(--fs-sm); }
    .inventory-scan-card__history li+li { border-top: 1px solid var(--line); }
    .inventory-scan-card__history li span:first-child { display: flex; flex-direction: column; }

    .inventory-label-sheet { grid-template-columns: repeat(auto-fill,minmax(340px,1fr)); }
    /* La etiqueta se mide contra si misma, no contra la ventana: es la misma
       pieza a 340 px en pantalla y a 96 mm en papel, y con `vw` el texto se
       salia del formato impreso. `container-type` deja usar cqw en los hijos;
       el relleno y los huecos del propio contenedor van en % porque cqw ahi
       resolveria contra un ancestro. */
    .inventory-label {
        container-type: inline-size;
        display: grid;
        grid-template-columns: minmax(0,1fr) minmax(96px,32%);
        grid-template-rows: auto 1fr auto;
        column-gap: 4%;
        row-gap: 3%;
        align-items: center;
        aspect-ratio: 1.58;
        padding: 5.5%;
        background: linear-gradient(145deg,var(--b-800),var(--b-600));
        text-align: left;
    }
    /* La cabecera cruza la etiqueta entera: el logotipo a la izquierda e
       «Inventario» apoyado en el borde derecho, justo encima del QR. */
    .inventory-label__brand { display: flex; grid-column: 1/-1; grid-row: 1; align-items: center; justify-content: space-between; gap: 4cqw; color: #fff; font-weight: 700; letter-spacing: var(--tracking-label); }
    .inventory-label__brand small { color: rgb(255 255 255 / 72%); font-size: 3.4cqw; letter-spacing: var(--tracking-label); text-align: right; }
    .inventory-label__logo { display: block; flex: 0 0 auto; grid-row: auto; width: 15cqw; height: auto; }
    .inventory-label__identity { display: flex; grid-column: 1; grid-row: 2; min-width: 0; flex-direction: column; justify-content: center; align-self: stretch; }
    /* El identificador cabe entero o no sirve: partido en «ROL-» / «01» deja
       de leerse de un vistazo. El cuerpo se calcula con los caracteres reales
       (~0,66 em por letra sobre los 53 cqw de la columna), asi que un ROL-01 y
       un MEGAFONIA-012 ocupan el mismo ancho y ninguno se recorta. */
    .inventory-label__id { margin: 1cqw 0 0; color: #fff; font-size: min(13cqw, calc(80cqw / var(--label-id-chars, 6))); font-weight: 700; line-height: .95; letter-spacing: var(--tracking-display); white-space: nowrap; }
    .inventory-label__item { max-width: 100%; overflow: hidden; color: #fff; font-size: 3.4cqw; font-weight: 700; letter-spacing: .08em; text-overflow: ellipsis; white-space: nowrap; }
    /* La URL baja a su propia fila a lo ancho de la etiqueta: en la columna
       estrecha se cortaba a la mitad y dejaba de ser transcribible. */
    .inventory-label__url { grid-column: 1/-1; grid-row: 3; max-width: 100%; overflow: hidden; color: rgb(255 255 255 / 70%); font-size: 2.8cqw; text-overflow: ellipsis; white-space: nowrap; }
    .inventory-label__qr { display: grid; grid-column: 2; grid-row: 2; place-items: center; width: 100%; aspect-ratio: 1; padding: 6%; border-radius: var(--r-xs); background: #fff; color: var(--b-900); font-size: 2.8cqw; text-align: center; }
    .inventory-label__qr svg { display: block; width: 100%; height: 100%; shape-rendering: crispEdges; }
    .inventory-label__qr.has-error { color: var(--danger); font-weight: 700; }

    /* Segunda tarjeta, del mismo tamaño que la etiqueta: el PNG que sube quien
       da de alta el artículo. Va sin margen ni adornos porque el diseño ya
       viene resuelto en el archivo; aquí solo se le da el formato de papel. */
    .inventory-label--preview { display: block; overflow: hidden; aspect-ratio: 96/61; padding: 0; background: #fff; }
    .inventory-label__preview { display: block; width: 100%; height: 100%; object-fit: cover; }

    @media(max-width:760px) {
        .inventory-scan-card { grid-template-columns: 1fr; }
        .inventory-scan-card__operations,.inventory-scan-card__actions,.inventory-scan-card__notice,.inventory-scan-card__return,.inventory-scan-card__history { grid-column: 1; }
    }

    @media print {
        /* Solo la geometria: los cuerpos de texto ya escalan solos con cqw. */
        .inventory-label-sheet { grid-template-columns: repeat(2,1fr); gap: var(--gap-inventory-label-print); }
        .inventory-label { width: 96mm; height: 61mm; min-height: 0; border-radius: 0; }
    }

    .inventory-summary-kpis {
        margin-bottom: var(--sp-7);
    }

    /* La lista de «Identificacion y custodia» no tenia ni una regla propia:
       rotulo y dato salian pegados porque ambos son elementos en linea. */
    .detail-list { display: grid; gap: var(--sp-4); margin-bottom: var(--sp-5); }
    .detail-list > div { display: flex; min-width: 0; flex-direction: column; gap: var(--sp-1); padding-bottom: var(--sp-3); border-bottom: 1px solid var(--line); }
    .detail-list > div:last-child { padding-bottom: 0; border-bottom: 0; }
    .detail-list span { color: var(--muted); font-size: var(--fs-xs); font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase; }
    .detail-list strong { overflow-wrap: anywhere; }
    @media (min-width: 620px) {
        .detail-list { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
    }

    .inventory-item-form {
        width: 100%;
        max-width: none;
        margin-inline: 0;
    }

    /* La pregunta que mas se equivocaba —cuanto material hay— deja de tener el
       mismo peso visual que el resto: si compite con el umbral de aviso, se
       vuelven a confundir. */
    .form-field--destacado {
        padding: var(--sp-5);
        border: 1px solid color-mix(in srgb, var(--brand) 28%, var(--line));
        border-radius: var(--r-sm);
        background: var(--brand-soft);
    }
    .form-field--destacado > label { font-size: var(--fs-base); font-weight: 700; }
    .form-field--destacado input { background: #fff; font-size: var(--fs-lg); font-weight: 700; }
    /* La nota ya esta dentro de un bloque tenido: repetir el recuadro seria
       una caja dentro de otra. */
    .form-field--destacado .form-note { margin-bottom: 0; padding: 0; border: 0; background: none; }
}


    /* Lector de QR. Se usa de pie en un almacén y con una mano: el visor manda,
       los controles son grandes y el texto de estado no se mueve de sitio para
       que no haya que buscarlo entre fotograma y fotograma. */
    .scan-dialog {
        width: min(94vw, 460px);
        max-height: 92dvh;
        padding: var(--sp-6);
        overflow-y: auto;
        border: 1px solid var(--surface-border);
        border-radius: var(--r);
        background: var(--surface);
        color: var(--ink);
    }
    .scan-dialog::backdrop { background: rgb(10 26 48 / 62%); }
    .scan-dialog:not([open]) { display: none; }
    .scan-dialog--fallback[open] {
        display: block; position: fixed; inset: 0; margin: auto;
        z-index: 10000; height: fit-content; max-height: 92vh;
        box-shadow: 0 0 0 100vmax rgb(10 26 48 / 62%);
    }
    .scan-dialog [hidden] { display: none !important; }
    .scan-dialog__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-5); }
    .scan-dialog__title { margin: 0; font-size: var(--fs-lg); }
    .scan-dialog__frame { position: relative; overflow: hidden; aspect-ratio: 1; border-radius: var(--r-sm); background: var(--b-900); }
    .scan-dialog__video { display: block; width: 100%; height: 100%; object-fit: cover; }
    /* La retícula no decodifica nada: dice dónde poner la etiqueta, que es la
       diferencia entre apuntar y adivinar. */
    .scan-dialog__reticle {
        position: absolute;
        inset: 18%;
        border: 3px solid rgb(255 255 255 / 82%);
        border-radius: var(--r-sm);
        box-shadow: 0 0 0 100vmax rgb(10 26 48 / 28%);
    }
    .scan-dialog__status { min-height: 2.6em; margin: var(--sp-5) 0 0; color: var(--ink-2); font-size: var(--fs-base); line-height: 1.4; }
    .scan-dialog__status.has-error { color: var(--danger); font-weight: 700; }
    /* [hidden] tiene que ganar: es la tercera vez que este proyecto tropieza
       con que una regla de autor con display: se come el display:none del
       atributo. Ver .cal-rolefilter__pop[hidden] en calendar.css. */
    .scan-dialog__detail { margin: var(--sp-3) 0 0; color: var(--ink-3); font-size: var(--fs-xs); word-break: break-word; }
    .scan-dialog__detail[hidden] { display: none; }
    .scan-dialog__manual { margin-top: var(--sp-5); padding-top: var(--sp-5); border-top: 1px solid var(--line); }
    .scan-dialog__manual label { display: block; margin-bottom: var(--sp-2); color: var(--ink-2); font-size: var(--fs-sm); }
    .scan-dialog__manual-row { display: flex; gap: var(--sp-3); }
    .scan-dialog__manual-row input { flex: 1 1 auto; min-width: 0; text-transform: uppercase; }
    .scan-dialog__manual-row .btn { flex: 0 0 auto; }

    @media (max-width: 480px) {
        .scan-dialog { width: 100vw; max-width: none; max-height: 100dvh; height: 100dvh; margin: 0; border: 0; border-radius: 0; }
        .scan-dialog__frame { aspect-ratio: auto; height: min(52dvh, 380px); }
    }
@layer legacy {
    /* Error servido DENTRO del armazón (N-35 / DoD S-3). La persona conserva
       su navegación: quien se topa con un 403 no ha dejado de trabajar, se ha
       equivocado de puerta. */
    .error-inline { text-align: left; }
    .error-inline .error-code {
        display: inline-block; margin-bottom: var(--sp-5);
        font-size: var(--fs-3xl); font-weight: 700; color: var(--ink-3);
        letter-spacing: var(--tracking-display);
    }
    .error-inline p { margin: 0 0 var(--sp-5); color: var(--ink-2); max-width: 62ch; }
    .error-inline__salidas { display: flex; flex-wrap: wrap; gap: var(--sp-5); }
}
