/* ── Foco de teclado ──────────────────────────────────────
   Red de seguridad global (WCAG 2.4.7). Va primero y sin !important: cualquier
   regla más específica de más abajo la pisa, pero ningún control queda sin anillo
   de foco por un `outline: none` suelto —que es exactamente lo que le había
   pasado al slider de progreso: navegable con teclado y completamente invisible. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

/* ── Barra superior ─────────────────────────────────────────────────────────
   Reemplaza al sidebar de configuración: toda la config se mudó a /settings.html
   y esos 272px de ancho quedaron para las tarjetas de tareas. */

.app-topbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    position: sticky;
    top: 0;
    z-index: 1030;
}

.app-brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    font-size: .95rem;
    color: var(--bs-body-color);
    text-decoration: none;
    white-space: nowrap;
}

.app-brand i { font-size: 1.15rem; }

.topbar-session {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 12px;
    border-radius: 999px;
    background: rgba(var(--bs-success-rgb), .12);
    font-size: .82rem;
    min-width: 0;
}

/* El nombre de la tarea se trunca: si no, una tarea de título largo empuja
   las acciones fuera de la barra. */
.topbar-session-name {
    max-width: 32ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* tabular-nums evita que la barra tiemble cuando cambian los dígitos del cronómetro. */
.topbar-session-timer {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.topbar-account-btn {
    background: none;
    border: 0;
    padding: 0;
    line-height: 0;
    border-radius: 50%;
}

.topbar-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--bs-primary);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: .78rem;
    font-weight: 600;
    overflow: hidden;
}

.topbar-avatar img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 575.98px) {
    .topbar-session-name { max-width: 12ch; }
}

/* ── Active session pulse dot ───────────────────────────────────── */
.pulse-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #fff;
    flex-shrink: 0;
    animation: pulse-anim 1.6s ease-in-out infinite;
}

@keyframes pulse-anim {
    0%, 100% { opacity: 1;   transform: scale(1); }
    50%       { opacity: 0.3; transform: scale(0.6); }
}

/* ── Work package cards ─────────────────────────────────────────── */
.wp-card {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    border-color: rgba(255, 255, 255, 0.08) !important;
}

.wp-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35) !important;
}

/* Active session card */
.wp-card--active {
    border-color: rgba(25, 135, 84, 0.55) !important;
    box-shadow:
        0 0 0 1px rgba(25, 135, 84, 0.25),
        0 4px 24px rgba(25, 135, 84, 0.12) !important;
}

/* Other cards when a session is active */
.wp-card--disabled {
    opacity: 0.45;
    pointer-events: none;
}

/* ── Jerarquía tipográfica de la tarjeta ────────────────────────── */
/* Un solo texto grande (el asunto) y todo lo demás atenuado. El contraste de
   tamaño y color es lo que dirige la mirada; sin él, la tarjeta es una lista
   plana donde todo pesa igual. */
.wp-title {
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--bs-body-color);
    /* Exactamente 2 líneas —ni más ni menos— para que todas las tarjetas de la
       fila alineen título, metadatos y progreso. Solo recortar no alcanzaba: un
       título de una línea subía todo lo de abajo y rompía la lectura horizontal. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: calc(2 * 1.35em);
}

.wp-id {
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
    font-variant-numeric: tabular-nums;
}

/* 13px: por debajo de eso el texto secundario deja de leerse cómodo, sobre todo
   atenuado sobre fondo oscuro. Sigue muy por debajo del título, que es lo que
   mantiene la jerarquía. */
.wp-meta {
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--bs-secondary-color);
    min-width: 0;
}

/* Los glifos necesitan más tamaño que la letra para leerse igual de bien: no tienen
   ni altura de x ni contexto de palabra que ayude a reconocerlos. */
.wp-meta i {
    font-size: 0.95rem;
    opacity: 0.75;
}

.wp-meta-sep { opacity: 0.35; }

.wp-meta-edit {
    color: var(--bs-secondary-color);
    font-size: 0.95rem;
    line-height: 1;
    opacity: 0.75;
    transition: opacity 0.15s ease;
}

.wp-meta-edit:hover { opacity: 1; }

/* Acciones secundarias: presentes pero sin borde, para que no compitan con el
   botón primario (Iniciar / Finalizar) del mismo renglón. */
.wp-icon-btn {
    color: var(--bs-secondary-color);
    border: 0;
    padding: 0.3rem 0.5rem;
    font-size: 1.05rem;
    line-height: 1;
}

.wp-icon-btn:hover {
    color: var(--bs-body-color);
    background: rgba(255, 255, 255, 0.07);
}

/* ── Timer ──────────────────────────────────────────────────────── */
.card-timer {
    font-size: 2.1rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 3px;
    color: #20c997;
    line-height: 1;
}

/* ── Status badges ──────────────────────────────────────────────── */
/* Escala de FLUJO: avanza de azul (por hacer) → cian/violeta (en curso) → verde
   (ok) → gris (terminado), con rojo/naranja para las salidas por falla y ámbar
   para lo pausado. Relleno sólido a propósito: el estado es el dato que cambia y
   el que se escanea primero. Texto negro donde el fondo es claro (contraste AA). */
.status-new          { background-color: #0b5ed7 !important; }                          /* por hacer      */
.status-inprogress   { background-color: #0dcaf0 !important; color: #000 !important; }  /* en curso       */
.status-developed    { background-color: #198754 !important; }                          /* código listo   */
.status-testing      { background-color: #7c3aed !important; }                          /* en QA          */
.status-tested       { background-color: #20c997 !important; color: #000 !important; }  /* QA aprobado    */
.status-testfailed   { background-color: #dc3545 !important; }                          /* QA falló       */
.status-rejected     { background-color: #fd7e14 !important; color: #000 !important; }  /* rechazado      */
.status-deployed     { background-color: #0f766e !important; }                          /* en producción  */
.status-done         { background-color: #198754 !important; }
.status-closed       { background-color: #6c757d !important; }                          /* terminado      */
.status-hold         { background-color: #ffc107 !important; color: #000 !important; }  /* pausado        */
.status-default      { background-color: #495057 !important; }

/* ── Barra de progreso (solo lectura) ───────────────
   Era un <input type="range"> siempre editable: parecía un indicador y un clic
   perdido en la pista escribía el avance en OpenProject sin confirmación ni
   deshacer. El avance ahora se edita desde el modal de la tarjeta, igual que las
   fechas. Misma forma que `.tree-bar` para que las dos vistas se lean igual.

   Los dos colores cumplen 3:1 contra el fondo de la tarjeta (WCAG 1.4.11): la
   pista al 15% de blanco daba 1.5:1 y el azul #0d6efd, 2.3:1. */
.wp-bar {
    height: 5px;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.38);
    overflow: hidden;
}

.wp-bar-fill {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: #3d8bfd;
}

/* ── Status change dropdown ─────────────────────────────────────── */
.status-badge-btn {
    cursor: pointer;
    font-size: .75rem;
    transition: opacity 0.15s ease, filter 0.15s ease;
    /* Elimina el triángulo por defecto de Bootstrap en favor de uno pequeño */
}

.status-badge-btn:hover {
    filter: brightness(1.15);
}

.status-badge-btn:disabled {
    cursor: wait;
    opacity: 0.7;
}

.status-badge-btn::after {
    /* Chevron de Bootstrap pero más pequeño */
    font-size: .6em;
    vertical-align: middle;
    margin-left: 3px;
}

.status-dropdown-menu {
    min-width: 160px;
    font-size: .85rem;
    /* El max-height real lo pone app.js al abrirlo (alto de la tarjeta contenedora);
       este es el tope de respaldo si el JS no llegara a correr. */
    max-height: 260px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* La tarjeta con el menú de estados abierto tiene que pintarse por encima de las de
   abajo. `.wp-card:hover` aplica `transform`, y `transform` crea un contexto de
   apilamiento que encierra el z-index del menú dentro de la tarjeta: sin esto, las
   tarjetas siguientes (posteriores en el DOM) lo tapaban y los estados de más abajo
   no se podían ni ver ni clickear. */
.wp-card:has(.dropdown-menu.show) {
    position: relative;
    z-index: 5;
}

.status-dropdown-menu .dropdown-item {
    padding: .35rem .75rem;
    border-radius: 4px;
    margin: 1px 4px;
    width: calc(100% - 8px);
}

.status-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* ── Progress bar ───────────────────────────────────────────────── */
.progress-thin {
    height: 5px;
}

/* ── Status filter pills ────────────────────────────────────────────────────
   Seleccionado vs no seleccionado se distingue por relleno, borde e ícono, no
   por opacidad: un texto atenuado se lee como "deshabilitado" (no puedo tocarlo)
   en vez de "no aplicado" (puedo activarlo), que era justo la confusión.
   Tres canales a la vez para no depender solo del color.                      */
.status-filter-pill {
    border: 1.5px solid transparent;
    font-weight: 500;
    transition: background-color 0.15s ease, border-color 0.15s ease,
                box-shadow 0.15s ease, transform 0.1s ease;
}

/* Inactiva: contorno, sin relleno. Legible por sí sola, no atenuada. */
.status-filter-pill:not(.is-active) {
    background-color: transparent !important;
    color: var(--bs-body-color) !important;
    border-color: rgba(255, 255, 255, 0.45);
}

.status-filter-pill:not(.is-active):hover {
    background-color: rgba(255, 255, 255, 0.07) !important;
    border-color: rgba(255, 255, 255, 0.55);
    transform: translateY(-1px);
}

/* Activa: relleno sólido del estado + anillo. Inconfundible frente al hover. */
.status-filter-pill.is-active {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
}

.status-filter-pill.is-active:hover {
    transform: translateY(-1px);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
}

/* El foco de teclado no debe confundirse con el anillo de "activa". */
.status-filter-pill:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

/* "Ver todos" y "Limpiar" van en la misma fila que las píldoras pero no son estados:
   sin relleno de color y con borde punteado, para que no se lean como uno más. */
.status-filter-more,
.status-filter-clear {
    border: 1.5px dashed rgba(255, 255, 255, 0.45);
    color: var(--bs-body-color);
    font-weight: 500;
    background: transparent;
}

.status-filter-more:hover,
.status-filter-clear:hover {
    background: rgba(255, 255, 255, 0.07);
    border-color: rgba(255, 255, 255, 0.7);
    color: var(--bs-body-color);
}

/* Limpiar destruye la selección: el rojo lo separa de "Ver todos", que es inocuo. */
.status-filter-clear {
    border-color: rgba(var(--bs-danger-rgb), 0.6);
    color: var(--bs-danger-text-emphasis);
}

.status-filter-clear:hover {
    background: rgba(var(--bs-danger-rgb), 0.12);
    border-color: rgba(var(--bs-danger-rgb), 0.9);
    color: var(--bs-danger-text-emphasis);
}

/* El skip link cae sobre la barra superior, que es sticky con z-index 1030. */
.skip-link:focus {
    position: fixed;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 1040;
    padding: 0.5rem 1rem;
    border-radius: 0.375rem;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    color: var(--bs-body-color);
    text-decoration: none;
}

/* ── History table ──────────────────────────────────────────────── */
.session-active-row {
    --bs-table-accent-bg: rgba(25, 135, 84, 0.12);
}

/* ── Auth page ──────────────────────────────────────────────────── */
.auth-page {
    background: radial-gradient(ellipse at 60% 20%, rgba(13, 110, 253, 0.07) 0%, transparent 60%),
                radial-gradient(ellipse at 20% 80%, rgba(32, 201, 151, 0.05) 0%, transparent 50%),
                var(--bs-body-bg);
}

.auth-card {
    background: rgba(var(--bs-tertiary-bg-rgb), 0.9);
    border: 1px solid var(--bs-border-color-translucent) !important;
    backdrop-filter: blur(12px);
}

.auth-tabs .nav-link {
    color: var(--bs-secondary-color);
    border-radius: 8px;
    transition: background 0.15s ease, color 0.15s ease;
}

.auth-tabs .nav-link.active {
    background: rgba(13, 110, 253, 0.18);
    color: #6ea8fe;
}

.auth-tabs .nav-link:not(.active):hover {
    background: rgba(255, 255, 255, 0.05);
    color: var(--bs-body-color);
}

.auth-divider {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.auth-divider::before,
.auth-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: rgba(255, 255, 255, 0.1);
}

/* ── Botón "Iniciar sesión con OpenProject" ────────────────────────
   Mismo patrón que los botones de "Sign in with X" de terceros: color de marca sólido
   y un ícono en placa clara — acá el azul de OpenProject en vez del blanco de Google,
   porque el logo de OpenProject ya es azul (blanco+ícono de color no aplica igual). */
.btn-openproject {
    background-color: #1a67a3;
    border-color: #1a67a3;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.btn-openproject:hover:not(:disabled),
.btn-openproject:focus:not(:disabled) {
    background-color: #155284;
    border-color: #155284;
    color: #fff;
}

.btn-openproject:disabled {
    background-color: var(--bs-secondary-bg);
    border-color: var(--bs-border-color);
    color: var(--bs-secondary-color);
    opacity: 1;
}

.btn-openproject-icon {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    object-fit: contain;
}

.btn-openproject:disabled .btn-openproject-icon {
    filter: grayscale(1) opacity(0.6);
}

/* ── Tipo de work package (Implementación, Desarrollo, Bug...) ──── */
/* Estado y tipo son dos dimensiones distintas en la misma tarjeta, así que además
   del color se diferencian por FORMA: el estado va relleno sólido, el tipo va en
   contorno + fondo tenue. Así el color puede ser semántico en ambos sin que se
   confundan entre sí. El color concreto lo aporta cada clase .type-* vía --type. */
.wp-type-badge {
    background: color-mix(in srgb, var(--type) 20%, transparent);
    color: color-mix(in srgb, var(--type) 72%, #fff);
    border: 1px solid color-mix(in srgb, var(--type) 55%, transparent);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    vertical-align: middle;
}

.type-implementation { --type: #ffc107; }  /* implementación — ámbar   */
.type-development    { --type: #0d6efd; }  /* desarrollo     — azul    */
.type-bug            { --type: #dc3545; }  /* bug / error    — rojo    */
.type-support        { --type: #0dcaf0; }  /* soporte        — cian    */
.type-feature        { --type: #20c997; }  /* feature        — verde   */
.type-epic           { --type: #8b5cf6; }  /* épica          — violeta */
.type-milestone      { --type: #f472b6; }  /* hito           — rosa    */
.type-phase          { --type: #94a3b8; }  /* fase           — pizarra */
.type-default        { --type: #adb5bd; }  /* sin categoría  — neutro  */

/* ── Miga de pan de la tarjeta ──────────────────────────────────── */
/* Un renglón atenuado entre el eyebrow y el título: dice de qué cuelga la tarea
   sin competir con el asunto, que es lo que se lee primero. */
.wp-crumbs {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.75rem;
    color: var(--bs-secondary-color);
    min-width: 0;
    margin-bottom: 0.25rem;
}

/* Sin padre la fila igual ocupa su alto: si desaparece, las tarjetas sin padre
   suben una línea respecto de las que sí lo tienen y la fila deja de alinearse. */
.wp-crumbs--empty { visibility: hidden; }

.wp-crumbs-label { flex-shrink: 0; opacity: 0.8; }

/* El nombre de la tarea de la que depende pesa más que la etiqueta: es el dato. */
.wp-crumb-parent {
    min-width: 0;
    font-weight: 600;
    color: var(--bs-body-color);
    font-variant-numeric: tabular-nums;
}

.wp-crumb-link {
    color: var(--bs-secondary-color);
    line-height: 1;
    opacity: 0.7;
}

.wp-crumb-link:hover { opacity: 1; }

/* ── Vista Árbol ────────────────────────────────────────────────── */
/* Filas, no tarjetas: acá lo que importa es la relación entre tareas, y una fila por nodo
   deja ver varios niveles de un vistazo. Cada fila es una grilla con las MISMAS columnas,
   para poder recorrer una columna de arriba abajo sin releer la fila entera. */

.tree-wrap {
    --tree-indent: 1.75rem;
    --tree-line: color-mix(in srgb, var(--bs-secondary-color) 35%, transparent);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    overflow: hidden;
}

/* Anchos FIJOS en las cuatro columnas de la derecha, encabezado incluido. Con la última en
   `auto` cada fila la medía según su propio botón ("Iniciar" y "En curso" no miden igual), y
   como el sobrante lo absorbe la columna 1fr, cada fila empezaba sus columnas en una x
   distinta: por eso se veía todo desalineado contra el encabezado. */
.tree-head,
.tree-node {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 8.5rem 10rem 6.5rem 6.5rem;
    align-items: center;
    gap: 0.75rem;
    padding: 0.35rem 0.75rem;
}

/* El encabezado nombra las columnas una sola vez, en vez de obligar a deducirlas
   fila por fila. */
.tree-head {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bs-secondary-color);
    background: var(--bs-tertiary-bg);
    border-bottom: 1px solid var(--bs-border-color);
    padding-top: 0.45rem;
    padding-bottom: 0.45rem;
    /* Con el árbol desplegado la primera fila se va de pantalla y las columnas vuelven a ser
       datos sin nombre. Pegado arriba, el encabezado sigue explicándolas. */
    position: sticky;
    top: 0;
    z-index: 1;
}

.tree-node {
    border-bottom: 1px solid color-mix(in srgb, var(--bs-border-color) 55%, transparent);
    font-size: 0.875rem;
    min-height: 2.5rem;
}

.tree-node:last-child { border-bottom: 0; }
.tree-node:hover { background: color-mix(in srgb, var(--bs-body-color) 6%, transparent); }

/* Las tareas ajenas se ven pero no se accionan: se atenúa el número y el título para que la
   mirada caiga primero en las propias, que son las únicas con botón de Iniciar. */
.tree-node:not(.tree-node--mine) .tree-subject,
.tree-node:not(.tree-node--mine) .tree-id { color: var(--bs-secondary-color); }

/* Tres pesos, no uno: una tarea CON subtareas es un contenedor y se lee como encabezado de
   su grupo; una hoja es una tarea concreta; una ajena es contexto. Sin esa diferencia, diez
   filas iguales obligan a leerlas todas para entender la estructura. */
.tree-node--branch .tree-subject {
    font-weight: 600;
    color: var(--bs-body-color);
}

.tree-node--branch:not(.tree-node--mine) .tree-subject {
    color: var(--bs-emphasis-color, var(--bs-body-color));
    opacity: 0.85;
}

.tree-node--focus {
    background: color-mix(in srgb, var(--bs-primary) 14%, transparent);
    box-shadow: inset 3px 0 0 var(--bs-primary);
}

/* ── Columna 1: sangría, líneas guía, caret, id y asunto ── */

.tree-main {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
}

/* Las líneas verticales son UN gradiente repetido, una por nivel de ancestro: sin ellas,
   con tres niveles ya no se sabe qué cuelga de qué. El ancho del bloque es exactamente la
   sangría del nodo, así que la última línea cae junto a su caret. */
.tree-branch {
    flex: 0 0 auto;
    display: inline-flex;
    justify-content: flex-end;
    align-self: stretch;
    align-items: center;
    width: calc(var(--tree-depth, 0) * var(--tree-indent) + 1.5rem);
    background-image: repeating-linear-gradient(
        to right,
        transparent 0 calc(var(--tree-indent) - 1px),
        var(--tree-line) calc(var(--tree-indent) - 1px) var(--tree-indent));
    background-size: calc(var(--tree-depth, 0) * var(--tree-indent)) 100%;
    background-repeat: no-repeat;
}

.tree-toggle {
    background: none;
    border: 0;
    color: var(--bs-secondary-color);
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 0.25rem;
    padding: 0;
    line-height: 1;
    flex-shrink: 0;
}

.tree-toggle:hover {
    color: var(--bs-body-color);
    background: color-mix(in srgb, var(--bs-body-color) 12%, transparent);
}

.tree-toggle:focus-visible,
.tree-subtask:focus-visible,
.tree-start:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 1px;
}

/* La hoja no ofrece expandir: hacer clic para descubrir "sin subtareas" es trabajo perdido.
   Ocupa el mismo lugar igual, para que los títulos sigan alineados. */
.tree-toggle--leaf { display: inline-block; width: 1.5rem; height: 1.5rem; }

.tree-id {
    font-variant-numeric: tabular-nums;
    color: var(--bs-secondary-color);
    flex-shrink: 0;
}

.tree-subject {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Cuántas subtareas tiene, cuando OpenProject lo dice: evita expandir a ciegas. */
.tree-count {
    flex-shrink: 0;
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    color: var(--bs-secondary-color);
    background: color-mix(in srgb, var(--bs-body-color) 10%, transparent);
    border-radius: 999px;
    padding: 0.05rem 0.4rem;
}

/* ── Columnas 2 a 5 ── */

.tree-col {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
}

.tree-status-col .badge { font-size: 0.7rem; }

/* Sufijo, no reemplazo: el nombre de la persona manda, "(Tú)" solo lo marca. */
.tree-you {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--bs-primary);
    white-space: nowrap;
}

/* Un dato que todavía no tenemos no es lo mismo que un cero. */
.tree-dash { opacity: 0.45; }

.tree-bar {
    flex: 1 1 auto;
    height: 4px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--bs-body-color) 38%, transparent);
    overflow: hidden;
}

.tree-bar-fill {
    display: block;
    height: 100%;
    background: var(--bs-primary);
}

.tree-pct {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    width: 2.4rem;
    text-align: right;
}

.tree-actions {
    justify-content: flex-end;
    gap: 0.35rem;
    flex-shrink: 0;
}

.tree-subtask {
    color: var(--bs-secondary-color);
    border: 0;
    padding: 0.15rem 0.4rem;
    line-height: 1;
}

.tree-subtask:hover {
    color: var(--bs-body-color);
    background: color-mix(in srgb, var(--bs-body-color) 10%, transparent);
}

/* Mismo ancho para "Iniciar" y "En curso": si cada fila mide distinto, la columna tiembla
   al recorrerla con la vista. */
.tree-start,
.tree-running {
    min-width: 4.9rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    white-space: nowrap;
}

.tree-start {
    padding: 0.15rem 0.5rem;
    font-size: 0.78rem;
}

.tree-running { font-size: 0.7rem; }

.tree-running i { font-size: 0.55rem; vertical-align: middle; }

/* ── Notas al pie de un nodo: cargando, vacío, error ── */

.tree-note {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
    border-bottom: 1px solid color-mix(in srgb, var(--bs-border-color) 55%, transparent);
}

.tree-note--error { color: var(--bs-danger-text-emphasis, #ea868f); }
.tree-note .tree-retry { padding: 0; font-size: 0.8rem; }

.tree-empty {
    text-align: center;
    padding: 2.5rem 1rem;
    color: var(--bs-secondary-color);
    border: 1px dashed var(--bs-border-color);
    border-radius: 0.5rem;
}

.tree-empty i { font-size: 2rem; opacity: 0.25; display: block; margin-bottom: 0.5rem; }

.tree-spin { display: inline-block; animation: tree-spin 0.8s linear infinite; }

@keyframes tree-spin { to { transform: rotate(360deg); } }

/* En pantalla angosta se caen las columnas de contexto y queda lo accionable: quién es la
   tarea y qué se puede hacer con ella. */
@media (max-width: 991.98px) {
    .tree-head,
    .tree-node { grid-template-columns: minmax(0, 1fr) auto auto; }
    .tree-head span:nth-child(3),
    .tree-head span:nth-child(4),
    .tree-assignee-col,
    .tree-progress-col { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .tree-spin { animation: none; }
}

/* ── Impresión: solo la vista previa del reporte ────────────────── */
/* ponytail: se usa window.print() del navegador; estas reglas recortan la página
   al contenido del reporte en vez de sumar una librería de PDF. */
@media print {
    body * { visibility: hidden; }

    #reportPreviewModal,
    #reportPreviewModal * { visibility: visible; }

    #reportPreviewModal {
        display: block !important;
        position: absolute;
        inset: 0;
        overflow: visible !important;
        background: #fff;
    }

    #reportPreviewModal .modal-dialog {
        max-width: 100%;
        margin: 0;
    }

    #reportPreviewModal .modal-content {
        border: 0;
        box-shadow: none;
        background: #fff;
        color: #000;
    }

    #reportPreviewModal .modal-body {
        overflow: visible !important;
        max-height: none !important;
    }

    /* Los controles no aportan nada en papel */
    #reportPreviewModal .modal-footer,
    #reportPreviewModal .btn-close,
    .modal-backdrop {
        display: none !important;
    }

    #reportPreviewModal .table,
    #reportPreviewModal .table th,
    #reportPreviewModal .table td,
    #reportPreviewModal .text-muted {
        color: #000 !important;
        border-color: #bbb !important;
    }

    #reportPreviewModal thead { display: table-header-group; }
    #reportPreviewModal tr    { page-break-inside: avoid; }
}

/* Corte entre las acciones de la app y la zona de cuenta. Sin él los botones y el avatar
   quedaban al mismo gap y el ojo los leia como una sola fila de controles equivalentes. */
.topbar-divider {
    width: 1px;
    height: 22px;
    background: var(--bs-border-color);
    margin-inline: 4px;
    flex: 0 0 auto;
}
