/* ===== TRACKER CONTAINER ===== */
.tracker-container {
    /* Los design tokens de Variant A (re-skin UX-TRK-01) se PROMOVIERON a :root
       en wwwroot/css/design-system/tokens.css (Epic UX-DS-01 / DS-01.01).
       Este contenedor ahora SOLO los consume vía var(--token), igual que el
       resto de la app — ya no están atrapados aquí. */
    /* UX-DS-03.01 — worksheet header (variant-A thead th es blanco + labels gris).
       Override PAGE-SCOPED de los tokens que DsDataGrid consume para el header;
       las tablas legacy fuera del tracker (site.css) conservan el navy global. */
    --table-header-bg: var(--bg-white);
    --table-header-text: var(--med-gray-medium);
    padding: 20px;
    /* FIX (2026-07): este contenedor vive DENTRO de <main>, debajo del top-row de 64px
       (--header-height). Con height:100vh el contenido medía 100vh + 64px y desbordaba el
       viewport: el <body> hacía scroll y el .sidebar (sticky, 100vh) no cubría el sobrante,
       dejando espacio en blanco bajo el menú, bajo el contenido y el gutter de scroll a la
       derecha. Restar el header hace que main = top-row + este contenedor = 100vh exacto. */
    height: calc(100vh - var(--header-height));
    display: flex;
    flex-direction: column;
    /* UX-DS-03.04 — variant-A --bg-page (era #f5f5f5 literal) */
    background: var(--bg-page);
    /* Anchor for the full-view initial-loading overlay (.tracker-initial-loading). */
    position: relative;
}

/* Full-view initial loading (2026-07) — covers the entire tracker while OnInitializedAsync resolves the
   views/tabs/columns and loads the first page, so the user never sees the empty-table → tabs → data flash. */
.tracker-initial-loading {
    position: absolute;
    inset: 0;
    z-index: 50;
    background: var(--bg-page);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
}
.tracker-initial-loading__spinner {
    width: 2.75rem;
    height: 2.75rem;
    color: var(--med-blue-interactive, #0067b8);
}
.tracker-initial-loading__text {
    margin: 0;
    font-size: .95rem;
    font-weight: 600;
    color: var(--med-gray-medium, #666);
}

/* ===== HEADER ===== */
.tracker-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
}

.tracker-header h1 {
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--med-blue-primary);
    margin: 0;
}

.tracker-actions {
    display: flex;
    gap: 8px;
}

/* ===== FILTERS ===== */
.tracker-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: flex-end;
    padding: 16px;
    background: white;
    border-radius: 8px;
    margin-bottom: 16px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.filter-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.filter-group label {
    font-size: 0.75rem;
    font-weight: 600;
    color: #666;
    text-transform: uppercase;
}

.filter-group select,
.filter-group input {
    padding: 8px 12px;
    border: 1px solid #d4d4d4;
    border-radius: 4px;
    font-size: 0.875rem;
    min-width: 120px;
}

/* Variant A: filtro con valor activo resaltado (fondo amarillo + borde azul). */
.filter-group select.has-value,
.filter-group input.has-value {
    background: var(--med-yellow-bg);
    border-color: var(--med-blue-interactive);
}

.filter-group.search input {
    min-width: 200px;
}

/* ===== PHASE FILTER (current-phase multi-select dropdown; replaces the intake toggle) ===== */
.filter-group.phase-filter { position: relative; }
.phase-filter-dd { position: relative; }
.phase-filter-dd > summary {
    list-style: none;
    cursor: pointer;
    padding: 8px 12px;
    border: 1px solid #d4d4d4;
    border-radius: 4px;
    font-size: 0.875rem;
    min-width: 120px;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.phase-filter-dd > summary::-webkit-details-marker { display: none; }
.phase-filter-dd > summary::after { content: "▾"; color: #666; }
.phase-filter-dd.has-value > summary {
    background: var(--med-yellow-bg);
    border-color: var(--med-blue-interactive);
}
.phase-filter-menu {
    position: absolute;
    z-index: 30;
    margin-top: 4px;
    min-width: 220px;
    max-height: 320px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid #d4d4d4;
    border-radius: 4px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, .12);
    padding: 6px;
}
.phase-filter-opt {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 8px;
    font-size: 0.85rem;
    font-weight: 400;
    text-transform: none;
    color: #222;
    border-radius: 4px;
    cursor: pointer;
    white-space: nowrap;
}
.phase-filter-opt:hover { background: #f2f6fc; }
.phase-filter-opt input { min-width: auto; }
.phase-filter-all {
    border-bottom: 1px solid #eee;
    margin-bottom: 4px;
    font-weight: 600;
}

.filter-count {
    margin-left: auto;
    font-size: 0.875rem;
    color: #666;
}

/* ===== TABLE WRAPPER ===== */
.tracker-table-wrapper {
    flex: 1;
    overflow: auto;
    background: white;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    margin-bottom: 60px; /* Space for unsaved changes bar */
}

/* ===== TABLE ===== */
/* table-layout: fixed (perf quick-win 3.4, PROPOSAL-TRACKER-SCROLL-PERF-2026-07-06): with ~400 columns in
   wide views, the auto table-layout algorithm re-measures cell CONTENT on every DOM patch/reflow (each
   Virtualize windowing pass); fixed layout sizes columns from the first header row only — O(columns), no
   content measuring — and keeps the table width stable across windowing (no layout shift as rows realize).
   Column widths come from the <th>s: the frozen/special columns keep their explicit widths below; every
   other column gets the :where() low-specificity default (140px) so ANY existing class width rule still
   wins. Content that used to auto-widen its column now ellipsizes (see .project-row td below). */
.tracker-table {
    table-layout: fixed;
    width: max-content;
    min-width: 100%;
    border-collapse: collapse;
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
}

/* Default column width under fixed layout. :where() keeps specificity at (0,0,1) so every existing
   width rule (.col-checkbox, .col-id, .col-tool, .col-wide, …) overrides it. */
:where(.tracker-table) th {
    width: 140px;
}

/* UX-DS-03.01 — worksheet header (Variant A thead th): white bg + 2px blue underline +
   small gray uppercase labels. Height from the DS token (--grid-header-h = 38px).
   background/color viajan vía --table-header-* (override en .tracker-container) porque
   la regla scoped de DsDataGrid (.ds-grid__head[b-x] th) gana en especificidad. */
.tracker-table th {
    background: var(--bg-white);
    color: var(--med-gray-medium);
    font-weight: 700;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.7px;
    padding: 0 12px;
    height: var(--grid-header-h);
    border-bottom: 2px solid var(--med-blue-primary);
    text-align: left;
    white-space: nowrap;
    /* fixed table-layout (3.4): headers no longer widen their column, so long labels must
       ellipsize instead of bleeding over the neighbor th. */
    overflow: hidden;
    text-overflow: ellipsis;
    user-select: none;
    position: sticky;
    top: 0;
    z-index: 10;
}

/* UX-DS-03.01 — la regla scoped de DsDataGrid declara font-weight:var(--font-weight-semibold)
   con especificidad (0,2,1) y su hoja viene después; este selector (0,2,2) la supera
   sin tocar el token global de tipografía. */
.tracker-table-wrapper table.tracker-table th {
    font-weight: 700;
}

/* Sortable Headers */
.tracker-table th.sortable {
    cursor: pointer;
    user-select: none;
    transition: background 0.15s ease;
}

/* UX-DS-03.01 — sortable hover/sorted al lenguaje del prototipo (variant-A.html:494):
   hover = texto azul + fondo amarillo suave; sorted = texto azul sobre blanco. */
.tracker-table th.sortable:hover {
    color: var(--med-blue-primary);
    background: var(--med-yellow-bg);
}

.tracker-table th.sortable.sorted {
    color: var(--med-blue-primary);
    background: var(--bg-white);
}

.tracker-table th.sortable::after {
    content: '';
    display: inline-block;
    margin-left: 4px;
    opacity: 0.4;
}

.tracker-table td {
    padding: 0 12px;
    border-bottom: 1px solid var(--grid-line);
    vertical-align: middle;
}

/* Densidad de fila de proyecto (Variant A: 32px). Fase/tarea fijan su propia altura. */
/* nowrap+ellipsis (perf quick-win 3.4): under fixed table-layout a column no longer auto-widens to fit
   its content, so long values must truncate instead of wrapping (wrapping would break the 32px density
   AND the Virtualize ItemSize="32" hint). Bonus: single-line rows keep the spacer math exact. */
.project-row td {
    height: 32px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ===== FROZEN COLUMNS ===== */
.frozen {
    position: sticky;
    background: white;
    z-index: 5;
}

/* UX-DS-03.01 — frozen header cells: opaque white (variant-A.html:532) so the
   non-frozen columns don't bleed through under horizontal scroll. z-index preserved. */
th.frozen {
    background: var(--bg-white);
    z-index: 15;
}

.col-checkbox { left: 0; width: 40px; min-width: 40px; }
.col-expand { left: 40px; width: 30px; min-width: 30px; }
/* Story 11B.14 (Q9) — frozen primary identity column now carries ProjectDisplayId (+ Intake badge)
   instead of the legacy int "#", so it is wider. col-tool shifts right to keep the sticky offsets exact. */
.col-id { left: 70px; width: 150px; min-width: 150px; max-width: 150px; overflow: hidden; }
.col-tool { left: 220px; width: 300px; min-width: 300px; max-width: 300px; overflow: hidden; text-overflow: ellipsis; }

/* Fix (2026-07-06, found while validating the perf quick wins — PRE-EXISTING since the DS-02.01 DsDataGrid
   retrofit): the scoped primitive rule `.ds-grid[b-…] .ds-grid__cell--frozen { left: 0 }` (specificity
   (0,3,0) — the [b-…] scope attribute counts at class level — and its bundle
   MtmpProjectsPoc.Web.styles.css loads AFTER this file) beats the per-column offsets above ((0,1,0)) —
   so ALL four frozen columns computed left:0 and stacked on top of each other under horizontal scroll
   (only col-tool remained visible; checkbox/expand/id buried underneath). Confirmed live with a
   styleSheets walker. th/td variants make these (0,3,1) > (0,3,0), re-winning the staggered offsets. */
.tracker-table-wrapper .tracker-table th.col-checkbox, .tracker-table-wrapper .tracker-table td.col-checkbox { left: 0; }
.tracker-table-wrapper .tracker-table th.col-expand, .tracker-table-wrapper .tracker-table td.col-expand { left: 40px; }
.tracker-table-wrapper .tracker-table th.col-id, .tracker-table-wrapper .tracker-table td.col-id { left: 70px; }
.tracker-table-wrapper .tracker-table th.col-tool, .tracker-table-wrapper .tracker-table td.col-tool { left: 220px; }

/* Story 11B.14 (Q9) — ProjectDisplayId cell: single-line ellipsis text + the warning "Intake" chip. */
.col-display-id .display-id-text {
    display: inline-block;
    max-width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
    font-weight: 600;
}

/* ProjectDisplayId is a link that opens the project detail in a new tab. Styled as an
   interactive link (brand blue, underline on hover) so the affordance reads as clickable. */
.col-display-id a.display-id-link {
    color: var(--med-blue-interactive, #0067b8);
    text-decoration: none;
    cursor: pointer;
}
.col-display-id a.display-id-link:hover,
.col-display-id a.display-id-link:focus-visible {
    text-decoration: underline;
}

/* Opción E (2026-07) — styled hover tooltip for truncated Tool/Phase/Task names.
   Rendered at <body> level by tracker-tooltip.js (a "portal") so the frozen col-tool's
   overflow:hidden never clips it. position:fixed because JS positions it in viewport
   coords (getBoundingClientRect). Matches the dark .comment-preview look already in the grid. */
.tracker-tooltip {
    position: fixed;
    z-index: 3000;
    max-width: 360px;
    background: #1e293b;
    color: #fff;
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 0.75rem;
    line-height: 1.35;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
    pointer-events: none;
    white-space: normal;
    word-break: break-word;
}

/* UX-DS-05.02 (CB-1.a) — divisor frozen como barra 1px compuesta (background), SIN box-shadow.
   El box-shadow sobre position:sticky repinta la columna congelada en cada frame de scroll
   horizontal; una barra de background es un fill barato y el ::after es overlay (no afecta el
   layout, los offsets frozen de 520px quedan intactos). Look idéntico. */
.col-tool::after {
    content: '';
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--frozen-divider);
}

/* ===== ROWS ===== */
/* Zebra (Variant A --row-zebra). Va ANTES de hover/selected/expanded a propósito:
   misma especificidad → el orden de fuente deja ganar a los estados interactivos. */
.project-row.zebra,
.project-row.zebra .frozen {
    background: var(--row-zebra);
}

.project-row:hover {
    background: var(--row-hover);
}

/* UX-DS-05.02 (CB-1.b) — el hover del cuerpo se conserva (regla de arriba); el highlight del
   spine frozen se ELIMINA a propósito: repintar el background de la celda sticky mientras el
   cursor recorre el grid la repinta por frame. Decisión Ivan 2026-07-04 (diseño §7.2). */

.project-row.selected {
    background: var(--row-selected);
}

.project-row.selected .frozen {
    background: var(--row-selected);
}

.project-row.expanded {
    background: var(--row-hover);
}

.project-row.expanded .frozen {
    background: var(--row-hover);
}

/* ===== ROW VARIANTS (Variant A) ===== */
/* Intake: SIN tratamiento visual por fila (decisión 2026-07-03). Antes las filas de fase
   "Intake Form" llevaban franja azul + tool-name azul negrita (clase `npd-row`), que se leía
   inconsistente (aparecía en una mezcla de INT-* y PRJ en DRAFT) y multi-barra. Se eliminó:
   las filas intake se ven uniformes; el estado read-only se comunica por el checkbox
   deshabilitado (`IsIntake` sigue gateando bulk-selection). NPD es un badge propio, no una fila. */

/* Completed: fila atenuada + Tool Name tachado (Variant A). */
.project-row.completed td {
    color: var(--med-gray-medium);
}
.project-row.completed .tool-name-text {
    text-decoration: line-through;
    text-decoration-color: var(--med-gray-light);
    text-decoration-thickness: 1px;
}

/* Tool Name en una sola línea + ellipsis para no romper la densidad de 32px.
   Opción B (2026-07): la columna congelada pasó de 220px→300px; el texto sube su
   max-width en el mismo delta (150→230) para aprovechar el ancho extra. */
.col-tool .tool-name-text {
    display: inline-block;
    max-width: 230px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}

/* ===== PHASES CONTAINER ROW ===== */
.phases-container-row {
    background: #f8fafc;
}

.phases-container-row .frozen {
    background: #f8fafc;
}

.phases-indent {
    border-right: 2px solid #e2e8f0;
}

.phases-cell {
    padding: 12px 16px !important;
}

/* ===== PHASES TIMELINE ===== */
.phases-timeline {
    display: flex;
    align-items: stretch;
    gap: 0;
    overflow-x: auto;
    padding: 4px 0;
}

.phase-connector {
    width: 24px;
    min-width: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

.phase-connector::before {
    content: '';
    width: 100%;
    height: 2px;
    background: linear-gradient(90deg, #cbd5e1, #94a3b8);
}

/* ===== PHASE CARD (Tracker Timeline Only) ===== */
/* Scoped to .phases-timeline to avoid conflicts with PhaseCard component */
.phases-timeline .phase-card {
    background: white;
    border-radius: 8px;
    padding: 10px 14px;
    min-width: 160px;
    max-width: 180px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
    border: 1px solid #e2e8f0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: all 0.2s ease;
}

.phases-timeline .phase-card:hover {
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    transform: translateY(-1px);
}

.phases-timeline .phase-card-complete {
    border-color: #10b981;
    background: linear-gradient(135deg, #f0fdf4 0%, #ecfdf5 100%);
}

.phases-timeline .phase-card-active {
    border-color: #3b82f6;
    background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
    box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);
}

.phases-timeline .phase-card-pending {
    border-color: #e2e8f0;
    background: #f8fafc;
    opacity: 0.7;
}

/* ===== PHASE HEADER ===== */
.phase-header {
    display: flex;
    align-items: center;
    gap: 6px;
}

.phase-status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.dot-complete {
    background: #10b981;
    box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
}

.dot-active {
    background: #3b82f6;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
    animation: pulse 2s infinite;
}

.dot-pending {
    background: #cbd5e1;
}

@keyframes pulse {
    0%, 100% { box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2); }
    50% { box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1); }
}

.phase-title {
    font-size: 0.75rem;
    font-weight: 600;
    color: #334155;
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.phase-progress-badge {
    font-size: 0.65rem;
    font-weight: 700;
    padding: 2px 6px;
    border-radius: 10px;
    white-space: nowrap;
}

.progress-badge-complete {
    background: #10b981;
    color: white;
}

.progress-badge-good {
    background: #3b82f6;
    color: white;
}

.progress-badge-started {
    background: #f59e0b;
    color: white;
}

.progress-badge-pending {
    background: #e2e8f0;
    color: #64748b;
}

/* ===== PHASE PROGRESS BAR ===== */
.phase-progress-bar {
    height: 4px;
    background: #e2e8f0;
    border-radius: 2px;
    overflow: hidden;
}

.phase-progress-fill {
    height: 100%;
    border-radius: 2px;
    transition: width 0.3s ease;
}

.fill-complete {
    background: linear-gradient(90deg, #10b981, #059669);
}

.fill-active {
    background: linear-gradient(90deg, #3b82f6, #2563eb);
}

.fill-pending {
    background: #cbd5e1;
}

/* ===== PHASE DATES ===== */
.phase-dates {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 2px;
}

.phase-date-input {
    font-size: 0.65rem;
    padding: 2px 4px;
    border: 1px solid #e2e8f0;
    border-radius: 4px;
    background: white;
    color: #475569;
    width: 90px;
}

.phase-date-input:focus {
    border-color: #3b82f6;
    outline: none;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

.phase-date-separator {
    color: #94a3b8;
    font-size: 0.7rem;
}

/* ===== PHASE COMMENT ===== */
.phase-comment {
    font-size: 0.65rem;
    color: #64748b;
    background: #f1f5f9;
    padding: 3px 6px;
    border-radius: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ===== PHASE ROWS V2 (Compact Table Format) ===== */
/* UX-DS-03.03 — filas phase al lenguaje variant-A (tr.row-phase): bg unificado
   (el ESTADO vive en el dot + color del nombre, no en el bg de la fila), tree-line
   └─ mono, dot 9px con phasePulse. Hex Tailwind tokenizados. */
.phase-row-v2 {
    background: var(--row-phase-bg);
    font-size: 11.5px;
    line-height: 1.2;
}

.phase-row-v2 td {
    padding: 4px 6px !important;
    border-bottom: 1px solid var(--grid-line);
    height: 28px;
    vertical-align: middle;
}

.phase-row-v2 .frozen,
.phase-row-v2.phase-complete .frozen,
.phase-row-v2.phase-in-progress .frozen,
.phase-row-v2.phase-pending .frozen {
    background: var(--row-phase-bg);
}

.phase-row-v2.phase-complete,
.phase-row-v2.phase-in-progress,
.phase-row-v2.phase-pending {
    background: var(--row-phase-bg);
}

/* Phase ID column */
.phase-row-v2 .phase-id {
    color: var(--med-gray-light);
    font-size: 0.7rem;
}

/* Phase Name Cell — indentación variant-A (18px). Especificidad (0,2,0) para
   ganar al `.phase-row-v2 td { padding: 4px 6px !important }` (0,1,1). */
.phase-row-v2 .phase-name-cell {
    padding-left: 18px !important;
}

.phase-name-content {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Tree-line └─ (variant-A .phase-tree) */
.phase-tree {
    font-family: var(--font-mono);
    color: var(--med-gray-light);
    letter-spacing: -0.5px;
    font-size: 0.9rem;
}

/* Dot de estado 9px (variant-A .phase-status-icon) */
.phase-status-indicator {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
}

.phase-status-indicator.dot-complete {
    background: var(--status-success);
}

.phase-status-indicator.dot-active {
    background: var(--med-blue-interactive);
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--med-blue-interactive) 45%, transparent);
    animation: phasePulse 1.5s ease-in-out infinite;
}

.phase-status-indicator.dot-pending {
    background: var(--med-gray-lighter);
}

@keyframes phasePulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--med-blue-interactive) 40%, transparent); }
    50%      { box-shadow: 0 0 0 5px transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .phase-status-indicator.dot-active { animation: none; box-shadow: none; }
}

/* Nombre por estado (variant-A .phase-name) */
.phase-name-text {
    font-weight: 600;
    color: var(--med-gray-dark);
    white-space: nowrap;
}

.phase-row-v2.phase-complete .phase-name-text { color: var(--status-success-deep); }
.phase-row-v2.phase-in-progress .phase-name-text { color: var(--med-blue-medium); }
.phase-row-v2.phase-pending .phase-name-text { color: var(--med-gray-medium); }

/* Phase Progress Cell */
.phase-progress-cell {
    min-width: 120px;
}

.phase-progress-wrapper {
    display: flex;
    align-items: center;
    gap: 8px;
}

.phase-progress-bar-v2 {
    flex: 1;
    height: 4px;
    background: #e2e8f0;
    border-radius: 2px;
    overflow: hidden;
    min-width: 50px;
}

.phase-progress-fill-v2 {
    height: 100%;
    border-radius: 3px;
    transition: width 0.3s ease;
}

.phase-progress-fill-v2.fill-complete {
    background: linear-gradient(90deg, #10b981, #059669);
}

.phase-progress-fill-v2.fill-active {
    background: linear-gradient(90deg, #3b82f6, #2563eb);
}

.phase-progress-fill-v2.fill-pending {
    background: #cbd5e1;
}

.phase-progress-text {
    font-size: 0.7rem;
    font-weight: 600;
    min-width: 32px;
    text-align: right;
}

.phase-progress-text.progress-badge-complete {
    color: #059669;
}

.phase-progress-text.progress-badge-good {
    color: #2563eb;
}

.phase-progress-text.progress-badge-started {
    color: #d97706;
}

.phase-progress-text.progress-badge-pending {
    color: #94a3b8;
}

/* Phase Status Badge */
.phase-status-cell {
    min-width: 90px;
}

.phase-status-badge {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 0.6rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.phase-badge-complete {
    background: #d1fae5;
    color: #065f46;
}

.phase-badge-active {
    background: #dbeafe;
    color: #1e40af;
}

.phase-badge-pending {
    background: #f1f5f9;
    color: #64748b;
}

/* Phase Date Inputs */
.phase-date-cell {
    min-width: 100px;
}

.phase-date-input-v2 {
    width: 100%;
    padding: 2px 4px;
    border: 1px solid #e2e8f0;
    border-radius: 3px;
    font-size: 0.7rem;
    color: #475569;
    background: white;
    height: 22px;
}

.phase-date-input-v2:focus {
    border-color: #3b82f6;
    outline: none;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

/* Phase Comment Input */
.phase-comment-cell {
    min-width: 180px;
}

.phase-comment-input {
    width: 100%;
    padding: 2px 6px;
    border: 1px solid #e2e8f0;
    border-radius: 3px;
    font-size: 0.7rem;
    color: #475569;
    background: white;
    height: 22px;
}

.phase-comment-input::placeholder {
    color: #94a3b8;
    font-style: italic;
}

.phase-comment-input:focus {
    border-color: #3b82f6;
    outline: none;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

/* ===== LEGACY PHASE ROWS (keeping for compatibility) ===== */
.phase-row {
    background: #fafafa;
}

.phase-row .frozen {
    background: #fafafa;
}

.phase-row .phase-name {
    padding-left: 24px;
    color: #666;
    font-size: 0.8rem;
    white-space: nowrap;
}

.phase-row.phase-complete {
    background: #f0fff4;
}

.phase-row.phase-complete .frozen {
    background: #f0fff4;
}

.phase-row.phase-in-progress {
    background: #fff8e6;
}

.phase-row.phase-in-progress .frozen {
    background: #fff8e6;
}

.phase-row.phase-pending {
    background: #fafafa;
}

/* ===== EXPAND BUTTON ===== */
.expand-btn {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.75rem;
    color: #666;
    padding: 4px;
    border-radius: 4px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.expand-btn:hover {
    background: #e5e5e5;
}

/* ===== EDITABLE CELLS ===== */
.cell-editable input,
.cell-editable select,
.cell-editable textarea {
    width: 100%;
    padding: 4px 8px;
    border: 1px dashed #d4d4d4;
    border-radius: 4px;
    background: transparent;
    font-size: 0.8rem;
    font-family: inherit;
}

.cell-editable input:focus,
.cell-editable select:focus,
.cell-editable textarea:focus {
    /* UX-DS-05.03b (feedback Ivan) — single focus rectangle. The old `border` + offset `outline` drew TWO
       concentric rectangles (the outline sits outside the border with a gap); with CB-2 auto-focusing the
       editor on activate it showed immediately as a "double rectangle". Keep one crisp solid-blue border as
       the focus affordance (dashed-grey → solid-blue is a clear state change); no separate outline. */
    border-color: #1010EB;
    border-style: solid;
    outline: none;
    background: white;
}

/* UX-DS-05.03b/05.05 (feedback Ivan) — fix the "double rectangle" on the ACTIVE editing cell. DevTools pinned
   the two frames: the <td>.cell-selected 2px blue inset ring (OUTER) + the editor input's own border (INNER),
   the latter forced by GLOBAL app-wide rules in create-project-hotfix.css (`input[type=…] { border: 1.5px …
   !important; padding: 10px 14px !important }` + `input:focus { border-color/box-shadow glow !important;
   transform: translateY(-1px) }`).
   WHY specificity alone could never win: since UX-DS-02.03 the hotfix is imported into `@layer overrides`
   (design-system/index.css) — and for `!important` declarations the layer cascade INVERTS: a layered
   !important beats ANY unlayered !important regardless of specificity. This file is unlayered, so its
   previous (0,3,2) !important rule silently lost to the hotfix's (0,1,1). The fix must therefore live
   INSIDE `@layer overrides` too — same layer, so specificity decides again and (0,3,2) beats (0,1,1).
   Validated live (Playwright, styleSheets walker + computed styles) on 2026-07-06.
   Result: the td's blue ring is the single frame; the input fills it borderless, flat and white (the editor
   auto-focuses on mount, CB-2). Padding reset so the input fits the 32px row; transform/box-shadow reset to
   kill the hotfix's focus glow + 1px lift. */
@layer overrides {
    .tracker-table-wrapper td.cell-editable.cell-selected input,
    .tracker-table-wrapper td.cell-editable.cell-selected select,
    .tracker-table-wrapper td.cell-editable.cell-selected textarea {
        border: 0 !important;
        box-shadow: none !important;
        outline: none !important;
        padding: 4px 8px !important;
        transform: none !important;
        background: #fff !important;
    }

    /* <select> only: with `appearance: auto` Chrome/macOS paints the NATIVE menulist bezel, which ignores
       `border: 0` — the surviving "inner rectangle" on dropdown editors (feedback Ivan, screenshot 2026-07-06;
       date/text/textarea editors draw no bezel, which is why they were already clean). appearance:none drops
       the bezel AND the native arrow, so a small CSS chevron takes its place (background-image beats the base
       rule's `background: #fff` shorthand above by source order at equal specificity, same layer). */
    .tracker-table-wrapper td.cell-editable.cell-selected select {
        appearance: none !important;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23555' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E") !important;
        background-repeat: no-repeat !important;
        background-position: right 6px center !important;
        padding-right: 22px !important;
    }

    /* Dirty (unsaved) active editor keeps its yellow fill — the base rule's `background: #fff` shorthand
       above would otherwise override the unlayered `.cell-editable .dirty` marker. (0,4,1) > (0,3,2). */
    .tracker-table-wrapper td.cell-editable.cell-selected .dirty {
        background-color: #fffde7 !important;
    }
}

.cell-editable .dirty {
    background: #fffde7 !important;
    border-color: #ffc107 !important;
    border-style: solid !important;
}

.cell-editable textarea {
    resize: none;
    min-height: 28px;
}

.col-wide {
    /* fixed table-layout sizes columns from the header row's `width` (min-width alone no longer widens
       the column) — keep min-width for safety, width is what the fixed algorithm reads. */
    width: 240px;
    min-width: 200px;
}

/* ===== UX-DS-05.05 (CB-4) — <Virtualize> loading skeleton (feedback Ivan) ===== */
/* The momentary blank on fast vertical scroll is Blazor Server's RENDER round-trip (the newly-scrolled
   window is patched over SignalR AFTER the scroll), NOT data loading — so <Virtualize>'s Placeholder slot
   (which only fills an ASYNC ItemsProvider's data gap) does not apply.
   WHY the skeleton must live on the <table> and nowhere lower: per the CSS table painting model, the
   background of a row / row-group (tr, tbody) is only ever painted BEHIND CELLS — the Virtualize spacer
   <tr> has NO cells, so a tbody/tr background never paints in the spacer area (confirmed live: the tbody
   had the gradient in computed styles yet the viewport stayed white; elementFromPoint mid-scroll returned
   the TABLE, whose white background was what the user saw). The <table> element is the only one whose
   background paints its full box regardless of cells, so the stripes go here. Static stripes (no
   animation), so prefers-reduced-motion needs no special casing. Validated live (Playwright mid-scroll
   screenshot) on 2026-07-06. !important beats the scoped DsDataGrid bundle's `.ds-grid { background:
   var(--bg-white) }` (MtmpProjectsPoc.Web.styles.css, loaded after this file). */
.tracker-table-wrapper table.tracker-table {
    background-color: #f6f6f8 !important;
    background-image: repeating-linear-gradient(
        to bottom,
        #e4e4ea 0,
        #e4e4ea 18px,          /* skeleton "row" band */
        #f6f6f8 18px,
        #f6f6f8 32px           /* gap → 32px stripe = ItemSize (row height) */
    ) !important;
}
/* Real rows (any <tr> WITH cells) get an opaque row background so they cover the table skeleton; the empty
   Virtualize spacer <tr>s (no cells) are excluded (their background would not paint anyway), so the skeleton
   shows through them. Zebra/hover/selected cell backgrounds sit on top of this per-cell, so striping and
   states are unaffected. thead cells keep their own opaque header background, covering the stripes up top. */
.tracker-table-wrapper .ds-grid__body tr:not(:empty) {
    background-color: #fff !important;
}

/* ===== BADGES ===== */
.badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Priority — legacy (UX-DS-03.02: las celdas Type/Status/Priority del grid ya van vía
   DsBadge; estas clases quedan para consumidores residuales fuera del grid). */
.badge-priority-high { background: #dc3545; color: white; }
.badge-priority-medium { background: #ffc107; color: black; }
.badge-priority-low { background: #28a745; color: white; }

/* Status — legacy (ver nota arriba) */
.badge-status-in-progress { background: #cce5ff; color: #004085; }
.badge-status-complete { background: #d4edda; color: #155724; }
.badge-status-on-hold { background: #fff3cd; color: #856404; }
.badge-status-cancelled { background: #f8d7da; color: #721c24; }

/* Type — legacy (ver nota arriba) */
.badge-type-replacement { background: #e2e3e5; color: #383d41; }
.badge-type-refurbishment { background: #d1ecf1; color: #0c5460; }
.badge-type-repair { background: #fff3cd; color: #856404; }
.badge-type-eol { background: #f8d7da; color: #721c24; }
.badge-type-duplication { background: #d4edda; color: #155724; }

/* ============================================================================
   UX-DS-03.02 — DsBadge dentro del grid del tracker: geometría + paleta soft
   variant-A (.badge del prototipo: 2px 8px, radius 3, 10px/700, ls 0.5px).
   Los VALORES PRE-EXISTENTES solid de DsBadge (draft/on-hold/completed/on-track/
   at-risk/delayed/active) NO se voltean globalmente (FD-G) — aquí se re-visten
   SOLO dentro del tracker con override page-scoped. Especificidad (0,3,0)+ para
   ganar a la regla scoped del bundle (.ds-badge--*[b-x] = 0,2,0).
   ============================================================================ */
.tracker-container .tracker-table .ds-badge {
    padding: 2px 8px;
    border-radius: 3px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.5px;
}
.tracker-container .tracker-table .ds-badge:hover { transform: none; }
.tracker-container .tracker-table .ds-badge--status-draft {
    background-color: var(--med-gray-lightest);
    color: var(--med-gray-medium);
}
.tracker-container .tracker-table .ds-badge--status-on-hold {
    background-color: var(--status-warning-bg);
    color: var(--med-yellow-deep);
}
.tracker-container .tracker-table .ds-badge--status-completed {
    background-color: var(--badge-status-complete-bg);
    color: var(--badge-status-complete-text);
}
.tracker-container .tracker-table .ds-badge--status-active,
.tracker-container .tracker-table .ds-badge--status-on-track {
    background-color: var(--status-success-bg);
    color: var(--status-success-deep);
}
.tracker-container .tracker-table .ds-badge--status-at-risk {
    background-color: var(--status-warning-bg);
    color: var(--med-yellow-deep);
    animation: none;
}
.tracker-container .tracker-table .ds-badge--status-delayed {
    background-color: var(--status-error-bg);
    color: var(--status-error-deep);
    animation: none;
}

/* Phase */
.badge-phase { background: #1010EB; color: white; }

/* FY */
.badge-fy { background: #FFCE00; color: black; font-weight: 700; }

/* ABC Codes */
.badge-abc-aplus { background: #7c3aed; color: white; font-weight: 700; }
.badge-abc-a { background: #10b981; color: white; }
.badge-abc-b { background: #3b82f6; color: white; }
.badge-abc-c { background: #94a3b8; color: white; }

/* CDP/SCC Code */
.cdp-code {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.75rem;
    background: #f1f5f9;
    padding: 2px 6px;
    border-radius: 3px;
    color: #475569;
    white-space: nowrap;
}

/* Confidence - for select styling */
.select-confidence-high { background: #f8d7da; }
.select-confidence-medium { background: #fff3cd; }
.select-confidence-low { background: #d4edda; }
.select-confidence-no-chance { background: #e2e3e5; }
.select-confidence-na { background: #f8f9fa; }

/* ===== CHECKLIST STATUS (CDP/SCC, PPAP, GRR/TMV/MSA) ===== */
.select-checklist-not-ready { background: #e2e8f0; color: #475569; }
.select-checklist-development { background: #dbeafe; color: #1e40af; }
.select-checklist-wip { background: #fef3c7; color: #92400e; }
.select-checklist-approved { background: #d1fae5; color: #065f46; }
.select-checklist-drafted { background: #ede9fe; color: #5b21b6; }

/* ===== EXECUTION STATUS (Supplier OQ Pass) ===== */
.select-execution-not-started { background: #f1f5f9; color: #64748b; }
.select-execution-in-progress { background: #dbeafe; color: #1e40af; }
.select-execution-passed { background: #d1fae5; color: #065f46; }
.select-execution-failed { background: #fee2e2; color: #b91c1c; }
.select-execution-no-data { background: #fef3c7; color: #92400e; }

/* ===== DATE CHANGES BADGE ===== */
.badge-date-changes {
    background: #f59e0b;
    color: white;
    padding: 2px 6px;
    border-radius: 10px;
    font-size: 0.7rem;
    font-weight: 700;
}

/* ===== PART/ASSET CODES ===== */
.part-code {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.7rem;
    background: #f1f5f9;
    padding: 2px 4px;
    border-radius: 3px;
    color: #475569;
    white-space: nowrap;
}

/* ===== CURRENCY FORMATTING ===== */
.cell-currency {
    text-align: right;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.8rem;
    color: #059669;
    font-weight: 500;
}

/* ===== PROGRESS BAR ===== */
.progress-bar-container {
    display: flex;
    align-items: center;
    gap: 4px;
    width: 70px;
}

.progress-bar-container.small {
    width: 60px;
}

.progress-bar-fill {
    height: 6px;
    background: #e5e5e5;
    border-radius: 3px;
    flex: 1;
    position: relative;
    overflow: hidden;
}

.progress-bar-fill::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: inherit;
    background: #1010EB;
    border-radius: 3px;
}

.progress-bar-text {
    font-size: 0.7rem;
    color: #666;
    min-width: 28px;
    text-align: right;
}

/* Alternative progress bar implementation */
.progress-bar-container {
    display: flex;
    align-items: center;
    gap: 6px;
}

.progress-bar-container .progress-bar-fill {
    width: 40px;
    height: 6px;
    background: linear-gradient(to right, #1010EB var(--progress, 0%), #e5e5e5 var(--progress, 0%));
    border-radius: 3px;
}

/* ===== PHASE ICONS ===== */
.phase-icon {
    font-size: 0.9rem;
}

/* ===== TOAST ===== */
.toast-success {
    position: fixed;
    top: 20px;
    right: 20px;
    background: #d4edda;
    color: #155724;
    padding: 12px 24px;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    z-index: 2000;
    animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
    from {
        transform: translateX(100%);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

/* Story 11B.05 — warning-style toast for partial saves (some rows skipped/failed). */
.toast-warning {
    position: fixed;
    top: 20px;
    right: 20px;
    background: #FFF4D0;
    color: #7a5b00;
    border: 1px solid var(--med-yellow, #FFCE00);
    padding: 12px 24px;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    z-index: 2000;
    animation: slideIn 0.3s ease-out;
}

/* Story 11B.05 — inline Save spinner (fallback if Bootstrap's .spinner-border is unavailable). */
.spinner-border {
    display: inline-block;
    width: 0.9rem;
    height: 0.9rem;
    vertical-align: -0.125em;
    border: 0.15em solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spinner-border 0.75s linear infinite;
}

.spinner-border-sm {
    width: 0.8rem;
    height: 0.8rem;
    border-width: 0.13em;
}

@keyframes spinner-border {
    to { transform: rotate(360deg); }
}

/* ===== Story 11B.05 — BULK SAVE RESULT SUMMARY MODAL (3 buckets) ===== */
.bulk-result-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 2500;
}

.bulk-result-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(640px, 92vw);
    max-height: 84vh;
    overflow: auto;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 12px 40px rgba(0,0,0,0.25);
    z-index: 2600;
    display: flex;
    flex-direction: column;
}

.bulk-result-modal .modal-header,
.bulk-result-modal .modal-footer {
    display: flex;
    align-items: center;
    padding: 14px 20px;
}

.bulk-result-modal .modal-header {
    border-bottom: 1px solid #e5e7eb;
    justify-content: space-between;
}

.bulk-result-modal .modal-footer {
    border-top: 1px solid #e5e7eb;
    justify-content: flex-end;
}

.bulk-result-modal .modal-body {
    padding: 16px 20px;
}

.bulk-result-headline {
    font-weight: 600;
    margin-bottom: 12px;
}

.bulk-result-bucket {
    margin-bottom: 14px;
}

.bulk-result-bucket .bucket-title {
    font-size: 0.95rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}

.bulk-result-bucket .bucket-count {
    font-family: var(--font-mono, monospace);
    background: #eef0f4;
    border-radius: 9px;
    padding: 1px 9px;
    font-size: 12px;
}

.bucket-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.bucket-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 5px 0;
    border-bottom: 1px dashed #eee;
    font-size: 0.85rem;
}

.bucket-row-project { font-weight: 600; }
.bucket-row-field { font-family: var(--font-mono, monospace); color: #475569; }
.bucket-row-detail { color: #94a3b8; }
.bucket-failed .bucket-count { background: #fde2e1; color: #991b1b; }
.bucket-skipped .bucket-count { background: #fff4d0; color: #7a5b00; }
.bucket-succeeded .bucket-count { background: #d4edda; color: #155724; }

/* ===== UNSAVED CHANGES BAR ===== */
.unsaved-changes-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: linear-gradient(90deg, var(--med-yellow-bg), #FFF4D0);
    border-top: 2px solid var(--med-yellow);
    color: var(--med-yellow-deep);
    font-weight: 600;
    padding: 11px 24px;
    display: flex;
    align-items: center;
    gap: 12px;
    box-shadow: var(--shadow-up);
    z-index: 1000;
}

.unsaved-changes-bar .warning-icon {
    font-size: 1.25rem;
}

/* Pill de conteo (Variant A): mono, fondo amarillo translúcido, texto azul. */
.unsaved-changes-bar .changes-count {
    background: rgba(255, 206, 0, 0.5);
    color: var(--med-blue-primary);
    font-family: var(--font-mono);
    font-weight: 700;
    border-radius: 9px;
    padding: 1px 9px;
    font-size: 11.5px;
}

.unsaved-changes-bar .actions {
    margin-left: auto;
    display: flex;
    gap: 12px;
}

/* ===== BUTTONS ===== */
.btn {
    padding: 8px 16px;
    border-radius: 4px;
    font-weight: 500;
    cursor: pointer;
    border: none;
    font-size: 0.875rem;
    transition: background 0.2s;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-primary {
    background: #1010EB;
    color: white;
}

.btn-primary:hover:not(:disabled) {
    background: #0d0dbd;
}

.btn-secondary {
    background: #e5e5e5;
    color: #333;
}

.btn-secondary:hover:not(:disabled) {
    background: #d4d4d4;
}

.btn-outline-secondary {
    background: transparent;
    border: 1px solid #d4d4d4;
    color: #333;
}

.btn-outline-secondary:hover:not(:disabled) {
    background: #f5f5f5;
}

.btn-outline-primary {
    background: transparent;
    border: 1px solid #1010EB;
    color: #1010EB;
}

.btn-outline-primary:hover:not(:disabled) {
    background: #f0f0ff;
}

/* ===== SCROLLBAR STYLING ===== */
.tracker-table-wrapper::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

.tracker-table-wrapper::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 4px;
}

.tracker-table-wrapper::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 4px;
}

.tracker-table-wrapper::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
}

/* ===== COMMENT INDICATOR ===== */
.comment-indicator-wrapper {
    position: relative;
    display: inline-flex;
}

.comment-indicator {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 6px;
    border: 1px solid #e2e8f0;
    border-radius: 4px;
    background: #f8fafc;
    cursor: pointer;
    transition: all 0.15s ease;
    font-size: 0.75rem;
    color: #64748b;
}

.comment-indicator:hover {
    background: #f1f5f9;
    border-color: #cbd5e1;
}

.comment-indicator.has-comments {
    background: #eff6ff;
    border-color: #bfdbfe;
    color: #3b82f6;
}

.comment-indicator.has-comments:hover {
    background: #dbeafe;
}

.comment-indicator.has-new {
    background: #fef3c7;
    border-color: #fcd34d;
    color: #d97706;
    animation: pulse-new 2s ease-in-out infinite;
}

@keyframes pulse-new {
    0%, 100% { box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.4); }
    50% { box-shadow: 0 0 0 4px rgba(251, 191, 36, 0); }
}

.comment-icon {
    font-size: 0.85rem;
    line-height: 1;
}

.comment-count {
    font-weight: 600;
    font-size: 0.7rem;
}

.comment-new-badge {
    width: 6px;
    height: 6px;
    background: #ef4444;
    border-radius: 50%;
    position: absolute;
    top: -2px;
    right: -2px;
}

/* Size variations */
.comment-indicator.size-sm {
    padding: 2px 5px;
    font-size: 0.7rem;
}

.comment-indicator.size-md {
    padding: 4px 8px;
    font-size: 0.8rem;
}

.comment-indicator.size-lg {
    padding: 6px 10px;
    font-size: 0.9rem;
}

/* Comment Preview (on hover) */
.comment-preview {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    background: #1e293b;
    color: white;
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 0.7rem;
    width: 220px;
    z-index: 100;
    margin-bottom: 6px;
    opacity: 0;
    visibility: hidden;
    transition: all 0.2s ease;
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}

.comment-indicator-wrapper:hover .comment-preview {
    opacity: 1;
    visibility: visible;
}

.comment-preview::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 6px solid transparent;
    border-top-color: #1e293b;
}

.preview-header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 4px;
    font-size: 0.65rem;
    opacity: 0.8;
}

.preview-author {
    font-weight: 600;
}

.preview-text {
    line-height: 1.4;
}

/* ===== COMMENTS MODAL ===== */
.comments-modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    animation: fadeIn 0.2s ease;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.comments-modal {
    background: white;
    border-radius: 12px;
    width: 90%;
    max-width: 520px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
    animation: slideUp 0.25s ease;
}

@keyframes slideUp {
    from { transform: translateY(20px); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
}

.comments-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    border-bottom: 1px solid #e5e7eb;
    background: linear-gradient(135deg, #001E46 0%, #002855 100%);
    border-radius: 12px 12px 0 0;
}

.header-info {
    display: flex;
    align-items: center;
    gap: 12px;
}

.modal-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: white;
    display: flex;
    align-items: center;
    gap: 8px;
}

.context-badge {
    font-size: 0.65rem;
    padding: 2px 8px;
    border-radius: 10px;
    font-weight: 600;
    text-transform: uppercase;
}

.context-project {
    background: #dbeafe;
    color: #1e40af;
}

.context-phase {
    background: #d1fae5;
    color: #065f46;
}

.context-task {
    background: #fef3c7;
    color: #92400e;
}

.close-btn {
    background: transparent;
    border: none;
    color: rgba(255,255,255,0.8);
    cursor: pointer;
    padding: 4px;
    border-radius: 4px;
    transition: all 0.15s ease;
}

.close-btn:hover {
    background: rgba(255,255,255,0.1);
    color: white;
}

.comments-modal-subheader {
    padding: 10px 20px;
    background: #f8fafc;
    border-bottom: 1px solid #e5e7eb;
    display: flex;
    align-items: center;
    gap: 10px;
}

.item-name {
    font-weight: 600;
    color: #1e293b;
    font-size: 0.9rem;
}

.item-id {
    font-size: 0.75rem;
    padding: 2px 6px;
    background: #e2e8f0;
    border-radius: 4px;
    color: #475569;
}

.comments-modal-body {
    flex: 1;
    overflow-y: auto;
    padding: 16px 20px;
    max-height: 350px;
}

.no-comments {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
    color: #94a3b8;
    text-align: center;
}

.no-comments i {
    font-size: 2.5rem;
    margin-bottom: 12px;
    opacity: 0.5;
}

.no-comments p {
    margin: 0;
    font-weight: 600;
    color: #64748b;
}

.no-comments span {
    font-size: 0.85rem;
    margin-top: 4px;
}

.comments-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.comment-item {
    display: flex;
    gap: 12px;
    padding: 12px;
    background: #f8fafc;
    border-radius: 8px;
    border: 1px solid #e5e7eb;
    transition: all 0.15s ease;
}

.comment-item:hover {
    background: #f1f5f9;
}

.comment-item.is-new {
    background: #fffbeb;
    border-color: #fcd34d;
}

.comment-item.legacy {
    background: #f5f5f5;
    border-style: dashed;
}

.comment-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: white;
    flex-shrink: 0;
}

.comment-item.legacy .comment-avatar {
    background: #94a3b8;
}

.comment-content {
    flex: 1;
    min-width: 0;
}

.comment-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
    flex-wrap: wrap;
}

.comment-author {
    font-weight: 600;
    font-size: 0.85rem;
    color: #1e293b;
}

.comment-date {
    font-size: 0.75rem;
    color: #94a3b8;
}

.comment-type-badge {
    font-size: 0.6rem;
    padding: 2px 6px;
    border-radius: 4px;
    font-weight: 600;
}

.comment-type-badge.status {
    background: #dbeafe;
    color: #1e40af;
}

.comment-type-badge.delay {
    background: #fee2e2;
    color: #b91c1c;
}

.comment-type-badge.escalation {
    background: #fef3c7;
    color: #92400e;
}

.comment-type-badge.resolution {
    background: #d1fae5;
    color: #065f46;
}

.new-badge {
    font-size: 0.6rem;
    padding: 1px 5px;
    background: #ef4444;
    color: white;
    border-radius: 3px;
    font-weight: 700;
}

.comment-text {
    font-size: 0.85rem;
    color: #374151;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}

.comments-modal-footer {
    padding: 16px 20px;
    border-top: 1px solid #e5e7eb;
    background: #f8fafc;
    border-radius: 0 0 12px 12px;
}

.new-comment-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.comment-type-selector {
    display: flex;
    gap: 4px;
}

.type-btn {
    padding: 6px 10px;
    border: 1px solid #e2e8f0;
    background: white;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.15s ease;
    font-size: 0.85rem;
}

.type-btn:hover {
    background: #f1f5f9;
}

.type-btn.active {
    background: #001E46;
    color: white;
    border-color: #001E46;
}

.comment-input-wrapper {
    display: flex;
    gap: 8px;
}

.comment-input {
    flex: 1;
    padding: 10px 12px;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    font-size: 0.875rem;
    resize: none;
    font-family: inherit;
    transition: border-color 0.15s ease;
}

.comment-input:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.send-btn {
    padding: 10px 16px;
    background: #001E46;
    color: white;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.15s ease;
}

.send-btn:hover:not(:disabled) {
    background: #002855;
}

.send-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ===== HORIZONTAL SCROLL INDICATORS ===== */
.tracker-table-wrapper {
    position: relative;
}

.tracker-table-wrapper.has-scroll-right::after {
    content: '';
    position: absolute;
    right: 0;
    top: 0;
    bottom: 8px;
    width: 40px;
    background: linear-gradient(to left, rgba(0,0,0,0.08), transparent);
    pointer-events: none;
    z-index: 20;
}

.tracker-table-wrapper.has-scroll-left::before {
    content: '';
    position: absolute;
    left: 520px; /* After frozen columns (checkbox 40 + expand 30 + id 150 + tool 300) — Story 11B.14; tool widened 220→300 (opción B, 2026-07) */
    top: 0;
    bottom: 8px;
    width: 20px;
    background: linear-gradient(to right, rgba(0,0,0,0.05), transparent);
    pointer-events: none;
    z-index: 20;
}

/* UX-DS-05.02 (CB-1.c) — animación scrollHint ELIMINADA. Una animación opacity infinita sobre
   la franja de 40px (sin capa propia) repinta esa región de forma continua, incluso en reposo.
   El gradiente estático de .has-scroll-right::after (arriba) ya comunica "hay más a la derecha". */

/* ================================
   TASK ROWS - UX SPECIFICATION
   Medtronic Design System Compliant
   ================================ */

/* UX-DS-03.03 — filas task al lenguaje variant-A (tr.row-task): tree ├─/└─,
   task-cb span 12px (complete=check verde / progress=dot azul), assignee pill,
   line-through en completadas. Hex tokenizados. */
.task-row {
    background: var(--row-task-bg);
    font-size: 11.5px;
    transition: background-color 150ms ease-out;
}

.task-row td {
    /* UX-DS-03.04 — variant-A tr.row-task td: height 26px + padding 0 12px
       (la altura la fija el token, no el padding vertical). */
    padding: 0 12px;
    height: var(--grid-row-h-task);
    border-bottom: 1px solid var(--grid-line);
    vertical-align: middle;
}

.task-row .frozen {
    background: var(--row-task-bg);
}

.task-row:hover {
    background: var(--row-hover);
}

.task-row:hover .frozen {
    background: var(--row-hover);
}

/* Task Name Cell — indentación variant-A (36px) */
.task-name-cell {
    padding-left: 36px !important;
}

.task-name-content {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Tree-line ├─/└─ (variant-A .task-tree) */
.task-tree {
    font-family: var(--font-mono);
    color: var(--med-gray-light);
    letter-spacing: -0.5px;
    font-size: 0.9rem;
}

/* Checkbox visual (variant-A .task-cb — span, read-only) */
.task-cb {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 1.4px solid var(--med-gray-lighter);
    border-radius: 2px;
    background: var(--bg-white);
    position: relative;
    flex-shrink: 0;
}

.task-cb.complete {
    background: var(--status-success);
    border-color: var(--status-success);
}

.task-cb.complete::after {
    content: "";
    position: absolute;
    top: 0;
    left: 3px;
    width: 3px;
    height: 7px;
    border: solid var(--bg-white);
    border-width: 0 1.6px 1.6px 0;
    transform: rotate(45deg);
}

.task-cb.progress {
    background: var(--bg-white);
    border-color: var(--med-blue-interactive);
}

.task-cb.progress::after {
    content: "";
    position: absolute;
    top: 1px;
    left: 1px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--med-blue-interactive);
}

/* Task name text */
.task-name-text {
    color: var(--med-gray-medium);
    font-weight: 500;
    line-height: 1.3;
}

/* Completada = line-through + gris (variant-A tr.row-task.task-complete .task-name) */
.task-row.task-complete .task-name-text {
    color: var(--med-gray-light);
    text-decoration: line-through;
}

/* Assignee pill + avatar (variant-A .task-assignee / .av) */
.task-assignee {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 10.5px;
    background: var(--bg-white);
    border: 1px solid var(--grid-line);
    border-radius: 10px;
    padding: 1px 7px 1px 4px;
    color: var(--med-blue-medium);
    font-weight: 600;
    white-space: nowrap;
}

.task-assignee .av {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--med-blue-medium), var(--med-blue-interactive));
    color: var(--text-inverse);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    font-weight: 700;
    flex-shrink: 0;
}

/* Optional badge */
.task-optional-badge {
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    padding: 1px 6px;
    border-radius: 3px;
    background: rgba(255, 193, 7, 0.15);
    color: #856404;
    border: 1px solid rgba(255, 193, 7, 0.3);
    flex-shrink: 0;
}

/* Status badges */
.task-status-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 0.6875rem;
    font-weight: 500;
    white-space: nowrap;
    min-width: 70px;
    transition: transform 100ms ease;
}

.task-row:hover .task-status-badge {
    transform: scale(1.02);
}

.task-badge-pending {
    background: #E9ECEF;
    color: #6C757D;
}

.task-badge-active {
    background: #17A2B8;
    color: #FFFFFF;
}

.task-badge-complete {
    background: #28A745;
    color: #FFFFFF;
}

.task-badge-skipped {
    background: #FFC107;
    color: #3C3C3C;
}

/* Row status variations — UX-DS-03.03: variant-A unifica el bg de task rows;
   el estado vive en el task-cb + line-through (tr.row-task.task-complete .task-name). */
.task-row.task-complete .task-name-text {
    color: var(--med-gray-light);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.task-row.task-complete .frozen {
    background: var(--row-task-bg);
}

.task-row.task-in-progress {
    background: var(--row-task-bg);
}

.task-row.task-in-progress .frozen {
    background: var(--row-task-bg);
}

.task-row.task-skipped {
    opacity: 0.6;
}

.task-row.task-skipped .task-name-text {
    text-decoration: line-through;
    color: var(--med-gray-light);
}

/* Metadata cells */
.task-assigned-cell {
    font-size: 0.75rem;
    color: #555555;
}

.task-date-cell {
    font-size: 0.75rem;
    color: #555555;
    font-variant-numeric: tabular-nums;
}

/* Task ID */
.task-id {
    font-size: 0.6875rem;
    color: #979797;
    font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
}

/* Focus state for accessibility */
.task-row:focus-within {
    outline: 2px solid #1010EB;
    outline-offset: -2px;
}

/* Status cell */
.task-status-cell {
    min-width: 90px;
}

/* ===== Story 11B.14 (Q9) — Frozen ProjectDisplayId + responsive System-IDs collapse ===== */

/* "Intake" warning chip in the frozen ProjectDisplayId cell (pre-transition: ProjectCode == null).
   This story OWNS the chip; 11B.16 reuses .badge-intake-warning. Text + icon + aria carry meaning
   (not color alone). Token --warning-100 with an amber fallback. */
.tracker-table .badge-intake-warning {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    margin-left: 6px;
    background: var(--warning-100, #fff3cd);
    color: var(--warning-700, #8a6d00);
    border: 1px solid var(--warning-300, #ffe08a);
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .02em;
    padding: 1px 6px;
    border-radius: 10px;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
}
.tracker-table .badge-intake-warning .bi { font-size: .68rem; }

/* The two secondary system-id columns + the collapsed dropdown column. Each ID is a read-only
   <code> token. The columns themselves are scrollable (NOT frozen). */
.tracker-table .col-intake-form-id,
.tracker-table .col-project-code { min-width: 130px; white-space: nowrap; }
.tracker-table .id-code {
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: .8rem;
    color: var(--med-blue-primary, #170f5f);
}

/* Avoid per-row layout shift when toggling the responsive dropdown popover. */
.tracker-table .ids-system-dropdown { contain: layout; transition: width 200ms ease; }
.ids-popover-wrapper { position: relative; display: inline-block; }
.ids-popover-trigger {
    background: none;
    border: none;
    padding: 2px 6px;
    cursor: pointer;
    color: var(--med-blue-interactive, #0077c8);
}
.ids-popover-panel {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 30;
    min-width: 200px;
    margin-top: 4px;
    padding: 8px 10px;
    background: #fff;
    border: 1px solid var(--grid-line, #dee2e6);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0,0,0,.16);
}
.ids-popover-list { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; }
.ids-popover-list dt { font-size: .7rem; color: var(--med-gray-medium, #6c757d); font-weight: 600; }
.ids-popover-list dd { margin: 0; font-size: .8rem; }

/* Responsive collapse (decision log §Q9): below 1440px hide the two independent ID columns and show
   the single dropdown column; at >=1440px do the inverse. Header + project cells flip together so the
   column count change is by VIEWPORT only (no per-row layout shift). */
@media (max-width: 1439px) {
    .tracker-table .col-intake-form-id,
    .tracker-table .col-project-code { display: none; }
    .tracker-table .ids-system-dropdown { display: table-cell; }
}
@media (min-width: 1440px) {
    .tracker-table .ids-system-dropdown { display: none; }
}

/* ============================================================================
   Story 11B.18 (FD-07) — MoldCell + MoldPopover (single scalar mold)
   Read-only display column + right-side slide-in drawer. The multi-mold badge
   and the IsFinalAsset star are DEFERRED (no scalar backs them) — not styled.
   ============================================================================ */

.tracker-table .col-mold {
    min-width: 140px;
    max-width: 220px;
}

/* Empty (no scalar mold) — selectable em-dash, matches the EmDashWithTooltip look. */
.mold-cell-empty {
    color: var(--med-gray-medium, #999);
    user-select: text;
}

/* Single mold — clickable inline chip. */
.mold-cell-single {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    max-width: 100%;
    padding: 2px 6px;
    border: none;
    border-radius: 4px;
    background: transparent;
    cursor: pointer;
    font: inherit;
    text-align: left;
    color: inherit;
    transition: background 0.15s ease;
}

.mold-cell-single:hover,
.mold-cell-single:focus-visible {
    /* repo has no --primary-50; --row-hover (#F0F4F9) is the project's light primary tint. */
    background: var(--row-hover, #F0F4F9);
    outline: none;
}

.mold-cell-icon {
    color: var(--med-blue-primary, #001E46);
    font-size: 0.85rem;
    flex: 0 0 auto;
}

.mold-cell-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mold-cell-asset {
    font-size: 0.72rem;
    color: var(--med-gray-medium, #777);
    flex: 0 0 auto;
}

/* ---- Drawer ---- */
.mold-popover-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.25);
    z-index: 1050;
}

.mold-popover-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 360px;
    max-width: 90vw;
    background: #fff;
    box-shadow: -4px 0 18px rgba(0, 0, 0, 0.18);
    z-index: 1051;
    display: flex;
    flex-direction: column;
    animation: mold-popover-slide-in 0.2s ease;
}

@keyframes mold-popover-slide-in {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
}

.mold-popover-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    background: var(--med-blue-primary, #001E46);
    color: #fff;
}

.mold-popover-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
}

.mold-popover-close {
    border: none;
    background: transparent;
    color: #fff;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 4px;
}

.mold-popover-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 18px;
}

.mold-popover-fields {
    margin: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px 0;
}

.mold-popover-fields dt {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--med-gray-medium, #777);
    margin-top: 12px;
}

.mold-popover-fields dt:first-child {
    margin-top: 0;
}

.mold-popover-fields dd {
    margin: 0;
    font-size: 0.95rem;
    color: var(--text-primary, #222);
}

.mold-popover-status-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 12px;
    font-size: 0.78rem;
    font-weight: 600;
    background: var(--row-hover, #F0F4F9);
    color: var(--med-blue-primary, #001E46);
}

.mold-popover-empty {
    color: var(--med-gray-medium, #999);
}

/* ============================================================================
   Story 11B.19 (FD-07) — MoldExpandInlinePreview (single scalar mold, read-only)
   Rendered by 11B.17's BulkConfirmationModal under each affected project row when
   a bulk edit touches a scalar mold field. Shows Current → New for the affected
   field; the new value is highlighted. The N-mold sub-table and SameSupplier /
   IsFinalAsset-max-1 warnings are DEFERRED (no scalar backs them) — not styled.
   ============================================================================ */

.mold-inline-preview {
    font-size: 0.85rem;
}

.mold-inline-preview-header {
    display: flex;
    align-items: center;
}

.mold-inline-expand-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 2px 4px;
    font: inherit;
    color: var(--med-blue-primary, #001E46);
}

.mold-inline-expand-toggle:hover,
.mold-inline-expand-toggle:focus-visible {
    background: var(--row-hover, #F0F4F9);
    outline: none;
    border-radius: 4px;
}

.mold-inline-chevron {
    font-size: 0.7rem;
    flex: 0 0 auto;
}

.mold-inline-project-id {
    font-weight: 600;
}

.mold-inline-preview-body {
    padding: 8px 10px 8px 26px;
}

.mold-inline-empty {
    color: var(--med-gray-medium, #999);
}

.mold-inline-fields {
    margin: 0;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 14px;
    align-items: baseline;
}

.mold-inline-fields dt {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--med-gray-medium, #777);
}

.mold-inline-fields dd {
    margin: 0;
    color: var(--text-primary, #222);
}

.mold-inline-change {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.mold-inline-current {
    color: var(--med-gray-medium, #777);
}

.mold-inline-arrow {
    color: var(--med-gray-medium, #777);
    flex: 0 0 auto;
}

/* Highlight the changed (post-bulk) value. Token --warning-50 with an amber fallback;
   repo defines --warning-100/300/700 (see badge-intake-warning) but not --warning-50. */
.mold-inline-new {
    background: var(--warning-50, #fff8e1);
    color: var(--warning-700, #8a6d00);
    border: 1px solid var(--warning-300, #ffe08a);
    padding: 1px 6px;
    border-radius: 4px;
    font-weight: 600;
}

.mold-popover-footer {
    padding: 14px 18px;
    border-top: 1px solid #e5e5e5;
}

.mold-popover-detail-link {
    color: var(--med-blue-primary, #001E46);
    font-weight: 600;
    text-decoration: none;
}

.mold-popover-detail-link:hover {
    text-decoration: underline;
}

/* ============================================================================
   Story 11B.11 (FD) — RESPONSIVE ADJUSTMENTS
   CSS-first. Goal: grid usable on a 1366px laptop and on tablets, without
   breaking the dense desktop layout or the existing breakpoints.

   Coexistence with 11B.14:
     • 11B.14 owns the <1440px ID-block collapse (line ~2014): it hides
       .col-intake-form-id + .col-project-code and shows .ids-system-dropdown.
       Nothing below re-declares those selectors, so the collapse keeps working.
     • The frozen sticky offsets (.col-checkbox 0 / .col-expand 40 / .col-id 70 /
       .col-tool 220, width 300) and the scroll-shadow ::before left:520px are NOT changed
       here — they stay exact at every width, so frozen columns never overlap
       the scrollable content (AC1/AC2).
   ============================================================================ */

/* --- AC1: Horizontal scroll at 1366px (standard laptop) -------------------- */
/* The wrapper already has overflow:auto and the table is width:max-content, so
   horizontal scrolling exists at any width. At <=1366px we make the scrollbar
   touch-/trackpad-friendly and force momentum scrolling on iOS, and we keep the
   frozen offsets verbatim (no re-declaration) so the sticky columns stay put. */
@media (max-width: 1366px) {
    .tracker-table-wrapper {
        -webkit-overflow-scrolling: touch; /* momentum scroll on iOS/iPadOS */
        scrollbar-width: thin;
    }

    .tracker-table-wrapper::-webkit-scrollbar {
        height: 10px;
    }
}

/* --- AC4: Pagination controls stay accessible at narrow widths -------------- */
/* The .pagination-bar already declares flex-wrap:wrap (inline in ProjectTracker
   .razor <style>); below 768px we stack it into a centred column so no control
   overflows off-screen. Selector is global so it reaches the inline-styled bar. */
@media (max-width: 767px) {
    .pagination-bar {
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
    }

    .pagination-bar .pagination-controls {
        justify-content: center;
    }
}

/* --- AC3: Touch-friendly row height + 44px tap targets on tablets ---------- */
/* Applied under a coarse pointer (tablets/touch laptops). Bumps the interactive
   targets (checkboxes, the expand chevron, filter selects/inputs, buttons) to a
   ~44px minimum WITHOUT touching .project-row td height for fine-pointer desktop,
   so the dense desktop layout is preserved. font-size:16px on inputs avoids the
   iOS focus-zoom. */
@media (pointer: coarse) {
    .expand-btn {
        min-width: 44px;
        min-height: 44px;
    }

    .tracker-filters .filter-group select,
    .tracker-filters .filter-group input {
        min-height: 44px;
        font-size: 16px;
    }

    .tracker-filters .filter-group input[type="checkbox"],
    .tracker-table .row-checkbox,
    .tracker-table input[type="checkbox"] {
        width: 20px;
        height: 20px;
    }

    .pagination-bar .pagination-btn,
    .tracker-actions .btn {
        min-height: 44px;
    }
}

/* Tablet-width fallback for devices that don't report pointer:coarse — the same
   44px targets apply between 768px and 1024px (iPad portrait/landscape). */
@media (min-width: 768px) and (max-width: 1024px) {
    .tracker-filters .filter-group select,
    .tracker-filters .filter-group input {
        min-height: 44px;
    }

    .expand-btn {
        min-width: 44px;
        min-height: 44px;
    }
}

/* --- AC2 (narrow): Filters stack vertically below 768px -------------------- */
/* The .tracker-filters flex row becomes a single column; each control and its
   group go full width so nothing is cut off on a phone/narrow split-screen. */
@media (max-width: 767px) {
    .tracker-filters {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    .tracker-filters .filter-group {
        width: 100%;
    }

    .tracker-filters .filter-group select,
    .tracker-filters .filter-group input,
    .tracker-filters .filter-group.search input {
        width: 100%;
        min-width: 0;
    }

    .tracker-filters .filter-count {
        margin-left: 0;
    }
}

/* --- AC5: Epic-34 column configurator modal scrollable on small screens ---- */
/* The configurator (.cc-modal / .cc-body) is an Epic 34 component — its markup is
   NOT touched here. .cc-modal already caps at max-height:86vh and .cc-body is
   overflow-y:auto, so it scrolls; below 768px we collapse the two-pane grid into
   one column (so the Available/Visible panes stack instead of squeezing) and
   tighten padding. Purely a CSS override against the component's global classes. */
@media (max-width: 767px) {
    .cc-modal {
        width: 96vw;
        max-height: 90vh;
    }

    .cc-body {
        grid-template-columns: 1fr;
        max-height: 70vh;
        overflow-y: auto;
    }
}
