/* ============================================================
   Bitácora — sistema de diseño "sala de comando"
   Portado de flacso-tickets y extendido para documentación,
   novedades y administración.
   ============================================================ */

:root {
    --f-display: 'Space Grotesk', system-ui, sans-serif;
    --f-body: 'Inter', system-ui, sans-serif;
    --f-mono: 'JetBrains Mono', ui-monospace, monospace;
}

html[data-theme="dark"] {
    --bg: #04070e; --panel: #0a1120; --panel-2: #101a2e; --panel-3: #17243c;
    --line: rgba(122, 152, 196, .16); --line-strong: rgba(122, 152, 196, .34);
    --ink: #e9eff8; --ink-2: #9fb1cc; --ink-3: #657795;
    --accent: #31e7ff; --accent-ink: #04070e; --accent-soft: rgba(49, 231, 255, .12);
    --ok: #2fe0a6; --warn: #ffb020; --bad: #ff5c7a; --sensitive: #8b7dff;
    --ok-soft: rgba(47, 224, 166, .13); --warn-soft: rgba(255, 176, 32, .14);
    --bad-soft: rgba(255, 92, 122, .14); --sensitive-soft: rgba(139, 125, 255, .15);
    --grid: rgba(122, 152, 196, .05); --glow: rgba(49, 231, 255, .45);
    --shadow: 0 18px 44px rgba(0, 0, 0, .55);
    /* La red del fondo (ver .fondo-red). Sobre oscuro el realce ILUMINA: la
       malla es tinta apagada y el puntero la enciende con el acento. */
    --red-nodo: var(--ink-3); --red-realce: var(--accent); --red-tono: 1;
}

html[data-theme="light"] {
    --bg: #e9eef6; --panel: #ffffff; --panel-2: #f3f7fc; --panel-3: #e6edf6;
    --line: #d3dced; --line-strong: #b4c3da;
    --ink: #0c1626; --ink-2: #42536e; --ink-3: #6a7c96;
    --accent: #0a97b3; --accent-ink: #ffffff; --accent-soft: rgba(10, 151, 179, .10);
    --ok: #0d8f68; --warn: #b46a00; --bad: #d92047; --sensitive: #5b4bd6;
    --ok-soft: rgba(13, 143, 104, .10); --warn-soft: rgba(180, 106, 0, .12);
    --bad-soft: rgba(217, 32, 71, .10); --sensitive-soft: rgba(91, 75, 214, .12);
    --grid: rgba(24, 58, 110, .045); --glow: rgba(10, 151, 179, .28);
    --shadow: 0 16px 38px rgba(24, 48, 92, .14);
    /* Sobre claro el realce OSCURECE, al reves que en oscuro. La malla es el
       verde agua de los botones y el puntero la hunde a un teal mas profundo.
       Con el acento como realce el hover ACLARABA: #0a97b3 tiene mas
       luminancia que el gris #6a7c96 que se usaba de base, asi que el efecto
       iba justo para el lado contrario al que se buscaba.
       El tono sube a .9 (antes .55): con la malla en acento, cortar la mitad
       de la opacidad la dejaba imperceptible. */
    --red-nodo: var(--accent); --red-realce: #05505f; --red-tono: .9;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    min-height: 100vh;
    background-color: var(--bg);
    background-image: linear-gradient(var(--grid) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid) 1px, transparent 1px);
    background-size: 48px 48px;
    color: var(--ink);
    font-family: var(--f-body);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* La red de nodos del fondo. Va fija al viewport y con z-index negativo:
   el fondo de <body> se propaga al lienzo de la página y se pinta por debajo
   de todo, así que la red queda entre ese fondo y el contenido. No recibe
   eventos — el puntero lo escucha el controller en window. */
.fondo-red {
    position: fixed; top: 0; left: 0; z-index: -1;
    /* width/height explícitos y NO `inset: 0`. El canvas es un elemento
       reemplazado: posicionado y con `width: auto`, el ancho sale de su tamaño
       intrínseco (300x150 por defecto) y el `right` se ignora. Con `inset: 0`
       el lienzo nunca se estira solo; parece que sí porque el JS le escribe
       `canvas.width`, que es justo lo que no hay que depender. */
    width: 100%; height: 100%;
    display: block; pointer-events: none;
}

::selection { background: var(--accent); color: var(--accent-ink); }

@keyframes led { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

a { color: var(--accent); }

/* ============ CMDBAR ============ */

.cmdbar {
    position: sticky; top: 0; z-index: 20;
    display: flex; align-items: center; gap: 20px;
    height: 60px; padding: 0 24px;
    background: color-mix(in srgb, var(--panel) 88%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--line-strong);
}

.marca { display: flex; align-items: center; gap: 11px; text-decoration: none; color: var(--ink); }
.marca-texto { line-height: 1.05; display: flex; flex-direction: column; }
.marca-nombre { font-family: var(--f-display); font-weight: 700; font-size: 15px; letter-spacing: .02em; }
.marca-sub { font-family: var(--f-mono); font-size: 9.5px; letter-spacing: .24em; color: var(--ink-3); text-transform: uppercase; }

/* Con nueve secciones la barra se iba a dos líneas y empujaba la aplicación
   para abajo. Ahora scrollea en horizontal y la altura queda fija. */
.cmdnav {
    display: flex; gap: 2px; margin-left: 8px;
    overflow-x: auto; scrollbar-width: none; min-width: 0;
}
.cmdnav::-webkit-scrollbar { display: none; }
.cmdnav-item {
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-2); padding: 7px 10px; border-radius: 7px; text-decoration: none;
    white-space: nowrap; transition: background .15s, color .15s;
}
.cmdnav-item:hover { background: var(--panel-3); color: var(--ink); }
.cmdnav-item.activo { color: var(--accent-ink); background: var(--accent); }

.cmdbar-derecha { margin-left: auto; display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.fuente-viva { display: flex; align-items: center; gap: 7px; font-family: var(--f-mono); font-size: 11px; color: var(--ink-2); }
.fuente-viva .rol { color: var(--accent); }

.led {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--accent); box-shadow: 0 0 8px var(--glow);
    animation: led 2.4s ease-in-out infinite; flex-shrink: 0;
}
.led-ok { background: var(--ok); box-shadow: 0 0 8px var(--ok); }

/* Botones cuadrados de la barra: llave, tema, salir. */
.btn-icono {
    display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--f-mono); font-size: 12px; color: var(--ink);
    background: var(--panel-2); border: 1px solid var(--line-strong);
    border-radius: 7px; width: 32px; height: 32px; padding: 0;
    margin: 0; cursor: pointer; text-decoration: none;
}
.btn-icono:hover { border-color: var(--accent); color: var(--accent); }

/* ============ LAYOUT ============ */

.contenido, main { max-width: 1400px; margin: 0 auto; padding: 28px 24px 90px; }

h1 { font-family: var(--f-display); font-weight: 700; font-size: 28px; margin: 6px 0 18px; letter-spacing: -.01em; }
h2 { font-family: var(--f-mono); font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2); margin: 26px 0 12px; }
h3 { font-family: var(--f-display); font-size: 15px; margin: 0 0 8px; }

.sobretitulo { font-family: var(--f-mono); font-size: 11px; letter-spacing: .24em; text-transform: uppercase; color: var(--accent); }

.meta { font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-2); margin: .3rem 0; }
.meta i { color: var(--ink-3); margin-right: 4px; }
.mono { font-family: var(--f-mono); font-size: 11px; color: var(--ink); }

.error, .exito {
    font-family: var(--f-mono); font-size: 12px;
    border-radius: 8px; padding: 11px 14px; border: 1px solid; margin: 0 0 14px;
}
.error { color: var(--bad); background: var(--bad-soft); border-color: var(--bad); }
.exito { color: var(--ok); background: var(--ok-soft); border-color: var(--ok); }

.volver {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--f-mono); font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ink-2); text-decoration: none; margin-bottom: 18px;
}
.volver:hover { color: var(--accent); }

.btn {
    display: inline-flex; align-items: center; gap: 7px;
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--accent-ink); background: var(--accent); border: 1px solid var(--accent);
    border-radius: 8px; padding: 9px 15px; text-decoration: none;
    transition: filter .15s;
}
.btn:hover { filter: brightness(1.12); }

/* Encabezado de página: sobretítulo + h1 a la izquierda, acción a la derecha. */
.board-encabezado {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 16px; flex-wrap: wrap; margin-bottom: 22px;
}
.board-encabezado h1 { margin: 4px 0 0; }

.rango { display: flex; gap: 6px; }
.rango a {
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ink-2); background: var(--panel-2); border: 1px solid var(--line-strong);
    border-radius: 7px; padding: 7px 12px; text-decoration: none;
}
.rango a:hover { border-color: var(--accent); color: var(--accent); }
.rango a.activo { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }

/* ============ BOARD KANBAN ============ */

/* ============ FILTROS DEL KANBAN (chips multi-select) ============ */

.filtros { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 14px 0 26px; }

.filtro-chip { position: relative; }
.filtro-chip > summary {
    display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
    background: var(--panel-2); border: 1px solid var(--line-strong); border-radius: 999px;
    padding: 6px 13px; font-size: 12.5px; color: var(--ink); white-space: nowrap;
    list-style: none; user-select: none;
}
.filtro-chip > summary::-webkit-details-marker { display: none; }
.filtro-chip > summary:hover { border-color: var(--accent); }
.filtro-chip.aplicado > summary { border-color: var(--accent); background: var(--accent-soft); }
.filtro-pref {
    font-family: var(--f-mono); font-size: 9.5px; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-3);
}
.filtro-caret { color: var(--ink-3); font-size: 9px; }
.filtro-mas {
    font-family: var(--f-mono); font-size: 10px; color: var(--accent);
    background: var(--accent-soft); border-radius: 999px; padding: 1px 7px;
}
.filtro-quitar {
    all: unset; cursor: pointer; color: var(--accent); font-size: 11px; line-height: 1;
    padding: 2px 3px; border-radius: 4px;
}
.filtro-quitar:hover { background: var(--accent-soft); }

/* La salida del filtro recordado. Se pinta como aviso, no como accion neutra:
   si hay filtro puesto hay tarjetas que no se estan viendo, y eso tiene que
   saltar a la vista. */
.filtros-limpiar {
    display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
    font-size: 11.5px; color: var(--warn); background: var(--warn-soft);
    border: 1px solid var(--warn-soft); border-radius: 999px; padding: 4px 11px;
}
.filtros-limpiar:hover { border-color: var(--warn); }

.filtro-menu {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 30; min-width: 220px;
    max-height: 340px; overflow-y: auto;
    background: var(--panel); border: 1px solid var(--accent); border-radius: 10px;
    box-shadow: var(--shadow); padding: 8px;
}
.filtro-opcion {
    display: flex; align-items: center; gap: 10px; margin: 0;
    padding: 7px 10px; border-radius: 7px; font-size: 13px; color: var(--ink);
    font-family: var(--f-body); text-transform: none; letter-spacing: normal; cursor: pointer;
    white-space: nowrap;
}
.filtro-opcion:hover { background: var(--accent-soft); }
.filtro-opcion input[type="checkbox"] {
    width: 15px; height: 15px; margin: 0; accent-color: var(--accent); flex-shrink: 0;
}
.filtro-nota { color: var(--ink-3); font-size: 11.5px; }

.filtros-conteo { font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3); margin-left: 6px; }
.filtros noscript button { margin-top: 0; }

.link-sprints {
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--warn); text-decoration: none; margin-left: auto; white-space: nowrap;
}
.link-sprints:hover { filter: brightness(1.15); }

/* El kanban usa TODA la pantalla: el main de esa pagina es fluido (sin el
   max-width centrado), asi el titulo, los chips y el tablero comparten el
   mismo borde izquierdo. Ademas la pagina se arma en columna y el tablero
   se estira hasta abajo: su scrollbar horizontal queda pegada al borde
   inferior de la pantalla, no colgando a mitad de pagina. */
/* La altura tiene que estar DEFINIDA, no ser un piso.
 *
 * El `body` global es `min-height: 100vh`, y eso alcanza para casi todo — pero
 * no para el kanban. `flex: 1` reparte el espacio DISPONIBLE, y si el
 * contenedor de mas arriba solo declara un minimo, no hay espacio disponible
 * que repartir: el body crece con su contenido, el tablero se estira hasta la
 * columna mas larga y las columnas nunca llegan a scrollear su interior. Se ve
 * como "las tarjetas se cortan abajo y tengo que scrollear la pagina entera".
 *
 * Con `height` fija la cadena cierra: body -> main-fluido -> tablero ->
 * columna-cards, y el scroll queda donde tiene que estar: mientras el tablero
 * entre, la pagina no scrollea — scrollean el tablero (horizontal) y cada
 * columna (vertical).
 *
 * `svh` y no `dvh`, y esto es fino: `dvh` sigue a la barra de direcciones del
 * celular, y ahora que la pagina SI puede scrollear, scrollear es justo lo que
 * hace colapsar esa barra. Como el contenido esta clavado por el piso de
 * `.tablero`, al colapsar la barra el viewport gana ~70px, el overflow se va a
 * cero, la pagina vuelve al tope, la barra reaparece y el ciclo se repite: el
 * tablero rebota solo. `svh` es el alto CON la barra visible y no cambia
 * durante el scroll. Mientras la pagina estaba clavada el `dvh` era estable y
 * no se notaba — el que lo destapa es este arreglo. El `100vh` queda de
 * reserva para quien no entienda `svh`.
 *
 * Y el `overflow-y` es `auto`, NO `hidden`, que es lo que hace que la pantalla
 * chica siga siendo usable: mientras el tablero entra, `flex: 1` lo achica
 * hasta el alto disponible y no hay nada que scrollear — la pagina se queda
 * quieta y scrollean las columnas, igual que antes. Cuando NO entra (portatil
 * bajo, celular apaisado, la barra de filtros en dos lineas), el piso de
 * `.tablero` empuja el contenido mas alla de los 100dvh y aparece el scroll
 * general. Un solo mecanismo para los dos casos, sin media query que adivine
 * a partir de que alto se rompe.
 *
 * (Ojo: `overflow` en el `body` se PROPAGA al viewport cuando el `html` es
 * `visible`, asi que el que scrollea es la pagina, no la caja del body. Por
 * eso el cajon `position: fixed` no se entera de nada.)
 *
 * Y por esa misma propagacion el eje X va en `auto` y NO en `hidden`: cortarlo
 * no aporta nada al arreglo —el tablero se contiene solo— y en cambio clipea
 * la PAGINA. El desplegable de un filtro es `position: absolute` con
 * `min-width: 220px` y opciones `nowrap`: si el chip cae cerca del borde
 * derecho, el menu se pasa, y con el eje cortado queda inalcanzable en vez de
 * ofrecer scroll.
 *
 * `overscroll-behavior-y: contain` en el body, en cambio, SI: corta el
 * pull-to-refresh del celular sin encerrar a nadie. Es lo que antes hacia,
 * de rebote, el `contain` de la columna. Lo de la columna encerraba; esto no:
 * el encadenamiento columna -> pagina sigue vivo, lo unico que se contiene es
 * el rebote de la pagina contra el navegador. */
body:has(.main-fluido) {
    display: flex; flex-direction: column;
    height: 100vh;
    height: 100svh;
    overflow-x: auto; overflow-y: auto;
    overscroll-behavior-y: contain;
}
/* El `min-height: 0` NO es decorativo: sin el, un hijo flex no se deja
   encoger por debajo de su contenido (`min-height: auto` es el default), el
   main crece con la columna mas alta y arrastra al body. Es el eslabon que
   hace que la cadena de alturas cierre hasta el tablero. */
.main-fluido {
    max-width: none; width: 100%;
    flex: 1; min-height: 0;
    display: flex; flex-direction: column; padding-bottom: 10px;
}

/* El scroll VERTICAL vive en cada columna, no en el tablero. El tablero solo
   scrollea horizontal.
 *
 * Antes el tablero declaraba `overflow-x: auto` y nada mas, y ahi esta la
 * trampa: por spec, si UN eje es distinto de `visible`, el otro se computa
 * como `auto`. O sea que el tablero scrolleaba en los DOS ejes sin que nadie
 * lo pidiera. Con las columnas sin limite de alto, el gesto se lo comia
 * primero el eje vertical y el horizontal recien respondia al llegar al
 * fondo — "para ir a la derecha primero tengo que bajar del todo".
 *
 * De ahi que el `overflow-y: hidden` sea EXPLICITO: es lo unico que apaga ese
 * eje fantasma. Y `align-items: stretch` (antes flex-start) es lo que le da a
 * cada columna una altura contra la cual scrollear su propio interior. */
/* El `min-height` es el PISO de usabilidad, y es la otra mitad del arreglo de
   la pantalla chica. `flex: 1` con `min-height: 0` deja que el tablero se
   encoja hasta la nada: en un portatil bajo, entre el encabezado, el titulo y
   los filtros no queda casi alto, y la columna se comprime a una franja donde
   no entra ni media tarjeta. Con el piso, el tablero deja de encogerse, se
   pasa de los 100dvh del body y ahi aparece el scroll de la pagina.

   320px son un encabezado de columna, el alta rapida y dos tarjetas: el
   minimo con el que la columna todavia se puede leer y arrastrar.

   El piso se le pide al `:has` y no al `.tablero` a secas porque una columna
   plegada no muestra tarjetas: son 46px de franja. Y plegar es justo la salida
   documentada para que el tablero entre en una pantalla chica — con el piso
   fijo, plegarlas todas seguia dejando scroll de pagina para no mostrar nada.
   Sin ninguna columna desplegada no hay nada que sostener. */
.tablero {
    display: flex; gap: 14px; align-items: stretch;
    flex: 1; min-height: 0;
    overflow-x: auto; overflow-y: hidden;
    overscroll-behavior-x: contain;
    padding: 4px 2px 6px; scrollbar-width: thin;
}
.tablero:has(.columna:not(.colapsada)) { min-height: 320px; }
.tablero .columna { flex: 0 0 300px; min-width: 300px; }
/* La columna se arma en filas: encabezado y alta rapida fijos arriba, y las
   tarjetas ocupando el resto con su propio scroll. */
.tablero .columna { display: flex; flex-direction: column; }
/* Sin `overscroll-behavior-y: contain` a proposito. Contener el eje vertical
   cortaba el encadenamiento: al llegar al fondo de la columna el gesto moria
   ahi, y en la pantalla chica —justo donde la pagina SI tiene para scrollear—
   el usuario quedaba encerrado en la columna. Antes daba igual porque la
   pagina estaba clavada; ahora seria el bug.
   Lo unico que ese `contain` protegia de verdad era el pull-to-refresh, y eso
   ahora lo cubre el `body`, que es donde corresponde: ahi corta el rebote de
   la pagina sin tocar el encadenamiento de la columna. */
.tablero .columna-cards {
    flex: 1; min-height: 0;
    overflow-y: auto;
    scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent;
}
/* La barra se VE. Con `thin` a secas, sobre el panel oscuro queda
   practicamente invisible y la columna parece cortada en vez de scrolleable:
   nadie adivina que hay tres tarjetas mas abajo. */
.tablero .columna-cards::-webkit-scrollbar { width: 8px; }
.tablero .columna-cards::-webkit-scrollbar-track { background: transparent; }
.tablero .columna-cards::-webkit-scrollbar-thumb {
    background: var(--line-strong); border-radius: 4px;
    border: 2px solid transparent; background-clip: content-box;
}
.tablero .columna-cards:hover::-webkit-scrollbar-thumb { background: var(--ink-3); background-clip: content-box; }
.board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; align-items: start; }
@media (max-width: 1100px) { .board { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .board { grid-template-columns: 1fr; } }

.columna {
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    box-shadow: var(--shadow); overflow: hidden;
}
.columna-titulo {
    display: flex; align-items: center; gap: 9px; padding: 13px 16px;
    border-bottom: 1px solid var(--line);
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink-2);
    margin: 0;
}
.columna-titulo i { font-size: 11px; }
.col-nuevo .led { background: var(--accent); box-shadow: 0 0 8px var(--glow); }
.col-curso .led { background: var(--warn); box-shadow: 0 0 8px var(--warn); }
.col-espera .led { background: var(--sensitive); box-shadow: 0 0 8px var(--sensitive); }
.col-resuelto .led { background: var(--ok); box-shadow: 0 0 8px var(--ok); }

.columna-contador, .cuenta {
    margin-left: auto; font-family: var(--f-mono); font-size: 11px;
    color: var(--ink); background: var(--panel-3); border-radius: 5px; padding: 2px 8px;
}

.columna-cards { display: flex; flex-direction: column; gap: 10px; padding: 12px; min-height: 120px; }

.columna-vacia, .vacio {
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 26px 0; color: var(--ink-3); font-size: 12px; font-style: normal;
}
.columna-vacia i, .vacio i { font-size: 20px; opacity: .55; }

/* ============ CARD ============ */

.card, .tarjeta {
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px;
    padding: 12px 14px;
    /* Sin `transform` en la transicion, y es una decision, no una poda.
     *
     * Sortable mueve el clon del arrastre escribiendole `transform: matrix(...)`
     * en CADA mousemove. Con una transicion de .1s encima, cada uno de esos
     * movimientos se ANIMA en vez de saltar: el clon queda 100ms atras del
     * cursor y, moviendo rapido, nunca llega al destino antes de la siguiente
     * actualizacion. Se reporto como "el arrastre se mueve poco".
     *
     * Estuvo dormida hasta que el arrastre paso a forceFallback: con el drag
     * nativo el clon lo pintaba el navegador y el CSS de la tarjeta no lo
     * tocaba. Y no animaba nada igual — ninguna regla le pone transform a
     * .card. La de .sprint-card queda como esta: esas no se arrastran. */
    transition: border-color .15s;
}
/* La manito de arrastre sólo dentro del tablero: en «Lo mío» las mismas
   tarjetas se muestran sin SortableJS y no se pueden mover. */
.columna-cards .card { cursor: grab; }
.columna-cards .card:active { cursor: grabbing; }
.card:hover, .tarjeta:hover { border-color: var(--accent); }

.grilla-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
/* El HUECO que la tarjeta deja en la columna mientras se la lleva. */
.card.sortable-ghost { opacity: .35; border-style: dashed; border-color: var(--accent); }

/* Y el CLON que sigue al puntero (forceFallback + fallbackOnBody).
 *
 * Va despues del ghost a proposito: Sortable le pone las DOS clases al clon, y
 * con la misma especificidad gana la ultima. Sin esto, la tarjeta que llevas en
 * la mano se dibuja al 35% y punteada — el look del hueco, no el de lo que
 * estas cargando.
 *
 * Y NO lleva `transform`: Sortable le escribe `translate3d(...)` inline para
 * moverlo. El `rotate(2deg)` que habia aca era del arrastre nativo, donde el
 * clon lo pintaba el navegador; ahora seria pelearle al posicionamiento por un
 * efecto cosmetico. Se cambia por una sombra, que no toca transform. */
.card.sortable-fallback {
    opacity: 1; border-style: solid; border-color: var(--accent);
    box-shadow: var(--shadow); cursor: grabbing; pointer-events: none;

    /* El candado: el clon NO transiciona nada.
     *
     * Sortable le reescribe el `transform` en cada mousemove, asi que
     * cualquier transicion sobre esa propiedad lo deja corriendo atras del
     * cursor. Ya paso una vez con el `transform .1s` que .card traia heredado.
     * Sortable limpia el `transition` INLINE del clon, pero eso no apaga una
     * regla de la hoja de estilos — por eso el candado va aca y no se confia
     * en que la libreria lo resuelva. */
    transition: none;
}

.card-encabezado { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 7px; }
.card-numero { font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3); }

.card-titulo, .tarjeta a {
    display: block; color: var(--ink); text-decoration: none;
    font-weight: 600; font-size: 13.5px; line-height: 1.35; margin-bottom: 8px;
}
.card-titulo:hover, .tarjeta a:hover { color: var(--accent); }

.card-responsable { font-size: 12px; color: var(--ink-2); display: flex; align-items: center; gap: 6px; }
.card-responsable i { font-size: 10px; color: var(--ink-3); }

.persona-telefono { font-size: 13px; display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.persona-telefono i, .miembro-telefono i { font-size: 10px; color: var(--ink-3); }
.miembro-telefono { display: block; font-size: 11.5px; color: var(--ink-2); margin-top: 2px; }
.formulario-telefono { margin-top: 14px; }

.panel-accion {
    margin-left: auto; font-size: 11.5px; font-weight: 500; color: var(--ink-2);
    text-decoration: none; display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px; border-radius: 6px; background: var(--panel-3);
}
.panel-accion:hover { color: var(--ink-1); }
.panel-accion i { font-size: 9.5px; }

.card-objetivo {
    font-size: 11.5px; color: var(--ink-2); display: flex; align-items: center; gap: 6px;
    margin-top: 5px; min-width: 0;
}
.card-objetivo i { font-size: 10px; color: var(--ink-3); flex-shrink: 0; }

.card-pie { display: flex; align-items: center; gap: 8px; margin-top: 9px; flex-wrap: wrap; }
.card-fecha { font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3); }
.card-tipo {
    font-family: var(--f-mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
    color: var(--ink-2); background: var(--panel-3); border-radius: 5px; padding: 2px 7px;
}
.card-origen { color: var(--ink-2); font-size: 11px; }
.card-proyecto {
    font-family: var(--f-mono); font-size: 10px; letter-spacing: .04em;
    color: var(--ink-2); background: var(--panel-3); border-radius: 5px; padding: 2px 7px;
}
.card.vencido, .tarjeta.vencido { border-color: var(--bad); }

/* ============ PILLS ============ */

.pill {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
    border-radius: 5px; padding: 3px 9px; border: 1px solid;
}
.pill-baja { color: var(--ink-3); background: var(--panel-3); border-color: var(--line-strong); }
.pill-media { color: var(--ink-2); background: var(--panel-3); border-color: var(--line-strong); }
.pill-alta { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }
.pill-urgente { color: var(--bad); background: var(--bad-soft); border-color: var(--bad); }
.pill-critica { color: var(--bad); background: var(--bad-soft); border-color: var(--bad); }

.pill-estado-nuevo { color: var(--accent); background: var(--accent-soft); border-color: var(--accent); }
.pill-estado-en_curso { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }
.pill-estado-esperando_respuesta { color: var(--sensitive); background: var(--sensitive-soft); border-color: var(--sensitive); }
.pill-estado-resuelto { color: var(--ok); background: var(--ok-soft); border-color: var(--ok); }

.pill-publico { color: var(--ok); background: var(--ok-soft); border-color: var(--ok); }
.pill-interno { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }
.pill-restringido { color: var(--bad); background: var(--bad-soft); border-color: var(--bad); }

/* ============ PANEL / DETALLE ============ */

.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); overflow: hidden; margin-bottom: 20px; }
.panel-titulo {
    display: flex; align-items: center; gap: 10px; padding: 14px 20px;
    border-bottom: 1px solid var(--line);
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-2);
    margin: 0;
}
.panel-titulo .pill { margin-left: auto; }
.panel-cuerpo { padding: 20px; }
.panel-cuerpo > form:first-child > label:first-child { margin-top: 0; }

.panel-alerta { border-color: var(--warn); }
.panel-alerta .panel-titulo { color: var(--warn); border-bottom-color: var(--warn); background: var(--warn-soft); }

.detalle-grilla { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; align-items: start; }
@media (max-width: 900px) { .detalle-grilla { grid-template-columns: 1fr; } }
.detalle-lateral { display: flex; flex-direction: column; gap: 20px; }

.detalle-titulo { font-family: var(--f-display); font-weight: 700; font-size: 22px; margin: 0 0 14px; letter-spacing: -.01em; }
.detalle-meta { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; font-size: 12.5px; color: var(--ink-2); margin-bottom: 18px; }

.cuerpo-texto {
    font-size: 13.5px; line-height: 1.65; color: var(--ink-2);
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 16px; white-space: pre-wrap; word-break: break-word; margin: 0;
}

.historial { display: flex; flex-direction: column; gap: 10px; list-style: none; padding: 0; margin: 0; font-size: 12.5px; color: var(--ink-2); }
.historial li { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.historial .hora, .historial-fecha { font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3); flex-shrink: 0; }
.historial code { font-family: var(--f-mono); font-size: 10.5px; color: var(--accent); background: var(--accent-soft); border-radius: 4px; padding: 1px 6px; }

.comentario {
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 12px 14px; margin-bottom: 10px;
}
.comentario .meta { margin-top: 0; }

.alerta { color: var(--warn); }

/* Token o link para copiar: se lee de un vistazo y se selecciona al hacer clic. */
.secreto {
    font-family: var(--f-mono) !important; font-size: 11.5px !important;
    max-width: 100%; width: 100%; cursor: text;
}

.en-linea { display: inline-flex; gap: 6px; align-items: center; }
.en-linea button { margin-top: 0; }

.origen {
    font-family: var(--f-mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
    color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent);
    border-radius: 5px; padding: 1px 7px;
}

/* ============ FORMULARIOS ============ */

label { display: block; margin: 16px 0 6px; font-family: var(--f-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }

/* Aclaracion debajo de un campo: para lo que el label no alcanza a explicar
   sin volverse una oracion. Va pegada al input, no separada como un parrafo. */
.ayuda { margin: 5px 0 0; font-size: 12px; line-height: 1.45; color: var(--ink-2); }
.ayuda strong { color: var(--ink); font-weight: 600; }
label input[type="checkbox"] { margin-right: 8px; }

input[type="text"], input[type="email"], input[type="password"], input[type="search"], select, textarea {
    width: 100%; max-width: 560px;
    background: var(--panel-2); border: 1px solid var(--line-strong); border-radius: 8px;
    color: var(--ink); font-family: var(--f-body); font-size: 13.5px; padding: 10px 12px;
    outline: none; transition: border-color .15s, box-shadow .15s;
}
textarea { font-family: var(--f-mono); font-size: 12.5px; line-height: 1.6; }
input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input::placeholder, textarea::placeholder { color: var(--ink-3); }
small { display: block; margin-top: 5px; font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3); }

button {
    display: inline-flex; align-items: center; gap: 7px;
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--accent-ink); background: var(--accent); border: 1px solid var(--accent);
    border-radius: 8px; padding: 9px 15px; cursor: pointer; margin-top: 12px;
    transition: filter .15s;
}
button:hover { filter: brightness(1.12); }

/* El submit de un formulario vertical va DEBAJO del ultimo campo, no al lado.
   Los campos miden hasta 560px y el boton es inline: en un panel ancho sobra
   lugar a la derecha y el boton se acomoda ahi, alineado a la base del campo.
   Block-level (display:flex) le da renglon propio; width:fit-content lo deja
   midiendo lo que mide. En los formularios que SI son una fila (.buscador,
   .filtros, .en-linea, .fechas-sprint, .acciones) el boton es un flex item y
   esto no lo mueve: los flex items ya son de bloque y no arman renglon. */
form > button { display: flex; width: fit-content; }
.acciones { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.acciones button { margin-top: 0; background: var(--panel-3); color: var(--ink); border-color: var(--line-strong); }
.acciones button:hover { border-color: var(--accent); color: var(--accent); }

.buscador { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 20px; }
.buscador input { max-width: 420px; margin: 0; }
.buscador button { margin-top: 0; }

/* El cuerpo abre el cajon: que el cursor lo diga. El titulo, adentro, vuelve
   al cursor de link — son dos destinos distintos y se tienen que sentir asi. */
.card[data-controller~="tarjeta"], tr[data-controller~="tarjeta"] { cursor: pointer; }
.card[data-controller~="tarjeta"] a, tr[data-controller~="tarjeta"] a { cursor: pointer; }

/* La auditoria: una tabla larga que se lee de arriba abajo. La columna del tipo
   de accion va apagada — clasifica la fila, no la cuenta: eso lo hace la frase
   de al lado. Ya no es el verbo crudo, asi que tampoco va en mono: la letra de
   maquina de escribir dice "esto es un dato tecnico", y dejo de serlo. */
.auditoria-tabla td { vertical-align: top; }
.auditoria-tabla .auditoria-verbo { color: var(--ink-3); font-size: 11.5px; white-space: nowrap; }
.auditoria-tabla .quien { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.auditoria-tabla .avatar-evento { flex-shrink: 0; margin: 0; }

/* Alta rapida: el mas vive en la columna y abre el formulario sin taparla.
   Cerrado es un boton chico; abierto, tres campos y listo. */
.alta-rapida-caja { border-bottom: 1px solid var(--line); }
.alta-rapida-mas {
    list-style: none; cursor: pointer; user-select: none;
    display: flex; align-items: center; justify-content: center;
    padding: 6px; font-size: 11px; color: var(--ink-3);
}
.alta-rapida-mas::-webkit-details-marker { display: none; }
.alta-rapida-mas:hover { color: var(--accent); background: var(--panel-2); }
details[open] > .alta-rapida-mas { color: var(--accent); }
.alta-rapida { padding: 4px 10px 12px; }
.alta-rapida input[type="text"], .alta-rapida select { max-width: 100%; font-size: 12.5px; padding: 6px 8px; }
.alta-rapida-fila { display: flex; gap: 6px; margin-top: 6px; }
.alta-rapida-fila select { flex: 1; min-width: 0; }
.alta-rapida button { margin-top: 8px; }

/* Las acciones del comentario propio. Discretas y al pie: son de quien lo
   escribio y nadie mas las va a usar, asi que no compiten con el texto. */
.comentario-acciones { display: flex; align-items: flex-start; gap: 12px; margin-top: 6px; }
.comentario-accion {
    all: unset; cursor: pointer; user-select: none; list-style: none;
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .08em;
    color: var(--ink-3);
}
.comentario-accion::-webkit-details-marker { display: none; }
.comentario-accion:hover { color: var(--accent); }
.comentario-accion-riesgo:hover { color: var(--bad); }
details[open] > .comentario-accion { color: var(--accent); }
.comentario-editar-caja { flex: 1; min-width: 0; }
.comentario-editar { margin-top: 8px; }
.comentario-editar textarea { width: 100%; font-size: 12.5px; }
.comentario-editar button { margin-top: 6px; }

/* Anular. Va cerrado y al final del panel: es lo que se hace una vez cada
   tanto, y abierto todo el tiempo le pone un boton rojo al lado a algo que la
   gente abre veinte veces por dia. */
.anular-caja { margin-top: 10px; }
.anular-abrir {
    list-style: none; cursor: pointer; user-select: none;
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-3);
}
.anular-abrir::-webkit-details-marker { display: none; }
.anular-abrir:hover { color: var(--bad); }
details[open] > .anular-abrir { color: var(--bad); }
.anular-item {
    margin-top: 12px; padding: 14px;
    background: var(--bad-soft); border: 1px solid var(--bad); border-radius: 10px;
}
.anular-nota { margin: 0 0 12px; font-size: 12.5px; color: var(--ink-2); }
.anular-item label {
    display: block; margin-bottom: 5px;
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-3);
}
.boton-peligro {
    margin-top: 12px;
    color: #fff; background: var(--bad); border: 1px solid var(--bad);
}
.boton-peligro:hover { filter: brightness(.9); }

/* Corregir el texto del ticket, desde el detalle. Cerrado es un renglon
   discreto: la descripcion es lo que la gente viene a leer, y un formulario
   abierto todo el tiempo le compite la atencion. */
.editar-caja { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 12px; }
.editar-abrir {
    list-style: none; cursor: pointer; user-select: none;
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-3);
}
.editar-abrir::-webkit-details-marker { display: none; }
.editar-abrir:hover { color: var(--accent); }
details[open] > .editar-abrir { color: var(--accent); }
.editar-contenido { margin-top: 12px; }
.editar-contenido label {
    display: block; margin-bottom: 5px;
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-3);
}
.editar-contenido input[type="text"] { margin-bottom: 14px; }
.editar-contenido button { margin-top: 12px; }

/* Editar EN EL LUGAR, no abajo.

   El <details> con el formulario es hermano del contenido renderizado; al
   abrirse lo reemplaza. Sin esto la descripcion se ve dos veces —renderizada y
   otra vez adentro del textarea— y en el cajon, que es angosto, corregir un
   renglon obliga a scrollear el ticket entero.

   Es CSS y no JavaScript a proposito: el <details> ya anda sin JS y `:has()`
   tambien, asi que el swap no depende de que Stimulus llegue a conectarse.
   Mismo patron que `.panel:has(.tacho-caja[open])`.

   El `>` no es decorativo: ata la regla a que el editor sea hermano DIRECTO de
   lo renderizado. Si alguien lo envuelve en un div, esto deja de aplicar. */
.cajon-cuerpo:has(> .editar-caja[open]) > .cajon-titulo,
.cajon-cuerpo:has(> .editar-caja[open]) > .descripcion-marco,
.panel-cuerpo:has(> .editar-caja[open]) > .detalle-titulo,
.panel-cuerpo:has(> .editar-caja[open]) > .descripcion-md { display: none; }

/* Abierto ya no es un apendice colgado al final: ocupa el lugar del contenido,
   asi que la linea que lo separaba de arriba sobra. */
.editar-caja[open] { margin-top: 0; border-top: 0; padding-top: 0; }

/* El mismo control abre y cancela; decir siempre "Editar el contenido" mientras
   el formulario esta abierto deja al usuario sin salida visible. */
.editar-rotulo-abierto { display: none; }
details[open] > .editar-abrir .editar-rotulo-cerrado { display: none; }
details[open] > .editar-abrir .editar-rotulo-abierto { display: inline; }

/* El MISMO formulario, ahora tambien en el cajon (`item/_contenido.html.twig`),
   que es angosto: sin esto el input y el textarea se pasan del panel. */
.cajon-cuerpo .editar-caja input[type="text"],
.cajon-cuerpo .editar-caja textarea { width: 100%; max-width: 100%; box-sizing: border-box; }

/* Escribir / Vista previa. Sin JavaScript no hay solapas y el textarea queda
   como estaba: la vista previa es una mejora, no un requisito para escribir. */
.solapas-md { display: flex; gap: 4px; margin-bottom: 6px; }
.solapa {
    margin: 0; padding: 4px 10px; font-size: 10px; letter-spacing: .08em;
    background: none; border: 1px solid transparent; color: var(--ink-3);
    border-radius: 6px 6px 0 0;
}
.solapa:hover { color: var(--ink-2); filter: none; }
.solapa-escribir { color: var(--accent); border-bottom-color: var(--accent); }
.previsualizando .solapa-escribir { color: var(--ink-3); border-bottom-color: transparent; }
.previsualizando .solapa-previa { color: var(--accent); border-bottom-color: var(--accent); }

.previsualizacion-salida {
    display: none; min-height: 84px; padding: 10px 12px;
    background: var(--panel-2); border: 1px solid var(--line-strong); border-radius: 8px;
    max-width: 560px;
}
.previsualizando > textarea { display: none; }
.previsualizando > .previsualizacion-salida { display: block; }

/* ============ CAJON LATERAL DEL ITEM ============ */

/* ---- El reporte, enmarcado: una pantalla dentro de la sala de comando ----

   La descripcion es lo unico del cajon que escribio una persona; lo demas son
   campos y controles. El marco la separa de esa ficha tecnica.

   Tres piezas y ninguna mas: la grilla tenue (el MISMO token que el fondo de
   la app, asi se lee como una pantalla y no como un recuadro pegado), el
   rotulo mono montado sobre el borde —como el grabado de un panel de rack— y
   dos esquineros de visor. Dos, no cuatro: alcanzan para que se lea el gesto
   sin que la caja parezca un blister. Sin animacion ni glow palpitante a
   proposito — esto se mira ocho horas por dia. */
.descripcion-marco {
    position: relative;
    margin: 18px 0 4px;
    padding: 18px 18px 16px;
    background:
        repeating-linear-gradient(var(--grid) 0 1px, transparent 1px 22px),
        repeating-linear-gradient(90deg, var(--grid) 0 1px, transparent 1px 22px),
        var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: var(--shadow), inset 0 1px 0 var(--line);
}

/* Los esquineros: arriba a la derecha y abajo a la izquierda, en diagonal.
   El rotulo se queda con la esquina de arriba a la izquierda. */
.descripcion-marco::before,
.descripcion-marco::after {
    content: ''; position: absolute; width: 22px; height: 22px;
    border: 1.5px solid var(--accent); opacity: .6; pointer-events: none;
}
.descripcion-marco::before { top: -1px; right: -1px; border-left: 0; border-bottom: 0; border-radius: 0 10px 0 0; }
.descripcion-marco::after { bottom: -1px; left: -1px; border-right: 0; border-top: 0; border-radius: 0 0 0 10px; }

/* Montado SOBRE la linea del borde: el fondo del cajon lo recorta, como una
   etiqueta grabada en la chapa. */
.descripcion-rotulo {
    position: absolute; top: -7px; left: 14px; padding: 0 7px;
    background: var(--panel);
    font-family: var(--f-mono); font-size: 9.5px; letter-spacing: .18em;
    text-transform: uppercase; color: var(--ink-3);
}

.descripcion-marco .descripcion-md { margin-top: 0; }
.descripcion-marco > .meta { margin: 0; }


/* Cerrado no existe para el mouse ni para el lector de pantalla: visibility
   hidden, no solo opacidad. Con opacidad sola el panel invisible seguiria
   tapando media pantalla. */
.cajon { position: fixed; inset: 0; z-index: 60; visibility: hidden; }
.cajon.abierto { visibility: visible; }

.cajon-fondo {
    position: absolute; inset: 0; background: rgba(0, 0, 0, .45);
    opacity: 0; transition: opacity .18s ease;
}
.cajon.abierto .cajon-fondo { opacity: 1; }

#cajon-item {
    position: absolute; top: 0; right: 0; height: 100%; display: block;
    width: min(620px, 94vw);
    background: var(--panel); border-left: 1px solid var(--line);
    box-shadow: -18px 0 40px rgba(0, 0, 0, .35);
    transform: translateX(100%); transition: transform .2s ease;
    overflow-y: auto; overscroll-behavior: contain;
}
.cajon.abierto #cajon-item { transform: none; }

.cajon-encabezado {
    position: sticky; top: 0; z-index: 1; display: flex; align-items: center; gap: 10px;
    padding: 14px 18px; background: var(--panel-2); border-bottom: 1px solid var(--line);
}
.cajon-numero { font-family: var(--f-mono); font-size: 13px; color: var(--ink-2); }
.cajon-completo, .cajon-cerrar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 7px;
    color: var(--ink-2); background: none; border: 1px solid transparent;
    text-decoration: none; font-size: 13px; cursor: pointer; margin: 0; padding: 0;
    letter-spacing: 0; text-transform: none;
}
.cajon-completo { margin-left: auto; }
.cajon-completo:hover, .cajon-cerrar:hover { color: var(--accent); border-color: var(--line-strong); filter: none; }

.cajon-cuerpo { padding: 18px; }
.cajon-titulo {
    font-family: var(--f-display); font-weight: 700; font-size: 19px; line-height: 1.35;
    letter-spacing: -.01em; text-transform: none; color: var(--ink);
    margin: 0 0 12px;
}
.cajon-seccion { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line); }
.cajon-subtitulo {
    display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink-3); font-weight: 500;
}
.cajon-seccion select, .cajon-seccion input, .cajon-seccion textarea { max-width: 100%; }
.cajon-seccion > label {
    margin: 14px 0 5px; font-family: var(--f-body); font-size: 11.5px;
    letter-spacing: 0; text-transform: none; color: var(--ink-3);
}
.cajon-seccion > label:first-of-type { margin-top: 2px; }

/* Un solo boton para toda la ficha, pegado abajo del ultimo campo y separado
   por la misma linea que separa las secciones: se lee como el cierre del
   bloque, no como la accion de la seccion que quedo arriba. */
.cajon-guardar { margin-top: 20px; }

/* La MISMA ficha, ahora tambien en el panel lateral de la vista completa
   (`item/_ficha.html.twig`). El panel ya trae su marco y su titulo, asi que la
   primera seccion no necesita otra linea arriba: serian dos rayas pegadas. */
.panel-cuerpo > .cajon-ficha > .cajon-seccion:first-of-type {
    margin-top: 0; padding-top: 0; border-top: 0;
}
.panel-cuerpo > .cajon-ficha select { width: 100%; }

/* El historial en el cajon: mismo lenguaje que la vista completa, mas apretado
   porque compite con menos ancho. */
.cajon-historial > summary { cursor: pointer; list-style: none; user-select: none; }
.cajon-historial > summary::-webkit-details-marker { display: none; }
.cajon-historial > summary:hover { color: var(--ink-2); }
.cajon-historial[open] > summary { margin-bottom: 12px; }

.cajon-historial .linea-de-tiempo { margin: 0; }
.cajon-historial .linea-de-tiempo li { color: var(--ink-3); }
.cajon-historial .linea-de-tiempo strong { color: var(--ink-2); font-weight: 500; }
.cajon-historial .avatar-evento { background: transparent; color: var(--ink-3); border-color: var(--line); }
.cajon-historial .hora { white-space: nowrap; color: var(--ink-3); }
.cajon-comentar { margin-top: 12px; }

@media (max-width: 640px) { #cajon-item { width: 100%; border-left: none; } }

/* ============ TABLAS ============ */

table { border-collapse: collapse; width: 100%; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
th, td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line); font-size: 13px; }
th { font-family: var(--f-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); background: var(--panel-2); }
tr:last-child td { border-bottom: none; }
tr.vencido td { background: var(--bad-soft); }
td.num { font-family: var(--f-mono); font-size: 12px; }
td form { display: inline-flex; gap: 6px; align-items: center; }
td form button { margin-top: 0; }
td select { max-width: 220px; }

/* ============ FICHAS DE PROYECTO ============ */

.grilla-proyectos { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }

.ficha {
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    padding: 18px 20px; box-shadow: var(--shadow);
    display: flex; flex-direction: column; gap: 10px;
}
.ficha:hover { border-color: var(--accent); }
.ficha.archivado { opacity: .6; }

.ficha-encabezado { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }

.ficha-nombre {
    font-family: var(--f-display); font-weight: 700; font-size: 16px;
    color: var(--ink); text-decoration: none;
}
.ficha-nombre:hover { color: var(--accent); }

.ficha-clave {
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .1em;
    color: var(--ink-3); background: var(--panel-3); border-radius: 5px; padding: 2px 7px;
}

.ficha-descripcion { font-size: 13px; line-height: 1.6; color: var(--ink-2); margin: 0; }

.ficha-pie {
    display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
    font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3);
    padding-top: 10px; border-top: 1px solid var(--line);
}
.ficha-pie i { margin-right: 5px; }
/* Que reporte por CI cambia el significado de la píldora: se ve. */
.ficha-ci { color: var(--ok); }

/* ============ PUBLICACIONES ============ */

/* Se lee como un diario: el feed tiene ancho de lectura, no de tablero. */
.feed { max-width: 760px; margin-top: 28px; }

.feed-dia {
    display: flex; align-items: baseline; gap: 10px;
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
    color: var(--accent); margin: 34px 0 14px; padding-bottom: 8px;
    border-bottom: 1px solid var(--line);
}
.feed-dia:first-child { margin-top: 0; }
.feed-dia-fecha { color: var(--ink-3); letter-spacing: .12em; }

.publicacion {
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    padding: 22px 26px; margin-bottom: 14px; box-shadow: var(--shadow);
    display: grid; grid-template-columns: 116px 1fr; gap: 20px; align-items: start;
}

/* La foto de la nota: la real si alguien la consiguió, la generada si no. */
.publicacion-columna-portada { min-width: 0; }

.publicacion-portada {
    display: block; border-radius: 8px; overflow: hidden;
    aspect-ratio: 16 / 9; background: var(--line);
}
.publicacion-portada .portada,
.publicacion-portada img { display: block; width: 100%; height: 100%; }
/* `cover` y no `contain`: la foto llena el recuadro sin barras a los costados. */
.publicacion-portada img { object-fit: cover; }

/* Pexels exige acreditar al fotógrafo. Va acá y no en la firma porque es un
   dato de la imagen, no de la noticia: en la firma le competía a quién hizo
   el trabajo, que es lo que el lector tiene que ver. */
.publicacion-credito {
    margin: 6px 0 0; font-size: 10px; line-height: 1.4;
    color: var(--ink-3); letter-spacing: .01em;
}
.publicacion-credito a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--line); }
.publicacion-credito a:hover { color: var(--ink-2); }
.publicacion-portada:hover .portada { transform: scale(1.04); }
.publicacion-portada .portada { transition: transform .25s ease; }

/* Con la portada al lado, el resto de la nota se apila en su propia columna. */
.publicacion-cuerpo { min-width: 0; }

/* Abajo de cierto ancho la miniatura al costado no entra: pasa a ser banner. */
@media (max-width: 620px) {
    .publicacion { grid-template-columns: 1fr; gap: 16px; }
    .publicacion-portada { aspect-ratio: 21 / 9; }
}

/* El que prefiere no ver animaciones tampoco tiene por qué ver este zoom. */
@media (prefers-reduced-motion: reduce) {
    .publicacion-portada .portada, .publicacion-portada:hover .portada { transition: none; transform: none; }
}

.publicacion-volanta, .nota-volanta {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px;
}
.publicacion-estado { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* La sección del diario: de qué proyecto es esta noticia. */
.seccion {
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
    color: var(--ink-3);
}

.publicacion-hora {
    font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3);
}

.publicacion-titulo {
    font-family: var(--f-display); font-weight: 700; font-size: 21px;
    line-height: 1.25; letter-spacing: -.015em; margin: 0 0 10px;
    /* Es un h2, y los h2 de la app son etiquetas en versalitas. Un titular no. */
    text-transform: none; color: var(--ink);
}
.publicacion-titulo a { color: var(--ink); text-decoration: none; }
.publicacion-titulo a:hover { color: var(--accent); }

.publicacion-bajada {
    font-size: 15px; line-height: 1.65; color: var(--ink-2); margin: 0 0 14px;
}

.publicacion-firma, .nota-firma {
    display: flex; flex-wrap: wrap; gap: 16px; align-items: center;
    font-size: 12.5px; color: var(--ink-2);
    padding-top: 12px; border-top: 1px solid var(--line);
}
.publicacion-firma i, .nota-firma i { color: var(--ink-3); margin-right: 5px; }
.publicacion-firma strong, .nota-firma strong { color: var(--ink); font-weight: 600; }

/* ============ LA NOTA (detalle) ============ */

.nota {
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    padding: 30px 36px 26px; box-shadow: var(--shadow);
}
@media (max-width: 700px) { .nota { padding: 22px 20px; } }

.nota-titulo {
    font-family: var(--f-display); font-weight: 700; font-size: 30px;
    line-height: 1.15; letter-spacing: -.02em; margin: 0 0 12px; color: var(--ink);
}

.nota-fecha {
    font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-3);
    margin: 0 0 20px;
}

/* La bajada: el párrafo que resume la nota, más grande que el cuerpo. */
.nota-bajada {
    font-size: 17px; line-height: 1.6; color: var(--ink);
    margin: 0 0 20px; max-width: 62ch;
}

.nota-cuerpo { margin-top: 22px; max-width: 68ch; }
.nota-cuerpo > p { font-size: 14.5px; line-height: 1.7; color: var(--ink-2); }

/* El cuerpo de la nota, en Markdown: se lee como texto corrido, no como ficha. */
.nota-texto { font-size: 15px; line-height: 1.75; color: var(--ink-2); }
.nota-texto p { margin: 0 0 1.1em; }
.nota-texto strong { color: var(--ink); font-weight: 600; }
.nota-texto h2 {
    font-family: var(--f-display); font-size: 18px; letter-spacing: -.01em;
    text-transform: none; color: var(--ink); margin: 1.8em 0 .6em;
}
.nota-texto h3 { font-family: var(--f-display); font-size: 15px; margin: 1.5em 0 .5em; color: var(--ink); }
.nota-texto ul, .nota-texto ol { margin: 0 0 1.1em; padding-left: 1.3em; }
.nota-texto li { margin-bottom: .4em; }
.nota-texto code {
    font-family: var(--f-mono); font-size: 13px;
    background: var(--panel-3); border-radius: 4px; padding: 2px 6px;
}
.nota-texto pre {
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 14px; overflow-x: auto;
}
.nota-texto pre code { background: none; padding: 0; }
.nota-texto blockquote {
    border-left: 3px solid var(--accent); margin: 1.2em 0; padding-left: 16px; color: var(--ink-3);
}
.nota-texto a { color: var(--accent); }

.pill-tipo-avance { color: var(--accent); background: var(--accent-soft); border-color: var(--accent); }
.pill-tipo-fix { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }
.pill-tipo-documentacion { color: var(--ok); background: var(--ok-soft); border-color: var(--ok); }
.pill-tipo-informe { color: var(--sensitive); background: var(--sensitive-soft); border-color: var(--sensitive); }

/* La píldora de despliegue: mergeado apaga el LED, desplegado lo prende. */
.pill-despliegue-mergeado { color: var(--ink-2); background: var(--panel-3); border-color: var(--line-strong); }
.pill-despliegue-mergeado .led { background: var(--ink-3); box-shadow: none; animation: none; }
.pill-despliegue-en_desarrollo { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }
.pill-despliegue-en_desarrollo .led { background: var(--warn); box-shadow: 0 0 8px var(--warn); }
.pill-despliegue-en_produccion { color: var(--ok); background: var(--ok-soft); border-color: var(--ok); }
.pill-despliegue-en_produccion .led { background: var(--ok); box-shadow: 0 0 8px var(--ok); }

/* Quién afirmó el despliegue. No es adorno: CI es un hecho, una persona es una afirmación. */
.segun { font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3); }

.detalle-tecnico { margin: 16px 0; }
.detalle-tecnico summary {
    cursor: pointer; font-family: var(--f-mono); font-size: 11px;
    letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2);
    padding: 9px 0; user-select: none;
}
.detalle-tecnico summary:hover { color: var(--accent); }
.detalle-tecnico[open] summary { color: var(--accent); }

.referencias { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.referencia {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: var(--f-mono); font-size: 11px;
    color: var(--ink-2); background: var(--panel-2);
    border: 1px solid var(--line-strong); border-radius: 7px;
    padding: 6px 11px; text-decoration: none;
}
.referencia:hover { border-color: var(--accent); color: var(--accent); }

/* ============ NOVEDADES ============ */

.novedades { display: grid; grid-template-columns: minmax(280px, 1fr) 2fr; gap: 20px; align-items: start; }
@media (max-width: 1000px) { .novedades { grid-template-columns: 1fr; } }

.persona {
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    padding: 14px 16px; margin-bottom: 12px; box-shadow: var(--shadow);
}
.persona h3 { display: flex; align-items: center; gap: 9px; font-size: 14px; margin: 0 0 8px; }
.persona ul { margin: 0; padding-left: 16px; font-size: 12.5px; color: var(--ink-2); }
.persona li { margin-bottom: 4px; }
.persona:last-child { margin-bottom: 0; }

.dia {
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
    color: var(--accent); margin: 22px 0 10px; padding-bottom: 6px;
    border-bottom: 1px solid var(--line);
}
.panel-cuerpo > .dia:first-child { margin-top: 0; }

/* ============ DOCUMENTACIÓN ============ */

.documento {
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    padding: 22px 26px; box-shadow: var(--shadow); line-height: 1.7; font-size: 14.5px;
}
.documento h1 { font-size: 24px; margin-top: 0; }
.documento h2 { font-family: var(--f-display); font-size: 18px; letter-spacing: 0; text-transform: none; color: var(--ink); margin-top: 28px; }
.documento h3 { font-size: 15px; margin-top: 22px; }
.documento code { font-family: var(--f-mono); font-size: 12.5px; background: var(--panel-3); border-radius: 4px; padding: 2px 6px; }
.documento pre { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 14px; overflow-x: auto; }
.documento pre code { background: none; padding: 0; }
.documento table { margin: 16px 0; }
.documento blockquote { border-left: 3px solid var(--accent); margin: 16px 0; padding-left: 16px; color: var(--ink-2); }

/* ============ CONECTORES ============ */

.grilla-conectores { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 20px; align-items: start; }
.conector .panel-titulo { font-family: var(--f-display); font-size: 15px; letter-spacing: 0; text-transform: none; color: var(--ink); }
.conector .cuenta { text-transform: uppercase; letter-spacing: .1em; font-size: 10px; }
.led.apagado { background: var(--ink-3); box-shadow: none; animation: none; }

/* ============ INGRESO ============ */

.ingreso {
    max-width: 400px; margin: 8vh auto 0;
    background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
    padding: 32px; box-shadow: var(--shadow);
}
.ingreso h1 { text-align: center; margin-bottom: 6px; }
.ingreso .sobretitulo { display: block; text-align: center; margin-bottom: 22px; }
.ingreso button { width: 100%; justify-content: center; margin-top: 20px; }

/* Con SSO configurado el formulario de contrasena no se muestra, asi que este
   boton nunca convive con otro: es LA accion de la pantalla y se ve como tal.
   Calca el boton principal (button) porque es un <a> y no hereda sus reglas. */
.ingreso .boton-sso {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; margin-top: 20px; padding: 11px 16px;
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--accent-ink); background: var(--accent); border: 1px solid var(--accent);
    border-radius: 8px; text-decoration: none; cursor: pointer;
    transition: filter .15s;
}
.ingreso .boton-sso:hover { filter: brightness(1.12); }

/* ============ ADJUNTOS ============ */

.adjuntos { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; }
.adjunto {
    margin: 0; max-width: 220px; border: 1px solid var(--linea);
    border-radius: 8px; overflow: hidden; background: var(--panel-2);
}
.adjunto img { display: block; width: 100%; height: 140px; object-fit: cover; }
.adjunto figcaption {
    padding: 6px 8px; font-size: 11px; color: var(--ink-2);
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
/* La anotada se distingue de un vistazo de la original de la que salio. */
.adjunto-anotado { border-color: var(--acento); }

/* Es un <dialog>: ventana modal centrada, no un panel incrustado. */
/* ============ DIALOGOS DE LA PLATAFORMA ============ */
/* Reemplazan a alert/confirm/prompt del navegador, que aparecen con la
   tipografia del sistema operativo y encabezados tipo "localhost:8087 dice". */
dialog.dialogo {
    margin: auto; padding: 0; width: min(420px, 92vw);
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: 10px; box-shadow: var(--shadow);
}
dialog.dialogo::backdrop { background: rgba(2, 5, 10, .72); }
dialog.dialogo form { padding: 18px 20px 16px; margin: 0; }

.dialogo-titulo {
    font-family: var(--f-display); font-size: 14px; margin: 0 0 6px; color: var(--ink);
}
.dialogo-mensaje { margin: 0; font-size: 13.5px; color: var(--ink-2); line-height: 1.5; }
.dialogo-campo {
    width: 100%; margin-top: 12px; padding: 8px 10px; font-size: 13.5px;
    background: var(--panel-3); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: 6px;
}
.dialogo-campo:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* La accion principal a la derecha, que es donde la busca la mano. */
.dialogo-acciones { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.dialogo-acciones button {
    cursor: pointer; padding: 7px 15px; font-size: 12.5px; border-radius: 6px;
    border: 1px solid var(--line-strong); background: var(--panel-3); color: var(--ink-2);
}
.dialogo-secundario:hover { color: var(--ink); border-color: var(--ink-3); filter: none; }
.dialogo-primario {
    background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 700;
}
/* Lo que no se deshace no se pinta del color de "seguir adelante". */
.dialogo-peligro { background: var(--bad); border-color: var(--bad); color: #fff; }

dialog.anotador {
    position: relative; margin: auto; padding: 14px;
    width: min(940px, 92vw); max-height: 90vh; overflow: auto;
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: 10px; box-shadow: var(--shadow);
}
dialog.anotador::backdrop { background: rgba(2, 5, 10, .72); }
.anotador-barra { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
/* El canvas se achica para entrar en pantalla, pero adentro sigue teniendo el
   tamaño real de la imagen: lo guardado no pierde resolucion. */
.anotador canvas { max-width: 100%; height: auto; cursor: crosshair; background: var(--panel-3); }

/* La cruz de cerrar, arriba a la derecha. Es el gesto que la gente busca
   primero en un modal; el boton "Cerrar" de la barra hace lo mismo y se
   queda para el que lee la barra. */
.anotador-cerrar {
    position: absolute; top: 8px; right: 10px; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; padding: 0; margin: 0; cursor: pointer;
    background: transparent; color: var(--ink-3);
    border: 1px solid transparent; border-radius: 6px; font-size: 14px;
}
.anotador-cerrar:hover { color: var(--bad); border-color: var(--bad-soft); background: var(--bad-soft); filter: none; }
.anotador-cerrar:focus-visible { box-shadow: 0 0 0 3px var(--accent-soft); }

/* La barra no puede quedar debajo de la cruz. */
.anotador-barra { padding-right: 34px; }

/* Las herramientas, como grupo pegado: se leen como un selector unico y no
   como cuatro botones sueltos entre Deshacer y Limpiar. */
.anotador-herramientas { display: inline-flex; }
.anotador-herramienta {
    display: flex; align-items: center; justify-content: center;
    width: 30px; height: 28px; padding: 0; margin: 0; cursor: pointer; font-size: 12px;
    background: var(--panel-3); color: var(--ink-2);
    border: 1px solid var(--line-strong); border-radius: 0;
}
.anotador-herramienta:first-child { border-radius: 6px 0 0 6px; }
.anotador-herramienta:last-child { border-radius: 0 6px 6px 0; }
.anotador-herramienta + .anotador-herramienta { border-left: none; }
.anotador-herramienta:hover { color: var(--accent); filter: none; }

/* La activa se pinta llena, no con un borde: entre cuatro botones pegados un
   borde de acento se confunde con el hover del de al lado. */
.anotador-herramienta.activa {
    background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
}
.anotador-herramienta:focus-visible { box-shadow: 0 0 0 3px var(--accent-soft); z-index: 1; }
.boton-chico { font-size: 11px; padding: 2px 8px; }

/* Un <form> que tiene que convivir en una linea de botones sin romper el flujo.
   Borrar exige POST + token, y eso obliga a un form: sin esto mete un salto de
   linea en el medio del figcaption. */
.form-en-linea { display: inline; margin: 0; }

/* Lo que no se deshace se pinta distinto. `--bad` ya tiene variante clara y
   oscura, asi que el boton acompana el tema solo. */
.boton-riesgo { color: var(--bad); border-color: var(--bad-soft); }
.boton-riesgo:hover { background: var(--bad-soft); border-color: var(--bad); color: var(--bad); filter: none; }

/* El boton de enviar en su propia linea: pegado al ultimo campo parece parte
   de el, y con un <select> al lado se lee como si fuera su accion. */
.acciones { margin-top: 18px; display: flex; gap: 10px; align-items: center; }

/* ============ ALTA DE ITEM (layout "historia y ficha") ============ */

.alta-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 20px; align-items: start; }
@media (max-width: 920px) { .alta-grid { grid-template-columns: 1fr; } }
.alta-grid .panel { margin-bottom: 0; }
label.primera { margin-top: 0; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { position: relative; display: inline-flex; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip span {
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
    border-radius: 7px; padding: 8px 13px; cursor: pointer;
    border: 1px solid var(--line-strong); background: var(--panel-3); color: var(--ink-2);
}
.chip input:checked + span { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 700; }
.chip input:focus-visible + span { box-shadow: 0 0 0 3px var(--accent-soft); }

.segmentos { display: flex; }
.seg { flex: 1; position: relative; display: flex; }
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg span {
    flex: 1; text-align: center; font-family: var(--f-mono); font-size: 10px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase; padding: 9px 0; cursor: pointer;
    border: 1px solid var(--line-strong); background: var(--panel-2); color: var(--ink-2);
}
.seg:first-child span { border-radius: 8px 0 0 8px; }
.seg:last-child span { border-radius: 0 8px 8px 0; }
.seg + .seg span { margin-left: -1px; }
.seg input:checked + span { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); position: relative; z-index: 1; }
.seg input:focus-visible + span { box-shadow: 0 0 0 3px var(--accent-soft); z-index: 2; }
.seg-baja input:checked + span { background: var(--panel-3); color: var(--ink); border-color: var(--line-strong); }
.seg-alta input:checked + span { background: var(--warn); border-color: var(--warn); }
.seg-critica input:checked + span { background: var(--bad); border-color: var(--bad); }

.barra-formato { display: flex; gap: 4px; align-items: center; margin-top: 18px; }
.barra-formato .rotulo {
    font-family: var(--f-mono); font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
    color: var(--ink-3); margin-right: 6px;
}
.barra-formato .pista { font-family: var(--f-mono); font-size: 9px; color: var(--ink-3); margin-left: 6px; }
button.fmt {
    display: flex; align-items: center; justify-content: center;
    width: 27px; height: 25px; padding: 0; margin-top: 0; cursor: pointer; font-size: 11px;
    background: var(--panel-3); color: var(--ink-2); border: 1px solid var(--line-strong); border-radius: 5px;
}
button.fmt:hover { border-color: var(--accent); color: var(--accent); filter: none; }
button.fmt i { font-size: 10px; }

/* Paleta de emojis de la barra de formato. El disparador es un <summary>, asi
   que no lo alcanza `button.fmt` (selector de elemento): hay que repetirle el
   aspecto o queda como un triangulito suelto en el medio de la barra. */
.barra-formato details.emojis { position: relative; display: inline-flex; }
.barra-formato details.emojis > summary {
    display: flex; align-items: center; justify-content: center;
    width: 27px; height: 25px; cursor: pointer; font-size: 11px;
    background: var(--panel-3); color: var(--ink-2);
    border: 1px solid var(--line-strong); border-radius: 5px;
    list-style: none; user-select: none;
}
.barra-formato details.emojis > summary::-webkit-details-marker { display: none; }
.barra-formato details.emojis > summary:hover { border-color: var(--accent); color: var(--accent); }
.barra-formato details.emojis[open] > summary { border-color: var(--accent); color: var(--accent); }

.emoji-panel {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
    display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; padding: 7px;
    background: var(--panel-2); border: 1px solid var(--line-strong); border-radius: 8px;
    box-shadow: 0 10px 26px rgba(0, 0, 0, .35);
}
.emoji-panel button {
    all: unset; cursor: pointer; text-align: center;
    width: 26px; height: 26px; line-height: 26px; border-radius: 5px; font-size: 15px;
}
.emoji-panel button:hover { background: var(--accent-soft); }
.emoji-panel button:focus-visible { box-shadow: 0 0 0 3px var(--accent-soft); }

.acciones button.crear {
    width: 100%; justify-content: center;
    background: var(--accent); color: var(--accent-ink); border-color: var(--accent); font-weight: 700;
}

/* ============ DESCRIPCION RENDERIZADA (markdown) ============ */

.descripcion-md { font-size: 13.5px; line-height: 1.65; color: var(--ink); margin-top: 14px; }
.descripcion-md h1, .descripcion-md h2, .descripcion-md h3 {
    font-family: var(--f-mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
    color: var(--accent); margin: 16px 0 6px; font-weight: 700;
}
.descripcion-md > :first-child { margin-top: 0; }
.descripcion-md p { margin: 0 0 8px; }
.descripcion-md ul, .descripcion-md ol { margin: 0 0 8px; padding-left: 20px; }
.descripcion-md li { margin-bottom: 4px; }
.descripcion-md ul.contains-task-list { list-style: none; padding-left: 4px; }
.descripcion-md input[type="checkbox"] { margin-right: 8px; accent-color: var(--ok); }
.descripcion-md code {
    font-family: var(--f-mono); font-size: .87em;
    background: var(--panel-2); padding: 1px 6px; border-radius: 4px;
}
.descripcion-md blockquote { margin: 0 0 8px; padding-left: 12px; border-left: 3px solid var(--line-strong); color: var(--ink-2); }

/* ============ HISTORIAL PLEGABLE (quien hizo que, y cuando) ============ */

details.historial-plegable summary { cursor: pointer; list-style: none; user-select: none; }
details.historial-plegable summary::-webkit-details-marker { display: none; }
.plegable-flecha { transition: transform .15s; font-size: 10px; }
details[open] .plegable-flecha { transform: rotate(90deg); }
.historial-plegable .contador {
    font-family: var(--f-mono); font-size: 10px; letter-spacing: 0;
    color: var(--accent); background: var(--accent-soft); border-radius: 999px; padding: 1px 8px;
}
.historial-plegable .pista {
    margin-left: auto; font-family: var(--f-mono); font-size: 9px;
    letter-spacing: .05em; text-transform: none; color: var(--ink-3);
}
.linea-de-tiempo { position: relative; }
.linea-de-tiempo::before {
    content: ""; position: absolute; left: 12px; top: 8px; bottom: 8px;
    width: 1px; background: var(--line);
}
.linea-de-tiempo li { flex-wrap: nowrap; align-items: flex-start; }
.avatar-evento {
    width: 25px; height: 25px; border-radius: 999px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--f-mono); font-size: 10px; font-weight: 700;
    border: 1px solid var(--line-strong); background: var(--panel-3); color: var(--ink-2);
    position: relative; z-index: 1;
}
.linea-de-tiempo .que { padding-top: 3px; min-width: 0; }
.linea-de-tiempo .hora { margin-left: auto; padding-top: 5px; }
.descripcion-md img { max-width: 100%; border: 1px solid var(--line); border-radius: 8px; display: block; margin: 6px 0; }

/* Miniaturas por seccion: una tira horizontal a continuacion del campo al
   que pertenecen, completando el ancho y envolviendo si son muchas. */
.miniaturas { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 20px; }
.miniaturas:empty { display: none; }
.miniaturas figure.miniatura { margin: 0; width: 104px; }
.miniaturas figure.miniatura img { width: 104px; height: 68px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line-strong); display: block; }
.miniaturas figure.miniatura figcaption { display: flex; gap: 3px; margin-top: 3px; }
.miniaturas figure.miniatura .boton-chico { padding: 2px 7px; font-size: 9px; }

/* En el alta los campos llenan su columna: el tope global de 560px dejaba a
   las miniaturas flotando lejos, pegadas al borde del panel. */
.alta-grid input[type="text"], .alta-grid select, .alta-grid textarea { max-width: none; }

/* Chip de captura en la descripcion: la imagen no aplasta el texto, se abre
   en el visor al tocarla. */
.chip-captura {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .04em;
    color: var(--accent); background: var(--accent-soft);
    border: 1px solid var(--accent); border-radius: 6px;
    padding: 3px 10px; margin: 2px 0; cursor: pointer;
}
.chip-captura:hover { filter: brightness(1.2); }
/* `cursor: zoom-out` sobre el marco y no sobre la imagen: afuera se cierra,
   encima de la captura no. El cursor tiene que decir la misma verdad que hace
   el click. */
dialog.visor {
    margin: auto; padding: 10px;
    background: var(--panel); border: 1px solid var(--line-strong);
    border-radius: 10px; box-shadow: var(--shadow); cursor: zoom-out;
    overflow: visible;
}
dialog.visor::backdrop { background: rgba(2, 5, 10, .8); }
dialog.visor img { display: block; max-width: 90vw; max-height: 85vh; border-radius: 6px; cursor: default; }
/* La cruz va montada sobre la esquina: adentro del marco se comería 30px de
   captura, y la captura es lo único que se vino a ver. */
.visor-cerrar {
    position: absolute; top: -14px; right: -14px;
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 50%;
    margin: 0; padding: 0; font-size: 13px; letter-spacing: 0; text-transform: none;
    color: var(--ink-2); background: var(--panel-2);
    border: 1px solid var(--line-strong); cursor: pointer;
}
.visor-cerrar:hover { color: var(--accent); border-color: var(--accent); filter: none; }

/* ============ RESULTADO DEL SPRINT GOAL ============ */
.pill-cumplido { color: var(--ok); background: var(--ok-soft); border-color: var(--ok); }
.pill-parcial { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }
.pill-no_cumplido { color: var(--bad); background: var(--bad-soft); border-color: var(--bad); }
.seg-cumplido input:checked + span { background: var(--ok); border-color: var(--ok); color: var(--accent-ink); }
.seg-parcial input:checked + span { background: var(--warn); border-color: var(--warn); color: var(--accent-ink); }
.seg-no_cumplido input:checked + span { background: var(--bad); border-color: var(--bad); color: var(--accent-ink); }

/* ============ LA BOLSA SEMANAL ============ */
.semana .panel-titulo .pill { margin-left: 0; }
.semana .pista-semana { margin-left: auto; font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .04em; text-transform: none; color: var(--ink-3); }
.semana .objetivo-semana { margin: 0; font-size: 14.5px; }

/* Cada objetivo, plegado: el estado y el contador SIEMPRE a la vista; los
   tickets, al abrir. Es <details> y no un controller de Stimulus por la misma
   razon que el editor del cajon — asi plegar no depende de que el JS conecte. */
.objetivo-caja { border-top: 1px solid var(--line); }
.objetivo-caja:first-of-type { border-top: 0; }
.objetivo-caja > summary {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 0; cursor: pointer; list-style: none;
}
/* El triangulo nativo se reemplaza por un chevron propio: el de Safari no
   hereda color y sobre el panel oscuro queda invisible. */
.objetivo-caja > summary::-webkit-details-marker { display: none; }
.objetivo-caja > summary::after {
    content: "\f078"; font-family: "Font Awesome 6 Free"; font-weight: 900;
    font-size: 9px; color: var(--ink-3); transition: transform .15s ease;
}
.objetivo-caja[open] > summary::after { transform: rotate(180deg); }
.objetivo-caja > summary:hover .objetivo-texto { color: var(--accent); }

/* El texto se lleva el espacio sobrante y el contador queda pegado a la
   derecha: asi los contadores de todos los objetivos quedan en columna y se
   comparan de un vistazo, que es lo que se hace el miercoles. */
.objetivo-texto { flex: 1; min-width: 0; }
.objetivo-cuenta { font-family: var(--f-mono); font-size: 12px; color: var(--ink-3); flex-shrink: 0; }
.objetivo-caja .historial,
.objetivo-vacio { margin: 2px 0 10px; padding-left: 22px; }

/* Como viene el objetivo, deducido de sus tickets. "Sin planificar" va en
   ambar y no en rojo: el lunes a la manana es normal, el jueves no — el color
   pide atencion sin declarar un fracaso que nadie decidio todavia. */
.pill-avance-listo { color: var(--ok); background: var(--ok-soft); border-color: var(--ok); }
.pill-avance-en_curso { color: var(--accent); background: var(--accent-soft); border-color: var(--accent); }
.pill-avance-sin_arrancar { color: var(--ink-3); }
.pill-avance-sin_planificar { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }

/* Objetivos del sprint: el titulo de cada promesa y sus tickets colgando. */
.objetivo-titulo { margin: 18px 0 6px; font-size: 14px; color: var(--ink); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.objetivo-titulo:first-child { margin-top: 0; }
.objetivo-titulo i { color: var(--accent); font-size: 11px; }
.objetivo-titulo.sueltos i { color: var(--ink-3); }
.comentario-objetivo { margin-left: 22px; }

/* ============ FECHAS Y BANNER DE SIMULACION ============ */

/* Los controles nativos (calendario del date, scrollbars) siguen el tema. */
:root { color-scheme: dark; }
html[data-theme="light"] { color-scheme: light; }

/* El input de fecha no estaba en la lista global y quedaba con el estilo
   blanco del navegador, ajeno al tema. */
input[type="date"], input[type="datetime-local"], input[type="time"] {
    width: 100%; max-width: 560px;
    background: var(--panel-2); border: 1px solid var(--line-strong); border-radius: 8px;
    color: var(--ink); font-family: var(--f-mono); font-size: 12.5px; padding: 9px 12px;
    outline: none; transition: border-color .15s, box-shadow .15s;
}
input[type="date"]:focus, input[type="datetime-local"]:focus, input[type="time"]:focus {
    border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
input[type="date"]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .6; }
.alta-grid input[type="date"] { max-width: none; }

.banner-simulacion {
    display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap;
    margin: 0; padding: .5rem 1rem; border-radius: 0;
}
.banner-simulacion form { display: inline-flex; }
.banner-simulacion .boton-chico { margin-top: 0; }

/* Gestion de objetivos: bloques arrastrables, alta en linea. */
.objetivo-bloque {
    background: var(--panel-2); border: 1px solid var(--line);
    border-radius: 8px; padding: 12px 14px; margin-bottom: 10px;
}
.objetivo-bloque.sortable-ghost { opacity: .35; background: var(--accent-soft); border-color: var(--accent); }
.objetivo-bloque .objetivo-titulo { margin: 0; }
.objetivo-bloque > .meta { margin: 6px 0 0 24px; font-size: 10.5px; }
.objetivo-bloque .historial { margin-top: 10px; padding-left: 24px; }
.agarre { cursor: grab; color: var(--ink-3); font-size: 11px; }
.agarre:active { cursor: grabbing; }
.quitar-objetivo { display: inline-flex; margin-left: auto; }
.quitar-objetivo .boton-chico { margin-top: 0; }
.agregar-objetivo { display: flex; gap: 8px; margin-top: 18px; align-items: stretch; }
.agregar-objetivo input[type="text"] { flex: 1; max-width: none; }
.agregar-objetivo button { margin-top: 0; flex-shrink: 0; }

/* Tachito de quitar: discreto hasta que lo mires con intencion. */
button.btn-tacho {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 26px; padding: 0; margin-top: 0; cursor: pointer;
    background: transparent; border: 1px solid transparent; border-radius: 6px;
    color: var(--ink-3); font-size: 12px;
}
button.btn-tacho:hover { color: var(--bad); background: var(--bad-soft); border-color: var(--bad); filter: none; }

/* ============ CARDS DE SPRINTS + MODAL GENERICO ============ */
.sprint-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.sprint-card {
    display: block; text-decoration: none; color: var(--ink);
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    box-shadow: var(--shadow); padding: 16px 18px;
    transition: border-color .15s, transform .1s;
}
.sprint-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.sprint-card-encabezado { display: flex; align-items: center; gap: 8px; justify-content: space-between; }
.sprint-card-nombre { font-family: var(--f-display); font-weight: 600; font-size: 15px; }
.sprint-card-nombre i { color: var(--accent); font-size: 12px; margin-right: 4px; }
.sprint-card-fechas { font-family: var(--f-mono); font-size: 11px; color: var(--ink-3); margin: 6px 0 10px; }
.sprint-card-objetivos { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; font-size: 12.5px; color: var(--ink-2); }
.sprint-card-objetivos i { color: var(--accent); font-size: 9px; margin-right: 4px; }
.sprint-card-objetivos .pill { margin-left: 4px; }
.sprint-card-objetivos .sin-objetivos { color: var(--ink-3); font-family: var(--f-mono); font-size: 11px; }
.board-encabezado button { margin-top: 0; }

dialog.dialogo {
    margin: auto; padding: 20px 26px 24px;
    width: min(780px, 94vw); max-height: 90vh; overflow: auto;
    background: var(--panel); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: 10px; box-shadow: var(--shadow);
}
dialog.dialogo::backdrop { background: rgba(2, 5, 10, .72); }
.dialogo-encabezado { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.dialogo-encabezado .panel-titulo { padding: 0; border: none; }
.dialogo input[type="date"], .dialogo textarea, .dialogo select, .dialogo input[type="text"] { max-width: none; }

.fechas-sprint { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fechas-sprint input[type="date"] { width: auto; padding: 5px 8px; font-size: 11.5px; }
.fechas-sprint .boton-chico { margin-top: 0; }

/* Constructor de objetivos en el alta de sprint. */
.objetivos-nuevos { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.objetivos-nuevos:empty { margin: 0; }
.objetivo-fila {
    display: flex; align-items: center; gap: 10px;
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 10px; font-size: 13px;
}
.objetivo-fila-texto { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.objetivo-fila.sortable-ghost { opacity: .35; border-color: var(--accent); }
.agregar-objetivo button { flex-shrink: 0; }

/* Entrada del constructor: objetivo arriba, descripcion + boton abajo. */
.constructor-entrada { display: flex; flex-direction: column; gap: 6px; }
.constructor-entrada input[type="text"] { max-width: none; }
.constructor-entrada-fila { display: flex; gap: 8px; }
.constructor-entrada-fila input[type="text"] { flex: 1; max-width: none; }
.constructor-entrada-fila button { margin-top: 0; flex-shrink: 0; }
.agregar-objetivo.con-descripcion { flex-direction: column; align-items: stretch; gap: 6px; }
.objetivo-fila-texto small { display: block; color: var(--ink-3); font-size: 11px; margin-top: 2px; }
.objetivo-descripcion { margin: 2px 0 0 24px; }

/* El detalle del sprint arriba: las fechas comparten fila. */
.fechas-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.fechas-grid label { margin-top: 16px; }
.fechas-grid label.primera { margin-top: 0; }

/* El Crear sprint del modal: separado del formulario y en AMBAR — crear es
   un acto distinto de cargar campos. Ambar y no verde: contra el cian de los
   demas botones, el par teal/cian es indistinguible para daltonismo
   rojo-verde; el eje azul/amarillo se conserva. */
dialog.dialogo button[type="submit"] {
    margin-top: 26px;
    background: var(--warn); border-color: var(--warn); color: var(--accent-ink);
}

/* ============ LA SEMANA: fila por proyecto (diseño aprobado) ============ */
/* Cada proyecto es un desplegable, abierto por defecto. La cabecera (nombre,
   sprint, estado y contador) queda SIEMPRE a la vista: lo que se pliega son
   sus objetivos, que es lo que ocupa lugar cuando se miran doce proyectos. */
.fila-proyecto {
    background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
    box-shadow: var(--shadow); padding: 14px 20px; margin-bottom: 10px;
}
.fila-cabecera {
    display: flex; align-items: center; gap: 18px;
    cursor: pointer; list-style: none;
}
.fila-cabecera::-webkit-details-marker { display: none; }
.fila-cabecera::after {
    content: "\f078"; font-family: "Font Awesome 6 Free"; font-weight: 900;
    font-size: 10px; color: var(--ink-3); transition: transform .15s ease;
}
.fila-proyecto[open] > .fila-cabecera::after { transform: rotate(180deg); }
.fila-identidad { flex: 1; min-width: 0; }
.fila-cabecera .pill { flex-shrink: 0; }
/* El cuerpo se separa de la cabecera solo cuando esta abierto: con el margen
   fijo, un proyecto plegado arrastraba un hueco debajo del nombre. */
.fila-proyecto[open] > .fila-cuerpo { margin-top: 12px; }

/* El enlace que ofrece crear el ticket que le falta al objetivo. */
.crear-el-ticket { white-space: nowrap; }
.crear-el-ticket i { font-size: 9px; }

@media (max-width: 860px) {
    .fila-cabecera { flex-wrap: wrap; gap: 10px; }
    .fila-identidad { flex-basis: 100%; }
}
.fila-nombre { font-family: var(--f-display); font-weight: 600; font-size: 15px; display: flex; align-items: center; gap: 7px; }
.fila-nombre i { color: var(--accent); font-size: 11px; }
.fila-nombre a { color: var(--ink); }
.fila-nombre a:hover { color: var(--accent); }
.fila-sprint { font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-3); margin-top: 4px; }
.fila-descripcion { margin: 0 0 6px; }
.fila-contador { text-align: right; flex-shrink: 0; }
.fila-contador .numero { font-family: var(--f-display); font-weight: 700; font-size: 21px; }
.semana .objetivo-semana { margin: 4px 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.semana .objetivo-semana i { color: var(--accent); font-size: 9px; }

/* ============ KANBAN: backlog y columnas de desarrollo ============ */
.col-backlog { border-style: dashed; }
.col-backlog .led { background: var(--ink-3); box-shadow: none; }
.col-revision .led { background: var(--sensitive); box-shadow: 0 0 8px var(--sensitive-soft); }
.col-prueba .led { background: var(--warn); box-shadow: 0 0 8px var(--warn-soft); }

/* ============ COLUMNAS PLEGABLES DEL TABLERO ============ */

/* Un kanban de siete columnas no entra en una pantalla, y casi nunca se
   miran todas a la vez. Colapsada, la columna no desaparece: se vuelve un
   lomo vertical que sigue diciendo su nombre y cuantas tarjetas tiene, que
   es la diferencia entre "la corri" y "la perdi". */
.columna-plegar {
    order: 9; margin-left: 6px;
    display: grid; place-items: center;
    width: 22px; height: 22px; padding: 0;
    background: none; border: 1px solid transparent; border-radius: 6px;
    color: var(--ink-3); cursor: pointer; font-size: 10px;
    transition: color .15s, border-color .15s;
}
.columna-plegar:hover { color: var(--accent); border-color: var(--line-strong); filter: none; }
.columna-contador { order: 8; }

.columna-nota {
    margin: 0; padding: 7px 16px;
    border-bottom: 1px solid var(--line);
    font-size: 11px; color: var(--ink-3);
}

.tablero .columna.colapsada { flex: 0 0 46px; min-width: 46px; }
.columna.colapsada .columna-titulo {
    flex-direction: column; gap: 12px;
    flex: 1; min-height: 240px; padding: 12px 0;
    border-bottom: none;
}
/* El nombre girado es lo que hace que el lomo se pueda leer sin desplegarlo. */
.columna.colapsada .columna-nombre { writing-mode: vertical-rl; }
.columna.colapsada .columna-contador { order: 10; margin-left: 0; margin-top: auto; padding: 2px 5px; }
.columna.colapsada .columna-plegar { order: 0; margin-left: 0; }
.columna.colapsada .columna-plegar i { transform: rotate(180deg); }
.columna.colapsada .columna-cards,
.columna.colapsada .columna-nota,
.columna.colapsada .alta-rapida-caja { display: none; }

/* ============ EL TACHO DEL ITEM ============ */

/* Anular desde el encabezado del ticket, en el detalle y en el cajon. Cerrado
   es un icono; abierto, el formulario con el motivo obligatorio.

   El :has() es necesario, no decorativo: .panel y .cajon-panel tienen
   overflow:hidden, y sin esto el desplegable se corta contra el borde del
   encabezado y el motivo queda tapado. */
.panel:has(.tacho-caja[open]),
.cajon-panel:has(.tacho-caja[open]) { overflow: visible; }

.panel-titulo .panel-acciones { display: inline-flex; align-items: center; }
.tacho-caja { position: relative; }
.tacho-abrir {
    list-style: none; cursor: pointer; user-select: none;
    display: grid; place-items: center;
    width: 26px; height: 26px;
    border: 1px solid transparent; border-radius: 7px;
    color: var(--bad); font-size: 12px;
    transition: background .15s, border-color .15s;
}
.tacho-abrir::-webkit-details-marker { display: none; }
.tacho-abrir:hover { background: var(--bad-soft); border-color: var(--bad); }
details[open] > .tacho-abrir { background: var(--bad-soft); border-color: var(--bad); }

.tacho-panel {
    position: absolute; right: 0; top: calc(100% + 8px); z-index: 40;
    width: 320px; max-width: 78vw;
}
.tacho-panel .anular-item { margin-top: 0; background: var(--panel-2); box-shadow: var(--shadow); }
.tacho-nota { margin: 0 0 12px; font-size: 12.5px; color: var(--ink-2); text-transform: none; letter-spacing: 0; }
.tacho-panel input[type="text"] { width: 100%; }

/* ============ PAPELERA ============ */

.papelera-encabezado { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.papelera-encabezado h1 { margin: 0; }
.vaciar-papelera { margin-left: auto; }
.vaciar-papelera .boton-peligro { margin-top: 0; }
.papelera-acciones { display: flex; gap: 8px; align-items: center; }
.papelera-acciones form { margin: 0; }
.papelera-acciones .boton-peligro { margin-top: 0; }
