/* Copyright (c) 2026 Oleksii Mykhalevych */

/* Audit-trail modal stacking & sizing.
   The audit modal is an ngx-bootstrap (BsModalService) modal opened from the
   project card. ngx-bootstrap puts the config `class` only on the inner
   `.modal-dialog`, while the outer `.modal` container (default z-index 1050)
   and the separate `.modal-backdrop` (default 1040) carry no per-modal class.
   The project card above sits at 11050/11049, so the audit modal must clear it.
   These global rules can't live in the view-encapsulated component CSS, which
   cannot reach `.modal` / `.modal-backdrop`. The container is matched via the
   dialog it wraps; the backdrop is matched as the sibling that precedes it
   (BsModalService attaches the backdrop to <body> right before the container). */
.modal:has(> .modal-dialog.project-audit-modal-dialog) {
    z-index: 11070 !important;
}

.modal-backdrop:has(+ .modal > .modal-dialog.project-audit-modal-dialog) {
    z-index: 11060 !important;
}

/* Centering (#2): the app has a fixed 90px left navigation panel (.mainNav,
   width:90px in css/layout/navigationShell.css). The dialog must be centred
   inside the CONTENT area to the RIGHT of that panel, i.e. its horizontal
   center is navWidth + (100vw - navWidth)/2 — shifted right of the viewport
   centre — with balanced left/right margins inside the content area and never
   overlapping the nav.

   Dialog width is ~80% of the content-area width (capped at 1400px) so the
   centring is visibly inset; equal margins are placed on both sides of the
   content area:
     content width = 100vw - navWidth
     dialog width  = min(80% * content width, 1400px)
     margin-left   = navWidth + (content width - dialog width) / 2
   margin-right:auto balances the remainder. */
.modal:has(> .modal-dialog.project-audit-modal-dialog) {
    --side-panel-width: 90px;
    --audit-content-width: calc(100vw - var(--side-panel-width));
    --audit-dialog-width: min(calc(var(--audit-content-width) * 0.8), 1400px);
}

.modal-dialog.project-audit-modal-dialog {
    width: var(--audit-dialog-width);
    max-width: var(--audit-dialog-width);
    margin-left: calc(
        var(--side-panel-width) + (var(--audit-content-width) - var(--audit-dialog-width)) / 2
    );
    margin-right: auto;
    /* #1: push the dialog ~50px down from the default vertical position. */
    margin-top: 80px;
}

/* Speed up open + backdrop fade (#8). ngx-bootstrap's default modal/backdrop
   transitions feel slow, especially over Remote Desktop; collapse them to near
   instant for this modal and its backdrop. (Open is also requested with
   animated:false in projectInfo.controller.ts openAuditModal.) */
.modal.fade:has(> .modal-dialog.project-audit-modal-dialog),
.modal.fade:has(> .modal-dialog.project-audit-modal-dialog) .modal-dialog {
    transition: none !important;
}

.modal-backdrop.fade:has(+ .modal > .modal-dialog.project-audit-modal-dialog) {
    transition: none !important;
}

/* ROOT CAUSE of the User-filter dropdown X/Y offset: Bootstrap applies
   `.modal.fade .modal-dialog { transform: translate(0,-25%) }` and, while the
   modal is open, `.modal.in .modal-dialog { transform: translate(0,0) }`. A
   non-`none` transform turns `.modal-dialog` into the containing block for its
   `position: fixed` descendants, so the custom-dropdown panel (position:fixed,
   coordinates taken from the input's getBoundingClientRect viewport rect) is
   re-based to the dialog's top-left instead of the viewport — shifting it on
   BOTH axes. The Group Task List filter works because its header has no
   transformed ancestor. Neutralize the transform for this dialog so fixed
   positioning is viewport-relative again and the panel opens flush beneath the
   input, exactly like the Group Task List. (Layout is unaffected — the dialog is
   positioned via margins above, not the transform.) */
.modal-dialog.project-audit-modal-dialog,
.modal.fade .modal-dialog.project-audit-modal-dialog,
.modal.in .modal-dialog.project-audit-modal-dialog {
    transform: none !important;
}

/* ============================================================================
   Audit-trail modal CONTENT styling (#5).

   Why this lives here (global) and NOT in the component CSS:
   The audit modal is an ngx-bootstrap modal rendered at <body>. Its component
   stylesheet uses ViewEncapsulation.Emulated, so every selector is rewritten to
   require the component's generated _ngcontent attribute. That attribute is NOT
   present on the embedded reusable controls (custom-dropdown renders its own
   DOM; angular-mydatepicker appends its calendar to <body>), so encapsulated
   rules cannot reach/theme them. Authoring the styling here — in a globally
   loaded stylesheet (config/index.html) — guarantees it reaches every element,
   matching the group-task-list / pipeline2 visual idioms (GlowRegular/
   GlowSemiBold, #4a4a4a/#808080/#b6b6b6, #dcdcdc/#f1f1f1 borders, 28px control
   height, 4px radius, --link-blue accents).
   ========================================================================== */

/* Grid template shared by the header and every body row, declared on the COMPONENT
   HOST element (<ef-project-audit-modal>) — the same element the resize logic writes
   --at-cols to (component.hostEl). The header/rows read `grid-template-columns:
   var(--at-cols)` and inherit it from here, so the live value the JS sets always wins.
   It MUST stay on the host (an ancestor of .project-audit-modal): if the default were
   declared lower, on .project-audit-modal itself, that copy would sit BETWEEN the host
   and the grid rows and shadow the JS-written value, freezing column widths on resize.
   9 columns: When · Who · Operation · Type · Object · Change · Field · Before · After.
   The 8 leading columns are fixed px; the last (After) is minmax(150px, 1fr) so it fills any
   slack up to the dialog's right edge — leaving NO blank area after After when the dialog is
   wider than the fixed columns (e.g. at the clamp's 50vw floor). The window width is recomputed
   from the column total on every resize, and After's right edge follows the dialog edge (#11). */
ef-project-audit-modal {
    --at-cols: 90px 120px 120px 80px 150px 100px 180px 120px minmax(150px, 1fr);
}

.project-audit-modal {
    /* Group Task List custom properties so var(--link-blue) etc. resolve inside the
       body-rendered modal (these are page-scoped to .mt-container in myTasks.css). */
    --link-blue: #5774e7;
    --main-text-color: #4a4a4a;
    --border-line: 1px solid #dcdcdc;

    /* Change-history design tokens (exact, per spec). */
    --at-title: #23262e;
    --at-ink: #2a2d34;
    --at-text: #5a6069;
    --at-muted: #6b7280;
    --at-muted-2: #9499a4;
    --at-muted-3: #9aa0ab;
    --at-ref: #aab0bb;
    --at-dash: #cdd1da;
    --at-divider: #ecedf2;
    --at-rowline: #f1f2f5;
    /* Ledger separator hierarchy (graded grays, all drawn at 1px so grid rows stay aligned —
       the visual weight comes from colour contrast). Transaction = strongest (darkest),
       object = normal, change-kind sub-boundary = lighter than object, field = lightest. */
    --at-bd-tx: #c9cdd6;
    --at-bd-object: #dcdee4;
    --at-bd-kind: #e4e6eb;
    --at-bd-field: #eceef2;
    --at-chip: #f0f1f4;
    --at-fieldbd: #d8dae1;
    --at-primary: #2f6fed;
    --at-primary-hov: #2861d8;

    display: flex;
    flex-direction: column;
    width: 100%;
    /* Fixed height (not max-height) so the dialog stays the same size across the
       loading -> loaded transition. The body (flex:1 1 auto; overflow:hidden) and the
       table wrapper (flex:1 1 auto; overflow:auto) fill and scroll inside this constant
       height, so the loading, empty, error and table states all occupy the same box. */
    height: calc(100vh - 110px);
    font-family: GlowRegular;
    color: var(--main-text-color);
}

.project-audit-modal .modal-header {
    display: flex;
    align-items: center;
    gap: 11px;
    border-bottom: 1px solid var(--at-divider);
    /* Explicit symmetric inset: padding-top and padding-right are both 15px so the close
       button's top gap and right gap from the modal corner are identical. padding-bottom is
       trimmed to 14px for a tighter look; left stays at Bootstrap's default 15px. */
    padding-top: 15px;
    padding-right: 15px;
    padding-bottom: 14px;
}

.project-audit-modal .modal-title {
    font-family: GlowSemibold;
    font-size: 16px;
    font-weight: 700;
    color: var(--at-title);
    margin: 0;
}

/* Neutral object chip beside the title (must NOT compete with the title). */
.project-audit-modal .project-audit-chip {
    padding: 3px 10px;
    border-radius: 6px;
    background: var(--at-chip);
    /* #3: black text (was --at-muted / #6b7280). */
    color: #1a1a1a;
    font-family: GlowRegular;
    font-weight: 500;
    font-size: 12.5px;
    white-space: nowrap;
}

/* Header close (the only close control — no footer button).
   Positioning: taken out of the flex flow and pinned to the top-right corner of
   .modal-content (the nearest position:relative ancestor), so it sits exactly
   10px from the top and 10px from the right at any modal width.
   z-index:1 keeps it clickable above the header flex content. */
.project-audit-modal .project-audit-close {
    position: absolute;
    top: 10px;
    right: 10px;
    margin: 0;
    z-index: 1;
    width: 34px;
    height: 34px;
    border: none;
    background: transparent;
    color: var(--at-muted-2);
    font-size: 20px;
    line-height: 1;
    border-radius: 6px;
    cursor: pointer;
    padding: 0;
}

.project-audit-modal .project-audit-close:hover {
    background: #f2f3f6;
    color: var(--at-text);
}

.project-audit-modal .modal-body {
    flex: 1 1 auto;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    /* Remove the white gap between the header divider and the #FAFBFC filter strip:
       Bootstrap's .modal-body adds 15px padding-top; zeroing it here lets the filter
       strip start immediately below the header divider. The filter strip's own
       padding-top:14px keeps the field controls off the divider. */
    padding-top: 0;
}

/* Filters: one row, auto-apply (no Apply button). Left padding matches the table row
   left inset (14px) so the From label aligns with the When column and the title.
   #5: The filter-strip background and its bottom border (the filter/table separator)
   must reach the modal card's left and right edges. Bootstrap's .modal-body adds
   15px padding on each side, which would inset the strip. Negative horizontal margins
   of -15px cancel that inset so the div bleeds to the card edges; compensating inner
   padding of 15px + original 14px = 29px on the left (and 15px on the right) keeps
   the actual filter-field controls at the same visual position as before.
   The border-bottom here (moved from border-top on .project-audit-head) becomes the
   filter/table separator; it now runs edge-to-edge because the element is full-width. */
.project-audit-modal .project-audit-filters {
    display: flex;
    align-items: flex-end;
    gap: 14px;
    flex-wrap: nowrap;
    /* #5: bleed to card edges. */
    margin-left: -15px;
    margin-right: -15px;
    padding-top: 14px;
    padding-bottom: 14px;
    padding-left: 29px;  /* 15px body-padding + 14px original = same visual position */
    padding-right: 15px;
    background-color: #FAFBFC;
    /* #5: filter/table separator drawn here (moved from border-top on .project-audit-head)
       so it runs edge-to-edge. */
    border-bottom: 1px solid var(--at-divider);
}

.project-audit-modal .project-audit-filters__field {
    display: flex;
    flex-direction: column;
    font-size: 13px;
    color: var(--main-text-color);
}

/* Filter labels: Title case, not uppercase. */
.project-audit-modal .project-audit-filters__field > label {
    margin-bottom: 5px;
    font-family: GlowSemibold;
    font-weight: 600;
    font-size: 12.5px;
    letter-spacing: 0.02em;
    color: var(--at-muted-2);
}

/* Shared control look across the plain text inputs, the datepicker input and the dropdown input. */
.project-audit-modal .project-audit-filters__field input[type='text'],
.project-audit-modal .project-audit-filters__field--date .customDatepicker__container .datepicker,
.project-audit-modal .project-audit-filters__field .customDropdown .ui-input-bordered {
    height: 32px;
    padding: 0 10px;
    border: solid 1px var(--at-fieldbd);
    border-radius: 6px;
    font-family: GlowRegular;
    font-size: 13px;
    color: var(--main-text-color);
    background-color: #ffffff;
    outline: none;
    box-sizing: border-box;
}

.project-audit-modal .project-audit-filters__field input[type='text']:focus,
.project-audit-modal .project-audit-filters__field--date .customDatepicker__container .datepicker:focus,
.project-audit-modal .project-audit-filters__field .customDropdown .ui-input-bordered:focus {
    border: 1px solid var(--at-primary);
}

.project-audit-modal .project-audit-filters__field input[type='text']::placeholder {
    font-family: GlowRegular;
    font-size: 13px;
    color: #b6b6b6;
}

/* Search: fixed width, does not stretch. Width widened by 30% (220px → 286px). */
.project-audit-modal .project-audit-filters__field--search {
    flex: 0 0 286px;
}

.project-audit-modal .project-audit-filters__field--search input[type='text'] {
    width: 286px;
}

/* Date field: the shared datepicker in its standard configuration (isCalendarIconShown
   default = true), so it carries the app's built-in PNG calendar icon at the right edge,
   identical to every other date filter in the app. */
.project-audit-modal .project-audit-date {
    position: relative;
    width: 112px;
}

.project-audit-modal .project-audit-date .customDatepicker__container .datepicker {
    width: 112px;
    cursor: pointer;
    padding-right: 30px;
    margin-left: 0;
}

.project-audit-modal .project-audit-filters__field--user {
    width: 146px;
}

.project-audit-modal .project-audit-filters__field--user .customDropdown {
    width: 146px;
}

.project-audit-modal .project-audit-filters__actions {
    display: flex;
    align-items: flex-end;
}

/* Apply: solid brand-blue button (spec A2). */
.project-audit-modal .project-audit-apply {
    padding: 8px 22px;
    background: var(--at-primary);
    color: #ffffff;
    border: none;
    border-radius: 6px;
    font-family: GlowSemibold;
    font-weight: 600;
    font-size: 13px;
    box-shadow: 0 1px 2px rgba(47, 111, 237, 0.3);
    cursor: pointer;
}

.project-audit-modal .project-audit-apply:hover {
    background: var(--at-primary-hov);
}

.project-audit-modal .project-audit-apply[disabled] {
    opacity: 0.5;
    cursor: default;
}

/* States (kept; rendered inline, not as a persistent banner). */
.project-audit-modal .project-audit-state {
    padding: 24px;
    text-align: center;
    color: #b6b6b6;
}

.project-audit-modal .project-audit-state--error {
    color: #ec4a43;
}

/* Table scroller: vertical scroll + horizontal overflow when total columns exceed 90vw (#11).
   Row border-top separators are intentionally content-inset (NOT full modal width) — only
   the filter/table separator (border-bottom on .project-audit-filters) spans edge-to-edge.
   The wrapper sits inside Bootstrap's .modal-body 15px horizontal padding so the table
   content inset is preserved without any margin/padding compensation. */
.project-audit-modal .project-audit-table-wrapper {
    flex: 1 1 auto;
    overflow: auto;
    overflow-x: auto;
    /* Firefox: thin, unobtrusive scrollbars. */
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, 0.18) transparent;

    padding-right: 10px;   /* gap between last column area and vertical scrollbar */
    padding-bottom: 16px;  /* gap between last row/table text and horizontal scrollbar */
    box-sizing: border-box;
}

/* Webkit (Chrome/Edge/Safari): thin, light, rounded scrollbars. */
.project-audit-modal .project-audit-table-wrapper::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

.project-audit-modal .project-audit-table-wrapper::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.18);
    border-radius: 4px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.project-audit-modal .project-audit-table-wrapper::-webkit-scrollbar-thumb:hover {
    background: rgba(0, 0, 0, 0.30);
    border-radius: 4px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.project-audit-modal .project-audit-table-wrapper::-webkit-scrollbar-track {
    background: transparent;
}

.project-audit-modal .project-audit-table-wrapper::-webkit-scrollbar-corner {
    background: transparent;
}

/* Inner track: holds the shared grid template var and the drag guide.
   Column sum: 90+120+120+80+150+100+180+120+150 = 1110px (initial default).
   JS keeps min-width in sync with the actual column total on every resize (#11). */
.project-audit-modal .project-audit-track {
    min-width: 1110px;
    position: relative;

    padding-right: 10px;   /* gap after last column before vertical scrollbar */
    padding-bottom: 16px;  /* safe area above horizontal scrollbar on macOS */
    box-sizing: content-box;
}

/* Bottom safe area so the horizontal scrollbar does not overlay the last row on macOS. */
.project-audit-modal .project-audit-track::after {
    content: "";
    display: block;
    height: 18px;
}


/* Zero-height sticky host for the floating twins; sticks at the same top line as the header,
   below it in stacking order. Inside the horizontally-scrollable track, so twins ride
   horizontal scroll with the columns (no -scrollLeft needed). */
.project-audit-modal .project-audit-context-layer {
    position: sticky;
    top: 0;
    height: 0;
    overflow: visible;
    z-index: 1;            /* header is z-index: 2 -> twins slide UNDER the header */
    pointer-events: none;
}

/* A twin is a mini-grid replicating its level's columns; cloned cells stay column-aligned.
   White plate so text stays readable; grows downward only. grid-template-columns/left/width set by JS.
   The combined-class display rules use three-class specificity (.project-audit-row.project-audit-twin)
   so they always win over the two-class .project-audit-row { display:grid } rule regardless of
   source order — the twin must be hidden/shown by JS, not inherited from .project-audit-row. */
.project-audit-modal .project-audit-twin {
    position: absolute;
    top: 0;
}
.project-audit-modal .project-audit-row.project-audit-twin {
    display: none;          /* shown as grid by JS when its level is pinned */
}
.project-audit-modal .project-audit-row.project-audit-twin.is-visible {
    display: grid;
}
/* Twin geometry (left/width) is measured from the real header cells, which already include the
   row's 14px left inset; null out the row-level padding here so it isn't applied a second time.
   The cloned cells keep their own .project-audit-cell padding (separate rule). */
.project-audit-modal .project-audit-row.project-audit-twin {
    padding: 0;
}

/* Header + every row share the same grid template, so they reflow together on resize.
   Left padding is 14px (the shared left inset — aligns When, filters and title).
   Right padding is 10px for the After column's right edge. */
.project-audit-modal .project-audit-head,
.project-audit-modal .project-audit-row {
    display: grid;
    grid-template-columns: var(--at-cols);
    padding: 0 10px 0 14px;
}

.project-audit-modal .project-audit-head {
    position: sticky;
    top: 0;
    background: #ffffff;
    z-index: 2;
    /* #5: border-top (the filter/table separator) was moved to border-bottom on
       .project-audit-filters so it now runs edge-to-edge. Only border-bottom remains
       here (the head/body divider). The vertical hover dividers on header cells
       start at the border-bottom edge, which has no gap. */
    border-bottom: 1px solid var(--at-divider);
    font-family: GlowSemibold;
    font-weight: 700;
    font-size: 13px;
    color: var(--at-muted);
}

.project-audit-modal .project-audit-head .project-audit-cell {
    position: relative;
    padding: 11px 10px;
    box-sizing: border-box;
    border-left: 1px solid transparent;
    border-right: 1px solid transparent;
}

.project-audit-modal .project-audit-head .project-audit-cell:hover {
    border-left-color: #d3d6de;
    border-right-color: #d3d6de;
}

.project-audit-modal .project-audit-head .project-audit-cell--when:hover {
    border-left-color: transparent;
}

.project-audit-modal .project-audit-head .project-audit-cell--when {
    padding-left: 0;
}

/* Body rows: NO base full-width separator. Horizontal separators are drawn per boundary
   level (transaction / object / field) on SPECIFIC cells only — see the ledger-separator
   block below — so the collapsed When/Who/Operation (and, for field boundaries, the
   collapsed Type/Object/Change) cells are never crossed by a line.
   Base row text reads at the app's standard 14px GlowRegular (inherited from
   .project-audit-modal); genuinely secondary tokens (date line, #id) stay smaller. */
.project-audit-modal .project-audit-row {
    font-size: 14px;
}

.project-audit-modal .project-audit-row .project-audit-cell {
    padding: 8px 10px;
    display: flex;
    align-items: center;
    min-width: 0;
    background: transparent;
}


.project-audit-modal .project-audit-row .project-audit-cell--when {
    padding-left: 0;
}

/* Cell content lives in an inner span: a twin's white plate hugs the content (content height) and
   never covers the row separators, which stay on the full-height cell. Same structure in rows and
   twins, so a cloned twin cell is pixel-identical to the inline cell. */
.project-audit-modal .project-audit-cell-inner {
    display: inline-flex;
    align-items: center;
    min-width: 0;
}
.project-audit-modal .project-audit-cell--when .project-audit-cell-inner {
    flex-direction: column;
    align-items: flex-start;
    white-space: nowrap;
}
.project-audit-modal .project-audit-twin .project-audit-cell-inner {
    background: #ffffff;
}

.project-audit-modal .project-audit-row .project-audit-cell--before,
.project-audit-modal .project-audit-row .project-audit-cell--after {
    font-variant-numeric: tabular-nums;
}

.project-audit-modal .project-audit-row .project-audit-cell--after {
    padding-right: 0;
}

/* When: time over date. */
.project-audit-modal .project-audit-time {
    color: var(--at-ink);
    font-variant-numeric: tabular-nums;
}

.project-audit-modal .project-audit-date-line {
    font-size: 11px;
    color: var(--at-muted-3);
    font-variant-numeric: tabular-nums;
}

/* Who: avatar circle + name. */
.project-audit-modal .project-audit-who {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--at-text);
    min-width: 0;
}

.project-audit-modal .project-audit-avatar {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--at-primary);
    color: #ffffff;
    font-family: GlowSemibold;
    font-weight: 700;
    font-size: 9px;
}

.project-audit-modal .project-audit-who__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Type chip. */
.project-audit-modal .project-audit-type {
    padding: 2px 8px;
    border-radius: 4px;
    background: var(--at-chip);
    color: var(--at-muted);
    font-family: GlowSemibold;
    font-weight: 600;

    font-size: 12.5px;
}

/* Object: name + faint #id. */
.project-audit-modal .project-audit-object__name {
    color: var(--at-ink);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.project-audit-modal .project-audit-object__id {
    margin-left: 5px;
    color: var(--at-ref);
    font-size: 11.5px;
    flex: 0 0 auto;
}

/* " #<id>" tokens inside Before/After value cells (e.g. predecessor "ZZZZZ #7", or every
   "#NN" in a comma-joined ref list). Same muted grey + smaller size as the Object-column #id;
   the 5px left margin supplies the gap (the literal leading space is no longer rendered). */
.project-audit-modal .project-audit-value-id {
    margin-left: 5px;
    color: var(--at-ref);
    font-size: 11.5px;
}

/* " (h)" hours-unit marker after the Total / Spent / Remaining work fields and the worklog
   date leaf in the Field column. Same muted treatment as the #id token: grey, smaller, 5px gap. */
.project-audit-modal .project-audit-hours-suffix {
    margin-left: 5px;
    color: #aab0bb;
    font-size: 11px;
}

/* Change badge: friendly label + color, no leading dot. */
.project-audit-modal .project-audit-badge {
    padding: 2px 9px;
    border-radius: 6px;
    font-family: GlowSemibold;
    font-weight: 600;
    font-size: 12.5px;
    white-space: nowrap;
}

.project-audit-modal .project-audit-badge--modified {
    background: #eaf1fc;
    color: #2461c4;
}

.project-audit-modal .project-audit-badge--added {
    background: #e6f5ec;
    color: #1f7a52;
}

.project-audit-modal .project-audit-badge--removed {
    background: #fdecea;
    color: #c0392b;
}

/* Operation: compact ellipsis; color matches the muted text level. */
.project-audit-modal .project-audit-operation {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--at-text);
}

/* ── Ledger separators (per-level, per-cell) ─────────────────────────────────
   The table reads as a grouped audit ledger. Each rendered row carries ONE boundary
   modifier (or none for the first row of the table) computed in rowBoundaryClass():

     --bd-tx      transaction changed  → strongest line across ALL cells (full width).
     --bd-object  object changed (same tx) → normal line from the Type column onward,
                  NOT crossing the merged When / Who / Operation cells.
     --bd-kind    change-kind group changed (same object) → sub-boundary lighter than object,
                  from the Change column onward, NOT crossing the merged Type / Object cells.
     --bd-field   field changed (same tx + object + kind) → lightest line from the Field column
                  onward, NOT crossing Type / Object / Change either.

   Borders are placed on the individual grid cells (the grid has per-cell divs), never as a
   single full-row border for object/field levels — that is what keeps the empty collapsed
   left cells free of any horizontal line. All three are 1px so the grid rows stay aligned;
   the hierarchy is conveyed by colour (tx darkest → field lightest). */

/* Transaction boundary: full-width strongest line (every cell). */
.project-audit-modal .project-audit-row--bd-tx > .project-audit-cell {
    border-top: 1px solid var(--at-bd-tx);
}

/* Object boundary: line from Type onward; When / Who / Operation stay uncrossed. */
.project-audit-modal .project-audit-row--bd-object > .project-audit-cell--type,
.project-audit-modal .project-audit-row--bd-object > .project-audit-cell--object,
.project-audit-modal .project-audit-row--bd-object > .project-audit-cell--change,
.project-audit-modal .project-audit-row--bd-object > .project-audit-cell--field,
.project-audit-modal .project-audit-row--bd-object > .project-audit-cell--before,
.project-audit-modal .project-audit-row--bd-object > .project-audit-cell--after {
    border-top: 1px solid var(--at-bd-object);
}

/* Change-kind sub-boundary: line from Change onward (Change / Field / Before / After);
   the merged Type / Object cells stay uncrossed so the object block reads as one merged
   unit spanning its kind groups. Lighter than the object boundary, heavier than field. */
.project-audit-modal .project-audit-row--bd-kind > .project-audit-cell--change,
.project-audit-modal .project-audit-row--bd-kind > .project-audit-cell--field,
.project-audit-modal .project-audit-row--bd-kind > .project-audit-cell--before,
.project-audit-modal .project-audit-row--bd-kind > .project-audit-cell--after {
    border-top: 1px solid var(--at-bd-kind);
}

/* Field boundary: lightest line from Field onward; Type / Object / Change stay uncrossed. */
.project-audit-modal .project-audit-row--bd-field > .project-audit-cell--field,
.project-audit-modal .project-audit-row--bd-field > .project-audit-cell--before,
.project-audit-modal .project-audit-row--bd-field > .project-audit-cell--after {
    border-top: 1px solid var(--at-bd-field);
}

/* Field name: segments wrap to multiple lines when the column is narrow.
   No truncation — the field path must always be fully visible. */
.project-audit-modal .project-audit-cell--field {
    color: #6b7280;
    white-space: normal;
    word-break: break-word;
    overflow-wrap: anywhere;
    align-items: flex-start;
    flex-wrap: wrap;
}

/* Resource/group chip: "[Resource] ● Group" — a neutral light-tinted pill with dark readable text
   and a dot in the exact group color. Replaces the old solid group-color pill. The pill background
   and text color are set inline from chipColors(); the dot color is set inline too. Used in the
   Before/After value cells, the object hover-card lines, and the inline Field-column tokens. */
.project-audit-modal .project-audit-rg-chip {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 5px;
    white-space: nowrap;
    font-size: 13px;
    font-weight: 600;
}
.project-audit-modal .project-audit-rg-chip__dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    margin: 0 7px;
    flex-shrink: 0;
}
.project-audit-modal .project-audit-rg-chip__dot--lead {
    margin: 0 7px 0 0;
}

/* Field-path segment group: each iteration's leading "·" separator is glued to the
   segment content that FOLLOWS it inside ONE flex item. Because the Field cell is a
   flex-wrap container, every flex item wraps as a unit, so a break can only occur
   BEFORE a "·Segment" group — never between the "·" and its segment (white-space:nowrap
   forbids any internal break, and also stops overflow-wrap:anywhere on the cell from
   splitting the group). inline-flex + align-items:center keeps the grouped content
   (resource chip, worklog icon + date, plain text + unit suffix) aligned exactly as the
   field cell aligned them before grouping. */
.project-audit-modal .project-audit-field-seg {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}

/* Separator between field-path segments. */
.project-audit-modal .project-audit-field-sep {
    color: #7a8089;
    font-weight: 700;
    font-size: 20px;
    line-height: 0;
    position: relative;
    top: 1px;
    padding: 0 4px;
}

/* Timesheet icon shown before worklog date segments in the Field cell.
   Rendered at 14px square, vertically centred with the date text, with a
   4px gap between the icon and the date. The SVG uses fixed fill colours
   (#4C5269) so opacity provides the muting rather than currentColor. */
.project-audit-modal .project-audit-worklog-icon {
    width: 14px;
    height: 14px;
    vertical-align: middle;
    margin-right: 4px;
    opacity: 0.8;
    flex-shrink: 0;
}

/* Work numbers next to the resource chip in a TaskAssignment add/remove cell.
   A small left gap separates it from the chip; font matches the table body. */
.project-audit-modal .project-audit-assignment-work {
    margin-left: 5px;
    font-size: 14px;
    line-height: 18px;
    vertical-align: middle;
    white-space: nowrap;
}

/* Comment value inline rendering: "<User>: [★] <text>".
   The wrapper is an inline-flex row so the star sits vertically centred between
   the user prefix and the comment text without disturbing line-height. The text
   portion is clamped to one visible line (overflow:hidden + text-overflow:ellipsis)
   consistent with how .project-audit-plaintext-value clips long values. */
.project-audit-modal .project-audit-comment-value {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 100%;
    overflow: hidden;
    font-size: 14px;
    line-height: 18px;
    white-space: nowrap;
}

.project-audit-modal .project-audit-comment-value__user {
    flex-shrink: 0;
    font-weight: 500;
}

.project-audit-modal .project-audit-comment-star {
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    margin-right: 3px;
    vertical-align: middle;
}

.project-audit-modal .project-audit-comment-value__text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Before / After HEADER cells: override the body-cell color rules below so the
   header cells match the standard header text color (var(--at-muted)) instead of
   the body-specific Before (--at-muted-2) / After (--at-ink) colors. */
.project-audit-modal .project-audit-head .project-audit-cell--before,
.project-audit-modal .project-audit-head .project-audit-cell--after {
    color: var(--at-muted);
}

/* Before / After value cells.
   The cell IS the flex wrapper: align-items:center vertically centres content,
   padding-top/bottom:6px give breathing room, and no fixed height lets the row
   grow to fit the inner span's clamped content.
   flex-wrap:wrap is kept so chips / collection-diff items reflow naturally. */
.project-audit-modal .project-audit-cell--before {
    color: var(--at-muted-2);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    min-width: 0;
    padding-top: 6px;
    padding-bottom: 6px;
}

.project-audit-modal .project-audit-cell--after {
    color: var(--at-ink);
    font-weight: 500;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    min-width: 0;
    padding-top: 6px;
    padding-bottom: 6px;
}

/* Faint empty placeholder. */
.project-audit-modal .project-audit-dash {
    color: var(--at-dash);
    font-weight: 400;
}

/* Resize handle: invisible until the column edge is hovered (A4). */
.project-audit-modal .project-audit-resize {
    position: absolute;
    top: 7px;
    bottom: 7px;
    right: -6px;
    width: 12px;
    cursor: col-resize;
    pointer-events: auto;
    z-index: 4;
}

/* Load more. */
/* "Load more records" control — mirrors the Group Task List ".load-more-tasks-btn"
   pattern: a left-aligned blue text link (color #5774e7, 13px) with a pointer cursor,
   indented to the table's 14px row inset and given a little top margin. Not a button.
   Rendered as the last child INSIDE .project-audit-table-wrapper (the scrollable area)
   so the user must scroll to the bottom to reach it — clicking then appends the next page. */
.project-audit-modal .project-audit-load-more {
    margin-left: 14px;
    margin-top: 12px;
    margin-bottom: 8px;
    height: 20px;
}

.project-audit-modal .project-audit-load-more__link {
    color: var(--link-blue);
    font-size: 13px;
    cursor: pointer;
}

.project-audit-modal .project-audit-load-more__link:hover {
    text-decoration: underline;
}

/* While a page is in flight: muted + non-interactive (the click handler also no-ops
   via the isLoadingMore guard). */
.project-audit-modal .project-audit-load-more__link--loading {
    opacity: 0.6;
    cursor: default;
    text-decoration: none;
}

/* ── Value-cell alignment: always left-align Before/After ────────────────────
   Numbers, dates, plain text, collection diffs, chips, and the em-dash marker
   are all left-aligned. The only modifier that remains is --object (pre-wrap for
   created/deleted object summaries), which does not affect alignment. */

/* ── Collection diff colours and sep (#17) ──────────────────────────────────
   Colours are now set on the chip approximation block below. The sep color
   remains here so it still applies between items. */
.project-audit-modal .project-audit-coll-sep {
    color: var(--at-muted-3);
}

/* ── Chip / badge overflow clipping in narrow columns (#12) ─────────────────
   Type and Change cells each contain a single chip/badge. Without overflow:hidden
   the chip bleeds into the adjacent column when the column is resized narrow.
   min-width:0 is required so the flex/grid cell can shrink below its content. */
.project-audit-modal .project-audit-row .project-audit-cell--type,
.project-audit-modal .project-audit-row .project-audit-cell--change {
    overflow: hidden;
    min-width: 0;
}

/* ── Field column: clip over-wide resource chips (#4) ───────────────────────
   When a single resource chip is wider than the Field column, it bleeds into
   the neighbour. overflow:hidden clips it; min-width:0 lets the grid cell
   shrink below the chip's intrinsic width. The existing white-space:normal /
   flex-wrap:wrap on .project-audit-cell--field is intentional (multi-segment
   field paths still wrap across lines) — only a chip that is wider than the
   column is clipped. The field-level rule stays on the base selector; this
   row-scoped rule is additive. */
.project-audit-modal .project-audit-row .project-audit-cell--field {
    overflow: hidden;
    min-width: 0;
}


/* ── Non-competence collection diff items (Tags, predecessors, …) ─────────────
   Text colour only — no chip background, no border-radius, no padding.
   Font is 14px to match the app's standard body text.
   added   = dark-blue text; removed = dark-red text; unchanged = normal text. */
.project-audit-modal .project-audit-coll-item--unchanged,
.project-audit-modal .project-audit-coll-item--added,
.project-audit-modal .project-audit-coll-item--removed {
    display: inline;
    font-size: 14px;
    line-height: 18px;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.project-audit-modal .project-audit-coll-item--unchanged {
    color: var(--at-text);
}

.project-audit-modal .project-audit-coll-item--added {
    color: #245599;
}

.project-audit-modal .project-audit-coll-item--removed {
    color: #9b5f5f;
}

/* ── Attributes collection diff — chip style at 14px ─────────────────────────
   Attributes are rendered as small chips (like Tags use in the project card).
   Base chip: light neutral background, rounded, 14px.
   Added/removed get tinted backgrounds matching the competence chip pattern. */
.project-audit-modal .project-audit-attr-chip {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 4px;
    background-color: var(--at-chip);
    color: var(--at-text);
    font-size: 13px;
    line-height: 18px;
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
}

.project-audit-modal .project-audit-attr-chip--added {
    background-color: #deeaf8;
    color: #245599;
}

.project-audit-modal .project-audit-attr-chip--removed {
    background-color: #faeaea;
    color: #9b5f5f;
}

.project-audit-modal .project-audit-attr-chip--unchanged {
    background-color: var(--at-chip);
    color: var(--at-text);
}

/* ── Competence chips (Competences field only) ───────────────────────────────
   Mimics the task-card .skill chip: #EEF1FE background, 4px border-radius,
   6px padding, 13px font, with a trailing inline-flex column of 5 graduated
   level bars (widths 3–7 px matching the real .skill .levels bars).
   Added competences use a blue tint; removed use a red tint. */
.project-audit-modal .project-audit-competence-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border-radius: 4px;
    background-color: #eef1fe;
    font-size: 13px;
    line-height: 16px;
    padding: 3px 6px;
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
}

.project-audit-modal .project-audit-competence-chip--added {
    background-color: #deeaf8;
    color: #245599;
}

.project-audit-modal .project-audit-competence-chip--removed {
    background-color: #faeaea;
    color: #9b5f5f;
}

.project-audit-modal .project-audit-competence-chip__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Five horizontal dashes stacked vertically, right-aligned — exact replica of the
   task-card inline skill chip .levels icon (skills.component.css).
   Bars stack top→bottom as DOM children [5,4,3,2,1]; flex-direction:column +
   align-items:flex-end keeps them flush to the RIGHT edge.
   Level 5 (top, widest) → level 1 (bottom, narrowest).
   Heights: 2px per bar (matches reference). Widths: 7/6/5/4/3 px top→bottom.
   Gap: 1px (margin-top on every child except the first, matching reference 1px).
   Colors: bar === level → blue #5774E7 (--active);
            bar < level  → light blue #ABB8F8 (--below);
            bar > level  → gray #B6B6B6 (default). */
.project-audit-modal .project-audit-competence-levels {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
    flex-shrink: 0;
    align-self: center;
}

.project-audit-modal .project-audit-competence-level {
    height: 2px;
    border-radius: 1px;
    background: #b6b6b6;
}

/* DOM order is [5,4,3,2,1] so child 1 = level 5 (top/longest), child 5 = level 1 (bottom/shortest). */
.project-audit-modal .project-audit-competence-level:nth-child(1) { width: 7px; }
.project-audit-modal .project-audit-competence-level:nth-child(2) { width: 6px; }
.project-audit-modal .project-audit-competence-level:nth-child(3) { width: 5px; }
.project-audit-modal .project-audit-competence-level:nth-child(4) { width: 4px; }
.project-audit-modal .project-audit-competence-level:nth-child(5) { width: 3px; }

/* The bar at the level: blue. */
.project-audit-modal .project-audit-competence-level--active {
    background: #5774e7;
}

/* Bars below the level: light blue. */
.project-audit-modal .project-audit-competence-level--below {
    background: #abb8f8;
}

/* Tinted overrides for added/removed chips. */
.project-audit-modal .project-audit-competence-chip--added .project-audit-competence-level--active {
    background: #245599;
}
.project-audit-modal .project-audit-competence-chip--added .project-audit-competence-level--below {
    background: #7aaad4;
}

.project-audit-modal .project-audit-competence-chip--removed .project-audit-competence-level--active {
    background: #9b5f5f;
}
.project-audit-modal .project-audit-competence-chip--removed .project-audit-competence-level--below {
    background: #d4a0a0;
}

/* ── Plain-text value inner span ─────────────────────────────────────────────
   Two-element structure: the cell is the flex wrapper (align-items:center,
   padding-top/bottom:6px — see .project-audit-cell--before/after above).
   This inner span carries the -webkit-line-clamp to cap at 4 lines with
   ellipsis. The row height is content-driven so the separator is always drawn
   AFTER the full clamped text — never through it.

   IMPORTANT: display:-webkit-box and display:flex must never be on the same
   element — flex overrides -webkit-box and breaks line-clamp. This span is
   a separate element from the flex-wrapper cell. */
.project-audit-modal .project-audit-plaintext-value {
    white-space: normal;
    overflow-wrap: anywhere;    /* break long unbroken tokens like id=1 name=... */
    line-height: 1.4;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;      /* up to 4 lines, then ellipsis */
    overflow: hidden;
    text-align: left;
    min-width: 0;
    width: 100%;
}

/* Created / deleted object summary: pre-wrap so the newline-separated "Key: value" lines
   render as distinct lines. The span still clamps at 4 lines via overflow:hidden. */
.project-audit-modal .project-audit-row .project-audit-cell--before.project-audit-value--object .project-audit-plaintext-value,
.project-audit-modal .project-audit-row .project-audit-cell--after.project-audit-value--object .project-audit-plaintext-value {
    white-space: pre-wrap;
}

/* ── ObjectValueHolder hover card ────────────────────────────────────────────
   A fixed-positioned card that escapes cell overflow:hidden by being rendered
   at body level (appended to .project-audit-modal via ngIf on a sibling element).
   position:fixed is used so it escapes every overflow:hidden ancestor.
   The card is shown/hidden and positioned by Angular (mouseenter)/(mouseleave)
   on the value cell; the JS sets style.left/top from getBoundingClientRect. */
.project-audit-object-card {
    position: fixed;
    z-index: 11090;
    background: #ffffff;
    border: 1px solid #d8dae1;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    padding: 8px 12px;
    min-width: 160px;
    max-width: 320px;
    font-family: GlowRegular;
    font-size: 13px;
    line-height: 1.5;
    color: #2a2d34;
    pointer-events: none;
}

.project-audit-object-card__line {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.project-audit-object-card__label {
    font-family: GlowSemibold;
    font-weight: 600;
    color: #6b7280;
    margin-right: 4px;
}

.project-audit-object-card__chip {
    display: inline-block;
    padding: 0px 5px;
    border-radius: 3px;
    color: #fff;
    font-size: 13px;
    line-height: 18px;
    vertical-align: middle;
    white-space: nowrap;
    background-color: #9499a4;
}
