/* /Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-jdzpxrovij] {
    position: relative;
    display: flex;
    flex-direction: column;
}

main[b-jdzpxrovij] {
    flex: 1;
    /* Flex item of .page (row). Without min-width:0 its automatic minimum is its content's
       min-content, so wide page content (e.g. the dashboard's portfolio table) inflates <main>
       and pushes the top bar / page content off-screen. min-width:0 lets it shrink to the
       viewport so wide content scrolls its OWN container instead of widening the page. */
    min-width: 0;
}

.sidebar[b-jdzpxrovij] {
    background: #2A2F38;
}

.top-row[b-jdzpxrovij] {
    background-color: #F6F5F2;
    border-bottom: 1px solid #E8E6E1;
    justify-content: flex-start;
    height: 3.5rem;
    display: flex;
    align-items: center;
}

/* Grows to fill the gap between the left cluster (Version / Org / BU) and the
   right cluster (today-override badge + auth links), so each stays on its side. */
.topbar-spacer[b-jdzpxrovij] {
    flex: 1 1 auto;
}

    .top-row[b-jdzpxrovij]  a, .top-row[b-jdzpxrovij]  .btn-link {
        white-space: nowrap;
        margin-left: 1.5rem;
        text-decoration: none;
        color: #3E4958;
        font-size: 0.85rem;
        font-weight: 500;
    }

    .top-row[b-jdzpxrovij]  a:hover, .top-row[b-jdzpxrovij]  .btn-link:hover {
        text-decoration: underline;
        color: #3D8B5E;
    }

    .top-row[b-jdzpxrovij]  a:first-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .top-row[b-jdzpxrovij]  span {
        color: #2A2F38;
        font-size: 0.85rem;
        font-weight: 600;
    }

@media (max-width: 640.98px) {
    .top-row[b-jdzpxrovij] {
        justify-content: space-between;
    }

    .top-row[b-jdzpxrovij]  a, .top-row[b-jdzpxrovij]  .btn-link {
        margin-left: 0;
    }
}

@media (min-width: 641px) {
    .page[b-jdzpxrovij] {
        flex-direction: row;
    }

    .sidebar[b-jdzpxrovij] {
        width: var(--sidebar-width);
        height: 100vh;
        position: sticky;
        top: 0;
        /* sticky makes the sidebar its own stacking context, which loses to
           later-in-DOM <main> content (VPM/Gantt fixed wrappers) by document
           order — hiding the NavMenu Miller flyout. The flyout (.miller-col,
           z 1063) lives INSIDE this context, so the sidebar's own tier is what
           actually competes at the root level — it must beat page sticky form
           footers (--z-sticky-footer:10) and the status cluster (20), or a
           submit bar paints over the flyout (the z:2-vs-z:10 bug). It stays
           below modals/messaging (1050+) and overlays (3000+), which are root
           siblings, so those still cover the nav. See the ladder in app.css. */
        z-index: var(--z-sidebar);
    }

    .top-row[b-jdzpxrovij] {
        position: sticky;
        top: 0;
        z-index: 1;
    }

    .top-row.auth[b-jdzpxrovij]  a:first-child {
        flex: 1;
        text-align: right;
        width: 0;
    }

    .top-row[b-jdzpxrovij], article[b-jdzpxrovij] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

/* ─── Today-override badge (always visible while override active) ─── */
.todayoverride-badge[b-jdzpxrovij] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.55rem;
    border-radius: 4px;
    background: #7b2fb5;
    color: #ffffff !important;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    box-shadow: 0 0 0 1px #5c1f8c inset;
}

.tdo-badge-clear[b-jdzpxrovij] {
    border: none;
    background: rgba(255, 255, 255, 0.25);
    color: #ffffff;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    border-radius: 3px;
    padding: 0 0.35rem;
}

    .tdo-badge-clear:hover[b-jdzpxrovij] {
        background: rgba(255, 255, 255, 0.45);
    }

#blazor-error-ui[b-jdzpxrovij] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-jdzpxrovij] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

/* ─── Status Cluster ─── */
.nav-status-cluster[b-jdzpxrovij] {
    position: fixed;
    bottom: 20px;
    left: 0;
    width: calc(var(--sidebar-width) - var(--scrollbar-width));
    /* min-height, NOT height. A fixed 40px fits the two 16px lines exactly — until the
       numbers get wide (in-flight latency: "Avg: 1733ms", "Peak: 2039ms"), the flex items
       shrink, the text wraps inside a span, and the second line paints on top of the first
       (George, 2026-07-30). Growing is the only honest failure mode here: the font is
       already at --font-min, so there is nothing left to shrink. */
    height: auto;
    min-height: 40px;
    background: #1e2329;
    color: #ffffff;
    font-size: var(--font-min);
    padding: 4px 10px;
    border-top: 1px solid #3a3f47;
    z-index: var(--z-status-cluster);
}

.status-line[b-jdzpxrovij] {
    display: flex;
    align-items: center;
    /* Wrap BETWEEN items, never inside one — "Avg: 1733ms" stays whole and moves to the
       next row rather than breaking into "Avg:" / "1733ms". */
    flex-wrap: wrap;
    gap: 6px;
    min-height: 16px;
}

    /* Each reading is atomic. Without this the flex items shrink and their text wraps,
       which is what produced the overlap. */
    .status-line > span[b-jdzpxrovij] {
        white-space: nowrap;
    }

@keyframes dot-pulse-b-jdzpxrovij {
    0% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.8); opacity: 0.6; }
    100% { transform: scale(1); opacity: 1; }
}

.status-dot[b-jdzpxrovij] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    animation: dot-pulse-b-jdzpxrovij 0.7s ease-in-out;
}

.status-sep[b-jdzpxrovij] {
    color: #555;
}

/* Boot ERROR panel only — the "Can't reach the server" + Retry state shown when the
   initial Supabase load fails (MainLayout's _initFailed branch). The first-paint
   spinner moved to the shared BusyPanel; these classes are deliberately NOT a spinner. */
.app-boot-error[b-jdzpxrovij] {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 60vh;
}
.app-boot-error-box[b-jdzpxrovij] {
    text-align: center;
    max-width: 28rem;
    padding: 1.5rem;
}
.app-boot-error-title[b-jdzpxrovij] {
    font-size: 1.05rem;
    font-weight: 600;
    margin-top: 0.75rem;
    color: #495057;
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.navbar-toggler[b-5tja6pqnoq] {
    appearance: none;
    cursor: pointer;
    width: 3.5rem;
    height: 2.5rem;
    color: white;
    position: absolute;
    top: 0.5rem;
    right: 1rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}

.navbar-toggler:checked[b-5tja6pqnoq] {
    background-color: rgba(255, 255, 255, 0.5);
}

/* ─── Brand Header ─── */
.top-row[b-5tja6pqnoq] {
    min-height: 3.5rem;
    background-color: #232830;
}

.navbar-brand[b-5tja6pqnoq] {
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    gap: 0.15rem;
}

.brand-icon[b-5tja6pqnoq] {
    color: #3D8B5E;
    font-weight: 800;
    font-size: 1.4rem;
}

.brand-icon-w[b-5tja6pqnoq] {
    color: #3E4958;
    font-weight: 800;
    font-size: 1.4rem;
    margin-right: 0.5rem;
}

.brand-text[b-5tja6pqnoq] {
    color: #F6F5F2;
    font-weight: 600;
    font-size: 1.05rem;
}

/* ─── Section Labels ─── */
.nav-section-label[b-5tja6pqnoq] {
    font-size: var(--font-min);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: rgba(246, 245, 242, 0.85);   /* brighter group headers — were too dim */
    /* Big gap ABOVE (separates sections), tight gap BELOW (header owns its list).
       George 2026-07-27: snug the list up, keep the sections uncrowded. */
    padding: 1.25rem 1.25rem 0.15rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.project-name[b-5tja6pqnoq] {
    color: #D4A843;
    font-size: var(--font-min);
    font-weight: 700;
    text-transform: none;
    letter-spacing: 0;
}

.role-badge[b-5tja6pqnoq] {
    font-size: var(--font-min);
    font-weight: 700;
    background: rgba(61, 139, 94, 0.25);
    color: #3D8B5E;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* ─── Divider ─── */
.nav-divider[b-5tja6pqnoq] {
    height: 1px;
    background: rgba(246, 245, 242, 0.08);
    margin: 0.5rem 1.25rem;
}

/* ─── Nav Icons ─── */
.nav-icon[b-5tja6pqnoq] {
    display: inline-block;
    width: 1.25rem;
    text-align: center;
    margin-right: 0.5rem;
    font-size: 0.85rem;
}

/* ─── Nav Items ─── */
/* The open project's name, tucked under the "Project" header. Not a section label and not a nav
   row — it's a caption, so it gets the header's indent but no uppercase/tracking, and sits snug. */
.nav-open-project[b-5tja6pqnoq] {
    padding: 0 1.25rem 0.35rem 1.25rem;
    margin-top: -0.1rem;
    color: #F6F5F2;
    font-size: 0.8rem;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The project name is the way HOME (George 2026-08-14) — there is no "Project Overview" row any more,
   so this is the control that gets you back out of a view. It has to READ as clickable or it is a
   hidden affordance, which is worse than the row it replaced.

   A LINK ON A DARK PANEL, done the way it should be:
   - NOT default link blue. #0d6efd on #232830 is roughly 3:1 — under the 4.5:1 AA floor for body text,
     and it reads as muddy rather than as an accent.
   - #D4A843 is the app's EXISTING project-name gold (see .project-name above), ~6.6:1 on this panel.
     Reused rather than invented, and it already MEANS "project" here, so the colour is carrying
     information instead of decoration.
   - A PERSISTENT underline, not hover-only. Colour alone must never be the sole signal that something
     is interactive — that fails for colour-blind readers and for anyone who does not hover to explore.
     Underline-offset keeps it off the descenders at this weight.
   - Hover and keyboard focus get the SAME treatment, so tabbing to it is as clear as pointing at it. */
a.nav-open-project-link[b-5tja6pqnoq] {
    display: block;
    color: #D4A843;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    text-decoration-color: rgba(212, 168, 67, 0.45);
    cursor: pointer;
    border-radius: 4px;
    transition: color 0.15s, background 0.15s;
}
a.nav-open-project-link:hover[b-5tja6pqnoq],
a.nav-open-project-link:focus-visible[b-5tja6pqnoq] {
    color: #E8C77A;                                  /* lifts, stays in the same hue family */
    text-decoration-color: #E8C77A;
    background: rgba(246, 245, 242, 0.06);           /* matches .nav-link:hover, so the panel behaves consistently */
}
a.nav-open-project-link:focus-visible[b-5tja6pqnoq] {
    outline: 2px solid #E8C77A;
    outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
    a.nav-open-project-link[b-5tja6pqnoq] { transition: none; }
}

/* Left-panel rows are the app's canonical "Small" — the ladder's --font-small was
   set FROM this value, so read it from the ladder rather than restating 0.85rem. */
.nav-item[b-5tja6pqnoq] {
    font-size: var(--font-small);
    padding-bottom: 0.05rem;   /* halved — rows read as one continuous list */
}

    .nav-item:first-of-type[b-5tja6pqnoq] {
        padding-top: 0;
    }

    .nav-item:last-of-type[b-5tja6pqnoq] {
        padding-bottom: 0.5rem;
    }

    .nav-item[b-5tja6pqnoq]  .nav-link {
        color: #F6F5F2;          /* full white — the 0.7 alpha was hard to read */
        white-space: nowrap;     /* keep each item on one line (no wrap/overlap) */
        background: none;
        border: none;
        border-radius: 6px;
        height: 2rem;            /* was 2.4 — tightens every row without crowding the text */
        display: flex;
        align-items: center;
        line-height: 2rem;
        width: 100%;
        padding-left: 0.5rem;
        transition: all 0.15s;
    }

.nav-item[b-5tja6pqnoq]  a.active {
    background-color: rgba(61, 139, 94, 0.2);
    color: #F6F5F2;
}

.nav-item[b-5tja6pqnoq]  .nav-link:hover {
    background-color: rgba(246, 245, 242, 0.06);
    color: #F6F5F2;
}

/* ─── Scrollable Area ─── */
.nav-scrollable[b-5tja6pqnoq] {
    display: none;
}

.navbar-toggler:checked ~ .nav-scrollable[b-5tja6pqnoq] {
    display: block;
}

@media (min-width: 641px) {
    .navbar-toggler[b-5tja6pqnoq] {
        display: none;
    }

    .nav-scrollable[b-5tja6pqnoq] {
        display: block;
        height: calc(100vh - 3.5rem);
        overflow-y: auto;
        position: relative;
        padding-bottom: 80px;
    }
}

/* ─── Footer ─── */
.nav-footer[b-5tja6pqnoq] {
    padding: 1.5rem 1.25rem 1rem;
    font-size: var(--font-min);
    color: rgba(246, 245, 242, 0.25);
    line-height: 1.5;
    border-top: 1px solid rgba(246, 245, 242, 0.06);
    margin-top: auto;
}

/* ─── Role Badges ─── */
.badge-admin-yellow[b-5tja6pqnoq] {
    background-color: #D4A843;
    color: #000;
}

.badge-viewer-gray[b-5tja6pqnoq] {
    background-color: #555;
    color: #fff;
}

/* ─── Miller-column flyout (Reports-page cascade pattern) ───
   Group rows (Project Manager / Resourcing / Admin) open a column just right
   of the sidebar. position:fixed escapes .nav-scrollable's overflow clipping.
   These z-indexes only order the flyout above the sidebar's own rows + status
   cluster WITHIN the sidebar's stacking context — the flyout's effective tier
   at the root is the sidebar's (--z-sidebar in app.css), which already beats
   page sticky form footers and sits below modals/messaging/overlays. So those
   still win; raising these numbers wouldn't change that. */
.miller-chev[b-5tja6pqnoq] {
    margin-left: auto;          /* row is flex (nav-link) — push chevron right */
    padding-right: 0.5rem;
    opacity: 0.6;
}

.nav-item .miller-row-open[b-5tja6pqnoq] {
    background-color: rgba(246, 245, 242, 0.1);   /* held-open look, like :hover */
}

.miller-backdrop[b-5tja6pqnoq] {
    position: fixed;
    inset: 0;
    z-index: 1062;
    background: transparent;    /* click-away catcher only — no dimming */
}

.miller-col[b-5tja6pqnoq] {
    position: fixed;
    left: var(--sidebar-width, 250px);
    z-index: 1063;
    min-width: 200px;
    background: #fff;
    border: 1px solid #dee2e6;
    border-radius: 0 6px 6px 0;
    box-shadow: 6px 0 18px rgba(0, 0, 0, 0.18);
    overflow-y: auto;           /* max-height set inline from the row position */
    padding-bottom: 0.25rem;
}

.miller-col-head[b-5tja6pqnoq] {
    font-size: var(--font-min);
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #6c757d;
    padding: 0.45rem 0.75rem 0.25rem;
}

.miller-col[b-5tja6pqnoq]  .list-group-item {
    font-size: 0.85rem;
    white-space: nowrap;
    padding: 0.45rem 0.9rem;
    cursor: pointer;
}

/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-z13f0itwbh],
.components-reconnect-repeated-attempt-visible[b-z13f0itwbh],
.components-reconnect-failed-visible[b-z13f0itwbh],
.components-pause-visible[b-z13f0itwbh],
.components-resume-failed-visible[b-z13f0itwbh],
.components-rejoining-animation[b-z13f0itwbh] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-retrying[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-failed[b-z13f0itwbh],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-z13f0itwbh] {
    display: block;
}


#components-reconnect-modal[b-z13f0itwbh] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-z13f0itwbh 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-z13f0itwbh 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-z13f0itwbh 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-z13f0itwbh]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-z13f0itwbh 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-z13f0itwbh {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-z13f0itwbh {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-z13f0itwbh {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-z13f0itwbh] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-z13f0itwbh] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-z13f0itwbh] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-z13f0itwbh] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-z13f0itwbh] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-z13f0itwbh] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-z13f0itwbh] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-z13f0itwbh 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-z13f0itwbh] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-z13f0itwbh {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/KanbanBoard.razor.rz.scp.css */
/* Kanban board (Phase 4a, read-only). Columns sit side by side and scroll INDEPENDENTLY — the board
   does not scroll as one (SpecKanban). Cards consume the shared --radius/--shadow ladder. */

.kb-board[b-ktph9fomea] {
    display: flex;
    gap: 12px;
    padding: 12px;
    align-items: stretch;             /* columns fill the board height so the drop zone reaches top-to-bottom */
    overflow-x: auto;
    height: var(--fit-page-height);   /* fit the viewport exactly — the shared tunable (app.css --fit-page-height) */
}

.kb-col[b-ktph9fomea] {
    flex: 0 0 auto;
    width: calc(var(--kb-cols, 1) * 272px + (var(--kb-cols, 1) - 1) * 8px);   /* N card-columns wide */
    display: flex;
    flex-direction: column;
    height: 100%;                     /* full height — you can drop anywhere down the column */
    background: #f1f3f5;            /* column surface — cards sit ON something (polish #1) */
    border-radius: var(--radius);
    padding: 8px;
}

.kb-col-done[b-ktph9fomea] {
    background: #eceff1;            /* Done columns read as gray (SpecKanban) */
}

.kb-col-over[b-ktph9fomea] {
    background: #ffc9c9;            /* over its WIP limit — the whole bucket goes gray → red (George 2026-08-09) */
}

/* WIP limit — a red STOP-sign octagon at the column bottom, the number inside. Always red (it's a stop sign);
   the COLUMN turning red is the over-limit alarm, not the sign. */
.kb-wip[b-ktph9fomea] {
    flex: 0 0 auto;
    align-self: center;
    margin: 8px 0 2px;
    width: 46px;                   /* ~⅓ a card's height */
    height: 46px;
    background: #d32f2f;
    clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
    box-shadow: inset 0 0 0 2px #fff;   /* the white ring, clipped to the octagon */
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-weight: 800;              /* heavy, condensed — the STOP-sign lettering */
    font-size: 20px;
    line-height: 1;
    letter-spacing: -0.5px;
}

.kb-col-head[b-ktph9fomea] {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    padding: 4px 6px 8px;
    font-weight: 600;
    color: #495057;
}

.kb-col-name[b-ktph9fomea] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kb-col-head-draggable[b-ktph9fomea] {
    cursor: grab;   /* drag a column header to reorder it within its block (Phase 8) */
}

.kb-col-head-draggable:active[b-ktph9fomea] {
    cursor: grabbing;
}

.kb-col-count[b-ktph9fomea] {
    flex: 0 0 auto;
    color: #868e96;
    font-size: var(--font-small);
}

.kb-over[b-ktph9fomea] {
    color: #e03131;
    font-weight: 700;
}

.kb-col-cards[b-ktph9fomea] {
    flex: 1 1 auto;                /* fill the column so the whole height is a drop zone, not just where cards are */
    overflow-y: auto;
    display: grid;                 /* N-wide grid; cards flow ACROSS then DOWN (row-major) off one bucket_order */
    grid-template-columns: repeat(var(--kb-cols, 1), 1fr);
    align-content: start;
    gap: 8px;
    padding: 2px;
}

.kb-card[b-ktph9fomea] {
    background: #fff;
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    border-left: 6px solid #999;   /* colour band — swim lane (matches VPM's lane colour), or status when ≤1 lane */
    padding: 8px 10px;
    cursor: grab;                  /* click opens the editor; press-and-drag moves it (Phase 5/7) */
}

.kb-card:active[b-ktph9fomea] {
    cursor: grabbing;
}

.kb-card:hover[b-ktph9fomea] {
    box-shadow: var(--shadow);
}

.kb-card:active[b-ktph9fomea] {
    /* Bright left edge marks the card you've grabbed. Driven by :active (pure CSS) not a Blazor class — a
       server round-trip can't repaint mid-drag, so the class version only flashed after release. An INSET
       shadow paints INSIDE the card, so the column's overflow scroll can't clip it (that was the "no glow"). */
    box-shadow: inset 6px 0 0 0 #f76707;
}

.kb-col-dragover[b-ktph9fomea] {
    outline: 2px dashed #4dabf7;   /* the column under the dragged card */
    outline-offset: -2px;
}

.kb-drop-msg[b-ktph9fomea] {
    margin: 8px 12px 0;
    padding: 6px 12px;
    background: var(--bs-warning-bg-subtle);
    color: var(--bs-warning-text-emphasis);
    border-radius: var(--radius-sm);
    font-size: var(--font-small);
}

.kb-card-cover[b-ktph9fomea] {
    display: block;
    width: calc(100% + 14px);        /* full-bleed to the card edges (card padding is 8/10, band is 4) */
    height: 110px;
    object-fit: cover;
    margin: -8px -10px 8px -6px;     /* keep the left colour band visible; bleed top/right/left-to-band */
    border-radius: var(--radius) var(--radius) 0 0;
    background: #f1f3f5;
}

.kb-card-top[b-ktph9fomea] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.kb-card-icon[b-ktph9fomea] {
    width: 28px;                    /* ~2× the VPM/Gantt icon */
    height: 28px;
    flex: 0 0 auto;
}

.kb-card-name[b-ktph9fomea] {
    font-weight: 600;
    color: #212529;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1 1 auto;
}

.kb-card-progress[b-ktph9fomea] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.kb-card-desc[b-ktph9fomea] {
    font-size: var(--font-small);
    color: #868e96;
    margin-top: 4px;
    display: -webkit-box;
    -webkit-line-clamp: 2;         /* truncate to ~2 lines */
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.kb-card-dates[b-ktph9fomea] {
    font-size: var(--font-min);
    color: #495057;
    margin-top: 6px;
}

.kb-unscheduled[b-ktph9fomea] {
    color: #adb5bd;
    font-style: italic;
}

.kb-card-l3[b-ktph9fomea] {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    font-size: var(--font-min);
    color: #495057;
}

.kb-l3-label[b-ktph9fomea] {
    flex: 0 0 auto;
}

.kb-l3-bar[b-ktph9fomea] {
    flex: 1 1 auto;
    height: 6px;
    background: #e9ecef;
    border-radius: 3px;
    overflow: hidden;
}

.kb-l3-fill[b-ktph9fomea] {
    display: block;
    height: 100%;
    background: #40c057;   /* L3 completion — green, distinct from the schedule sprite */
}

.kb-sched[b-ktph9fomea] {
    position: relative;
    height: 6px;
    margin-top: 8px;
    background: #e9ecef;
    border-radius: 3px;
    overflow: visible;   /* the today tick is taller than the bar and must not be clipped */
}

.kb-sched-fill[b-ktph9fomea] {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    background: #4dabf7;   /* progress done — blue, distinct from the green L3 bar */
}

/* Today marker — a caret above the bar pointing down at today's position. The distance from the caret to the
   runner (progress) IS the ahead/behind read (no red "expected" fill — that read as done). 2× size per George. */
.kb-sched-today[b-ktph9fomea] {
    position: absolute;
    top: -10px;
    width: 0;
    height: 0;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-top: 10px solid #212529;
    transform: translateX(-8px);
    z-index: 2;
}

/* Runner sprite — the SAME asset VPM/Gantt use (red when late). Sits on the bar at the progress mark; a
   started card puts its RIGHT edge at progress, a late-not-started card sits at the start. */
.kb-runner[b-ktph9fomea] {
    position: absolute;
    top: -5px;
    height: 16px;
    width: 16px;
    pointer-events: none;
    z-index: 1;
}

.kb-runner-at-progress[b-ktph9fomea] {
    transform: translateX(-100%);   /* right edge lands on the progress boundary */
}

/* Late binary card (milestone/ping/risk) — no bar, just the red runner where the bar would go. */
.kb-flag-late[b-ktph9fomea] {
    margin-top: 8px;
    height: 16px;
}

.kb-flag-late img[b-ktph9fomea] {
    height: 16px;
    width: 16px;
}

.kb-card-acct[b-ktph9fomea] {
    display: flex;
    align-items: center;
    gap: 3px;
    margin-top: 4px;
    font-size: var(--font-min);
    color: #868e96;
}

.kb-acct-none[b-ktph9fomea] {
    background: var(--bs-warning-bg-subtle);   /* the app's warning yellow — flags a lane with no owner */
    color: var(--bs-warning-text-emphasis);
    border-radius: var(--radius-sm);
    padding: 0 5px;
    font-weight: 600;
}

.kb-card-people[b-ktph9fomea] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 10px;
    margin-top: 6px;
    font-size: var(--font-min);
    color: #495057;
}

.kb-person[b-ktph9fomea] {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.kb-role[b-ktph9fomea] {
    color: #adb5bd;
    font-weight: 700;
}

.kb-meta[b-ktph9fomea] {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: #343a40;   /* dark — the faint gray read as disabled (George 2026-08-08) */
    font-weight: 600;
}

.kb-count[b-ktph9fomea] {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.kb-ico[b-ktph9fomea] {
    width: 13px;
    height: 13px;   /* SVG bubble — inherits the dark currentColor, unlike the 💬 emoji */
}

.kb-col-empty[b-ktph9fomea] {
    color: #adb5bd;
    text-align: center;
    padding: 12px;
    font-size: var(--font-small);
}

/* ── Bucket management (Phase 8) ── */
.kb-col-edit[b-ktph9fomea] {
    flex: 0 0 auto;
    border: none;
    background: transparent;
    color: #868e96;
    cursor: pointer;
    padding: 0 2px;
    font-size: var(--font-small);
    line-height: 1;
}

.kb-col-edit:hover[b-ktph9fomea] {
    color: #212529;
}

.kb-addcol[b-ktph9fomea] {
    flex: 0 0 160px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px 4px;
}

.kb-addcol-btn[b-ktph9fomea],
.kb-addcol-done[b-ktph9fomea] {
    border: 1px dashed #ced4da;
    background: transparent;
    border-radius: var(--radius);
    padding: 8px;
    cursor: pointer;
    color: #495057;
    font-weight: 600;
}

.kb-addcol-btn:hover[b-ktph9fomea],
.kb-addcol-done:hover[b-ktph9fomea] {
    border-color: #4dabf7;
    color: #1971c2;
}

.kb-addcol-done[b-ktph9fomea] {
    font-weight: 400;
    color: #868e96;
    font-size: var(--font-small);
}

.kb-scrim[b-ktph9fomea] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.kb-modal[b-ktph9fomea] {
    background: #fff;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 20px;
    width: 320px;
    max-width: 92vw;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.kb-modal-title[b-ktph9fomea] {
    margin: 0;
    font-size: 1.1rem;
    color: #212529;
}

.kb-field[b-ktph9fomea] {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: var(--font-small);
    color: #495057;
    font-weight: 600;
}

.kb-field-note[b-ktph9fomea] {
    font-weight: 400;
    color: #868e96;
}

.kb-input[b-ktph9fomea] {
    border: 1px solid #ced4da;
    border-radius: var(--radius-sm);
    padding: 6px 8px;
    font-size: 0.95rem;
    font-weight: 400;
    color: #212529;
}

.kb-hint[b-ktph9fomea] {
    font-size: var(--font-min);
    color: #868e96;
    font-style: italic;
}

.kb-modal-actions[b-ktph9fomea] {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
}

.kb-spacer[b-ktph9fomea] {
    flex: 1 1 auto;
}

.kb-btn[b-ktph9fomea] {
    border: 1px solid #ced4da;
    background: #fff;
    border-radius: var(--radius-sm);
    padding: 6px 14px;
    cursor: pointer;
    color: #495057;
}

.kb-btn-save[b-ktph9fomea] {
    background: #1971c2;
    border-color: #1971c2;
    color: #fff;
    font-weight: 600;
}

.kb-btn-del[b-ktph9fomea] {
    border: 1px solid #f1aeb5;
    background: #fff;
    border-radius: var(--radius-sm);
    padding: 6px 14px;
    cursor: pointer;
    color: #c92a2a;
}

.kb-btn-del:disabled[b-ktph9fomea] {
    color: #ced4da;
    border-color: #e9ecef;
    cursor: not-allowed;
}

/* ── Phase 9 · Time Machine scrub bar ── */
.kb-timemachine[b-ktph9fomea] {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 12px;
    background: #f7f9fb;
    border-bottom: 1px solid #e2e2e2;
}

/* The mode's name — a label at the head of the row, read as a heading not a control (Deming's card). */
.kb-tm-title[b-ktph9fomea] {
    font-weight: 700;
    font-size: var(--font-small);
    letter-spacing: .02em;
    color: #6c5ce7;   /* the same "you are in the past" accent the read-only badge uses */
    white-space: nowrap;
}

.kb-tm-slider[b-ktph9fomea] { flex: 1 1 auto; max-width: 480px; }

.kb-tm-date[b-ktph9fomea] {
    font-weight: 600;
    font-size: var(--font-small);
    white-space: nowrap;
    color: #212529;
}

.kb-tm-badge[b-ktph9fomea] {
    font-size: var(--font-min);
    color: #fff;
    background: #6c5ce7;   /* not a health colour — a "you are looking at the past" marker */
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}

/* A card in the past is not grabbable and does not open — say so with the cursor. */
.kb-card-readonly[b-ktph9fomea] { cursor: default; }
.kb-card-readonly:active[b-ktph9fomea] { box-shadow: var(--shadow-sm); }
/* /Components/Pages/MyWork.razor.rz.scp.css */
.mywork[b-wx3ymcsji1] {
    margin-top: 0.5rem;
    max-width: 56rem;
}
/* "My Work" header row — title left, the Viewing-person combo right. */
.pw-row[b-wx3ymcsji1] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.6rem;
    flex-wrap: wrap;
}
.pw-title[b-wx3ymcsji1] {
    margin: 0;
}
.pw-viewing[b-wx3ymcsji1] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: #555;
    margin: 0;
}
.pw-viewing select[b-wx3ymcsji1] {
    width: auto;
}

/* Filters row — project checkboxes + the due-within horizon. */
.pw-controls[b-wx3ymcsji1] {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    flex-wrap: wrap;
    font-size: 0.82rem;
    color: #555;
    padding: 0.45rem 0.1rem;
    border-top: 1px solid #f1f3f5;
    border-bottom: 1px solid #f1f3f5;
    margin-bottom: 0.7rem;
}
.pw-ctl-label[b-wx3ymcsji1] {
    font-weight: 600;
    color: #6c757d;
}
.pw-proj-chk[b-wx3ymcsji1] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin: 0;
}
.pw-deliv-chk[b-wx3ymcsji1] {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin: 0;
    font-weight: 600;
    color: #495057;
}
.pw-due-ctl[b-wx3ymcsji1] {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin-left: auto;
}
.pw-due-ctl input[b-wx3ymcsji1] {
    width: 3.4rem;
}

/* Bucket headers. */
.bkt[b-wx3ymcsji1] {
    font-size: var(--font-min);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0.85rem 0 0.35rem;
}
.bkt-overdue[b-wx3ymcsji1] { color: #dc3545; }
.bkt-today[b-wx3ymcsji1]   { color: #fd7e14; }
.bkt-week[b-wx3ymcsji1]    { color: #6c757d; }
.bkt-later[b-wx3ymcsji1]   { color: #adb5bd; }

/* Action rows. Calm hover: tint + solidified outline + 1px lift, NO height change. */
.act-row[b-wx3ymcsji1] {
    border: 1px solid #e9ecef;
    border-radius: 6px;
    background: #fff;
    margin-bottom: 6px;
}
.act-row:hover[b-wx3ymcsji1] {
    border-color: #adb5bd;
    background: #f8f9fa;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10);
}
.act-row.sel[b-wx3ymcsji1] {
    border-color: #0d6efd;
    box-shadow: inset 3px 0 0 0 #0d6efd;
}
.act-head[b-wx3ymcsji1] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.5rem 0.7rem;
    cursor: pointer;
    border-radius: 6px;
}
.act-main[b-wx3ymcsji1] {
    min-width: 0;
}
.act-name[b-wx3ymcsji1] {
    font-weight: 600;
    font-size: 0.9rem;
}
.act-ctx[b-wx3ymcsji1] {
    font-size: var(--font-min);
    color: #6c757d;
}
.act-due[b-wx3ymcsji1] {
    text-align: right;
    white-space: nowrap;
    font-size: 0.8rem;
    color: #6c757d;
}
.act-due.late[b-wx3ymcsji1] {
    color: #dc3545;
    font-weight: 600;
}
.act-tag[b-wx3ymcsji1] {
    color: #adb5bd;
    font-weight: 400;
}

/* Selected-row expansion: type header + action pills. */
.act-expand[b-wx3ymcsji1] {
    padding: 0.4rem 0.7rem 0.6rem;
    border-top: 1px solid #f1f3f5;
}
.act-expand-head[b-wx3ymcsji1] {
    font-size: var(--font-min);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #6c757d;
    margin-bottom: 0.35rem;
}
.act-pills[b-wx3ymcsji1] {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}
/* /Components/Pages/OrgAdmin.razor.rz.scp.css */
/* OrgAdmin — the house list standard: the NAME is the edit affordance, and delete is a light ×.
   Scoped here rather than borrowed from ProjectDetailShell.razor.css, because Blazor CSS isolation
   would not apply that file's .pdp-x to this page. */

.org-name-link[b-7tfzvvb67y] {
    color: #0d6efd;
    text-decoration: underline;
    cursor: pointer;
}

.org-name-link:hover[b-7tfzvvb67y] {
    color: #0a58ca;
}

/* Matches .pdp-x in the detail shell so the × reads the same size everywhere. */
.org-x[b-7tfzvvb67y] {
    line-height: 1;
    padding: 0 .4rem;
}
/* /Components/Pages/Profile.razor.rz.scp.css */
.profile-todayoverride[b-ynonh9cs40] {
    margin-top: 1.5rem;
    padding: 0.85rem 1rem;
    border: 1px solid #b794d6;
    border-left: 4px solid #7b2fb5;
    border-radius: 6px;
    background: #f7f0fb;
    max-width: 32rem;
}

.profile-todayoverride h4[b-ynonh9cs40] {
    margin: 0 0 0.35rem;
    color: #7b2fb5;
}

.tdo-help[b-ynonh9cs40] {
    margin: 0 0 0.75rem;
    font-size: 0.85rem;
    color: #555;
}

.tdo-controls[b-ynonh9cs40] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.tdo-controls input[type="date"][b-ynonh9cs40] {
    margin-left: 0.4rem;
    padding: 0.2rem 0.4rem;
}

.tdo-status[b-ynonh9cs40] {
    margin: 0.75rem 0 0;
    font-size: 0.9rem;
}

.tdo-active[b-ynonh9cs40] {
    color: #7b2fb5;
    font-weight: 600;
}
/* /Components/Pages/ReviewActionRegister.razor.rz.scp.css */
/* K9 · Review Action Register — the full page (r4 §5). */

.rar-page[b-m6z1nvg54b] {
    padding: 12px 16px;
    max-width: var(--content-width);   /* the app's standard content width — was full-viewport, ~2× too wide */
}

.rar-page-head[b-m6z1nvg54b] {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 10px;
}

.rar-page-title[b-m6z1nvg54b] {
    margin: 0;
}

.rar-scope[b-m6z1nvg54b] {
    color: #6c757d;
    font-size: var(--font-small);
}

.rar-grow[b-m6z1nvg54b] {
    flex: 1 1 auto;
}

.rar-score[b-m6z1nvg54b] {
    font-weight: 700;
    color: #2b8a3e;
}

.rar-close[b-m6z1nvg54b] {
    border: none;
    background: transparent;
    color: #868e96;
    cursor: pointer;
    font-size: 1.3rem;
    line-height: 1;
    padding: 0 2px;
}

.rar-close:hover[b-m6z1nvg54b] {
    color: #212529;
}

.rar-add-btn[b-m6z1nvg54b] {
    border: 1px dashed #ced4da;
    background: transparent;
    border-radius: var(--radius-sm);
    padding: 6px 14px;
    cursor: pointer;
    color: #1971c2;
    font-weight: 600;
    margin-bottom: 12px;
}

.rar-add-btn:hover[b-m6z1nvg54b] {
    border-color: #4dabf7;
}

.rar-add[b-m6z1nvg54b] {
    border: 1px solid #e9ecef;
    border-radius: var(--radius);
    background: #fbfdf9;
    padding: 10px 12px;
    margin-bottom: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.rar-add-row[b-m6z1nvg54b] {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.rar-field[b-m6z1nvg54b] {
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: var(--font-min);
    color: #495057;
    font-weight: 600;
}

.rar-add-actions[b-m6z1nvg54b] {
    display: flex;
    justify-content: flex-end;
    gap: 6px;
}

.rar-input[b-m6z1nvg54b] {
    border: 1px solid #ced4da;
    border-radius: var(--radius-sm);
    padding: 6px 8px;
    font: inherit;
    font-weight: 400;
    color: #212529;
    box-sizing: border-box;
}

.rar-add > .rar-input[b-m6z1nvg54b] {
    width: 100%;
}

.rar-views[b-m6z1nvg54b] {
    display: flex;
    gap: 6px;
    margin-bottom: 12px;
}

.rar-view[b-m6z1nvg54b] {
    border: 1px solid #ced4da;
    background: #fff;
    border-radius: var(--radius-sm);
    padding: 5px 12px;
    cursor: pointer;
    color: #495057;
    font-size: var(--font-small);
}

.rar-view.on[b-m6z1nvg54b] {
    background: #1971c2;
    border-color: #1971c2;
    color: #fff;
    font-weight: 600;
}

.rar-err[b-m6z1nvg54b] {
    background: var(--bs-warning-bg-subtle);
    color: var(--bs-warning-text-emphasis);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    font-size: var(--font-small);
}

.rar-empty[b-m6z1nvg54b] {
    color: #adb5bd;
    font-style: italic;
}

.rar-table[b-m6z1nvg54b] {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-small);
}

.rar-table th[b-m6z1nvg54b] {
    text-align: left;
    color: #6c757d;
    font-weight: 600;
    font-size: var(--font-min);
    text-transform: uppercase;
    letter-spacing: .03em;
    border-bottom: 1px solid #dee2e6;
    padding: 4px 8px;
}

.rar-table td[b-m6z1nvg54b] {
    padding: 6px 8px;
    border-bottom: 1px solid #f1f3f5;
    vertical-align: top;
}

.rar-badge[b-m6z1nvg54b] {
    padding: 0 6px;
    border-radius: var(--radius-sm);
    font-size: var(--font-min);
    font-weight: 700;
    white-space: nowrap;
}

.rar-late[b-m6z1nvg54b] {
    background: #ffe3e3;
    color: #c92a2a;
}

.rar-open[b-m6z1nvg54b] {
    background: #fff3bf;
    color: #856404;
}

.rar-done[b-m6z1nvg54b] {
    background: #d3f9d8;
    color: #2b8a3e;
}

.rar-muted[b-m6z1nvg54b] {
    background: #e9ecef;
    color: #868e96;
}

.rar-commit[b-m6z1nvg54b] {
    color: #212529;
}

.rar-who[b-m6z1nvg54b],
.rar-due[b-m6z1nvg54b] {
    color: #495057;
    white-space: nowrap;
}

.rar-src[b-m6z1nvg54b] {
    color: #adb5bd;         /* "source unavailable" — muted, not a link, not a blank */
    font-size: var(--font-min);
    font-style: italic;
    cursor: default;
}

.rar-src-link[b-m6z1nvg54b] {
    color: #1971c2;
    font-size: var(--font-min);
}
/* /Components/Shared/ActivityPanel.razor.rz.scp.css */
/* Agent-activity feed — scoped to ActivityPanel. Dense, monospace-leaning, one line per entry. */

.activity-panel[b-th0ssl4kv4] {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.activity-filters[b-th0ssl4kv4] {
    display: flex;
    gap: 6px;
    padding: 6px 8px;
    border-bottom: 1px solid #dee2e6;
    flex-shrink: 0;
}

.act-pill[b-th0ssl4kv4] {
    font-size: 0.8rem;
    padding: 1px 10px;
    border: 1px solid #adb5bd;
    border-radius: 10px;
    background: #fff;
    color: #495057;
    cursor: pointer;
}

.act-pill.on[b-th0ssl4kv4] {
    background: #495057;
    color: #fff;
    border-color: #495057;
}

.activity-feed[b-th0ssl4kv4] {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 4px 0;
    font-size: 0.8rem;
}

.act-empty[b-th0ssl4kv4] {
    padding: 16px;
    color: #6c757d;
    font-size: 0.8rem;
}

/* Density comes from SPACING, not sub-floor type (Beck, 2026-08-22): the floor holds at 0.8rem because
   George reads this at a glance, and a tight line-height + thin vertical padding buys the row count back. */
.act-row[b-th0ssl4kv4] {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding: 1px 8px;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.act-row:hover[b-th0ssl4kv4] {
    background: #f1f3f5;
}

.act-time[b-th0ssl4kv4] {
    color: #868e96;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.act-actor[b-th0ssl4kv4] {
    font-weight: 600;
    color: #212529;
}

.act-text[b-th0ssl4kv4] {
    color: #343a40;
}

/* The resolved target name — the L3's identity, which is what makes the feed George's project not a log. */
.act-target[b-th0ssl4kv4] {
    color: #1971c2;
    font-weight: 600;
}

.act-refusal .act-target[b-th0ssl4kv4] {
    color: #c92a2a;
}

.act-where[b-th0ssl4kv4] {
    color: #868e96;
}

/* A refusal is the highest-value line in the feed — it must not blend in. */
.act-refusal[b-th0ssl4kv4] {
    background: #fff5f5;
}

.act-verb-refused[b-th0ssl4kv4] {
    font-weight: 700;
    color: #c92a2a;
    letter-spacing: 0.02em;
}

.act-refusal .act-text[b-th0ssl4kv4] {
    color: #c92a2a;
}

.act-code[b-th0ssl4kv4] {
    color: #e03131;
    font-family: 'Consolas', 'Courier New', monospace;
    font-size: 0.8rem;
}

/* The synthetic "activity log write failed" marker — an announced gap. */
.act-broken[b-th0ssl4kv4] {
    background: #fff9db;
}

.act-broken .act-text[b-th0ssl4kv4] {
    color: #a5730a;
    font-weight: 600;
}

.act-note[b-th0ssl4kv4] {
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 0 2px;
    font-size: 0.8rem;
    line-height: 1;
}

.act-note-body[b-th0ssl4kv4] {
    padding: 4px 8px 8px 46px;
    color: #495057;
    white-space: pre-wrap;
    font-size: 0.8rem;
    border-bottom: 1px solid #f1f3f5;
}
/* /Components/Shared/AiChatPanel.razor.rz.scp.css */
/* Right-side AI assistant overlay — mirrors MessagingPanel's panel, scoped to THIS component (CSS isolation means
   .msg-panel from MessagingPanel.razor.css does not reach here, which is why the panel had no z-index/positioning). */

.ai-chat-backdrop[b-cd4mo0tkat] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.15);
    z-index: 1065;
}

/* Fixed overlay docked to the right edge, full height, above the VPM/Gantt canvas (same tier as Messages, 1066). */
.ai-chat-panel[b-cd4mo0tkat] {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 480px;          /* a touch wider than Messages — chat wants room; user can drag to resize */
    max-width: 95vw;
    background: #fff;
    border-left: 1px solid #dee2e6;
    box-shadow: -6px 0 18px rgba(0, 0, 0, 0.18);
    z-index: 1066;
    display: flex;
    flex-direction: column;
}

/* Closed = hidden but STILL MOUNTED (display:none doesn't unmount the Blazor <AiPanel/>), so the conversation
   persists across close/reopen. */
.ai-chat-hidden[b-cd4mo0tkat] {
    display: none;
}

.ai-chat-header[b-cd4mo0tkat] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid #dee2e6;
    background: #f8f9fa;
}

/* Left-edge drag handle (wired by ai-panel-resize.js) — sits on the panel's left border. */
.ai-chat-resize[b-cd4mo0tkat] {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 8px;
    cursor: ew-resize;
    z-index: 5;
}

    .ai-chat-resize:hover[b-cd4mo0tkat] {
        background: rgba(13, 110, 253, 0.18);
    }
/* /Components/Shared/ArchErrorStrip.razor.rz.scp.css */
/* ArchErrorStrip — moved verbatim from VpmView's .vpm-error-strip block so the
   Gantt shows the identical strip. Scoped to this component. */
.arch-error-strip[b-behxe7hxi1] { background: #f8d7da; border-bottom: 1px solid #f5c2c7; font-size: 0.82rem; max-height: 38vh; overflow: auto; }
.arch-error-strip-head[b-behxe7hxi1] { padding: 6px 12px; cursor: pointer; font-weight: 600; color: #842029; display: flex; gap: 8px; align-items: center; user-select: none; }
.arch-error-strip-caret[b-behxe7hxi1] { width: 12px; display: inline-block; }
/* Explicit minimize/expand button, pushed to the right edge of the head. */
.arch-error-strip-min[b-behxe7hxi1] { margin-left: auto; background: transparent; border: 1px solid transparent; color: #842029; cursor: pointer; font-size: 0.95rem; line-height: 1; padding: 1px 8px; border-radius: 3px; }
.arch-error-strip-min:hover[b-behxe7hxi1] { background: rgba(132, 32, 41, 0.10); border-color: #f5c2c7; }
.arch-error-table[b-behxe7hxi1] { width: 100%; margin: 0; border-collapse: collapse; }
.arch-error-table th[b-behxe7hxi1] { background: #f1c2c7; color: #842029; text-align: left; padding: 4px 12px; font-weight: 600; }
.arch-error-table td[b-behxe7hxi1] { padding: 3px 12px; border-top: 1px solid #f5c2c7; vertical-align: middle; color: #212529; }
.arch-error-pill[b-behxe7hxi1] { border-radius: 999px; font-size: var(--font-min); padding: 1px 12px; }
/* /Components/Shared/DashLeaderboard.razor.rz.scp.css */
/* K20 · leaderboard — a clickable subject LOOKS clickable.

   George, 2026-08-10, looking at "No ME assigned — enclosure design cannot start": it should be blue
   underlined text. The row already carried a pointer cursor and a hover state, but neither survives a
   glance or a screenshot, and a reader who cannot tell a row navigates will not try it.

   Applied on the SUBJECT cell only, and only when the row is actually clickable — underlining a dead row
   would be worse than leaving it plain, because it promises a destination that isn't there. */
.dash-lb-link[b-5wz4bj4ni5] {
    color: #0d6efd;
    text-decoration: underline;
}
/* /Components/Shared/FollowUpFooter.razor.rz.scp.css */
/* The follow-up footer's own look + layout, moved here from the shell so the component styles itself wherever
   it is used (the shell's detail pane, or Skyline standalone). flex:none = it holds its height and the pane
   above absorbs the squeeze; the max-height + internal scroll keep a long band from swallowing that pane. */
.fuf[b-o5jysn5wg6] {
    flex: none;
    border-top: 1px solid var(--border, #d8d8d8);
    max-height: 45%;
    overflow-y: auto;
    background: var(--footer-bg, #fafbfc);
}

.fuf-band[b-o5jysn5wg6] { padding: 6px 12px; }
.fuf-band + .fuf-band[b-o5jysn5wg6] { border-top: 1px dashed var(--border, #e2e2e2); }
/* /Components/Shared/MessagingPanel.razor.rz.scp.css */
/* Small round sender avatar in the feed (user_table.profile_pic). Sized to sit
   inline with the sender name; cover-fit so non-square sources don't distort. */
.msg-avatar[b-5vt46z1pm3] {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    object-fit: cover;
    flex: 0 0 auto;
}

/* Dim the app behind the panel; click to dismiss. Transparent-ish so the
   VPM/Gantt view stays readable — the right side is the least important
   region of those canvases. */
.msg-panel-backdrop[b-5vt46z1pm3] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.15);
    /* Above the task-edit modals (TaskEditModal 1055, DeliverableDetailModal
       1060) so the panel is usable when opened from the in-modal message icon
       — it overlays the modal non-destructively, leaving unsaved edits intact
       behind the dim. */
    z-index: 1065;
}

/* Fixed overlay docked to the right edge, full height. Overlays the canvas
   rather than squeezing it, so width-sensitive canvases (VPM/Gantt) never
   need a resize nudge. */
.msg-panel[b-5vt46z1pm3] {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 420px;
    max-width: 92vw;
    background: #fff;
    border-left: 1px solid #dee2e6;
    box-shadow: -6px 0 18px rgba(0, 0, 0, 0.18);
    z-index: 1066;
    display: flex;
    flex-direction: column;
}

.msg-panel-header[b-5vt46z1pm3] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid #dee2e6;
    background: #f8f9fa;
}

.msg-panel-body[b-5vt46z1pm3] {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 0.9rem;
}

/* Per-post delete (§3.9) — grey × that reddens on hover (× over trash, per
   the app convention), shown only to author / PM / delegate PM. The inline
   "Delete · Cancel" confirm replaces it on click. */
.msg-del-x[b-5vt46z1pm3] {
    background: none;
    border: none;
    padding: 0 2px;
    line-height: 1;
    font-size: 1.1rem;
    font-weight: 700;
    color: #adb5bd;
    cursor: pointer;
}
.msg-del-x:hover[b-5vt46z1pm3] { color: #dc3545; }
.msg-del-confirm[b-5vt46z1pm3] { font-size: 0.8rem; white-space: nowrap; }
/* /Components/Shared/MyMessagesPanel.razor.rz.scp.css */
/* Cross-project My Messages flyout (§3.9). Wider than the per-project panel
   because it holds four Miller columns side by side (BU → Project → Task →
   Message). Same overlay pattern. */
.mymsg-backdrop[b-th84mr42nr] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.15);
    z-index: 1065;
}

/* Anchored to the LEFT, contiguous with the nav sidebar (Miller columns flow
   out from the left panel). Shadow on the right edge. */
.mymsg-panel[b-th84mr42nr] {
    position: fixed;
    top: 0;
    left: var(--sidebar-width, 250px);
    bottom: 0;
    width: 880px;
    max-width: calc(100vw - var(--sidebar-width, 250px));
    background: #fff;
    border-right: 1px solid #dee2e6;
    box-shadow: 6px 0 18px rgba(0, 0, 0, 0.18);
    z-index: 1066;
    display: flex;
    flex-direction: column;
}

.mymsg-header[b-th84mr42nr] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid #dee2e6;
    background: #f8f9fa;
}

/* Column + row styling (.cascade-cols / .cascade-col / .cascade-col-head /
   .cascade-empty / .cascade-item / .cascade-text) is now the shared cascade
   engine in wwwroot/app.css (extracted for Profile §3.6.1). The Message column
   below reuses .cascade-col / .cascade-col-head for its container; the rows use
   the message-specific styles here. */

/* Message rows — body preview + sender/time meta, with the unread red circle
   (.cascade-dot, shared in wwwroot/app.css) leading the body. */
.mymsg-msg[b-th84mr42nr] {
    display: flex;             /* flex so the red unread dot keeps its size */
    align-items: center;
    gap: 0.4rem;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    border-bottom: 1px solid #f1f3f5;
    padding: 0.45rem 0.6rem;
    cursor: pointer;
}
.mymsg-msg:hover[b-th84mr42nr] { background: #e7f1ff; }   /* blue hover so the targeted message is obvious */
.mymsg-msg-body[b-th84mr42nr] {
    font-size: 0.85rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Components/Shared/PostComposer.razor.rz.scp.css */
.mention-menu[b-vi0t7945c7] {
    max-height: 11rem;
    overflow-y: auto;
    margin-top: -1px;
    border-radius: 0 0 0.375rem 0.375rem;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
    z-index: 1050;
}

.mention-menu .list-group-item[b-vi0t7945c7] {
    cursor: pointer;
    font-size: 0.85rem;
}
/* /Components/Shared/ProjectBanner.razor.rz.scp.css */
/* Project banner ("black box") — moved verbatim from VpmView (Stage 1a).
   .vpm-banner positions itself at column 1 of the host's header grid and stays
   180px so it aligns with the label column below it in VPM. */

.vpm-banner[b-xzt8fs2ytb] {
    grid-row: 1;
    grid-column: 1;
    background: #2A2F38;
    color: #fff;
    padding: 8px 10px;
    overflow: hidden;
    z-index: 20;
}

/* banner-content is a flex column so mt-auto on the "Edit Project" pill pushes
   the pill row to the bottom, regardless of how many detail rows show. */
.banner-content[b-xzt8fs2ytb] { display: flex; flex-direction: column; height: 100%; gap: 1px; }
.banner-title[b-xzt8fs2ytb] { font-weight: 700; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.banner-code[b-xzt8fs2ytb] { font-size: var(--font-min); color: #D4A843; }
/* White (was gray #adb5bd) per George — reads cleaner on the dark banner. */
.banner-detail[b-xzt8fs2ytb] { font-size: var(--font-min); color: #fff; white-space: nowrap; }

/* On-brand pill: gold outline against the dark banner, chip-sized.
   Two EXPLICIT rows (George 2026-08-08) — Config Project, then Buffer + Manage. Each row is nowrap: the
   line breaks are chosen here, never left to whatever happens to fit inside the 180px column. That is
   what keeps the banner's height a constant, so it stays aligned with the calendar beside it; a pill
   added later that no longer fits will overflow visibly (the banner clips) instead of silently pushing
   the header taller again. */
.banner-pill-rows[b-xzt8fs2ytb] { display: flex; flex-direction: column; gap: 4px; }
.banner-pill-row[b-xzt8fs2ytb] { display: flex; gap: 4px; flex-wrap: nowrap; align-items: center; white-space: nowrap; }
.banner-pill[b-xzt8fs2ytb] { font-size: var(--font-min); padding: 1px 10px; background: transparent; color: #D4A843; border: 1px solid #D4A843; border-radius: 999px; line-height: 1.3; }
.banner-pill:hover[b-xzt8fs2ytb] { background: #D4A843; color: #2A2F38; }
/* Disabled pill (e.g. Manage when the project has no buffer) — grayed + muted to
   match the disabled Show Buffer checkbox; no hover fill, no pointer. */
.banner-pill:disabled[b-xzt8fs2ytb] { color: #6c757d; border-color: #6c757d; opacity: 0.55; cursor: default; }
.banner-pill:disabled:hover[b-xzt8fs2ytb] { background: transparent; color: #6c757d; }
/* /Components/Shared/ProjectDetailShell.razor.rz.scp.css */
/* ProjectDetailPage-Spec §2 — the shell geometry. The page fills the space under the top bar; the LIST and
   the DETAIL BODY are the only scrollers, so the title, the leaderboard and the two-band footer are always on
   screen. This is the layout the spec exists to prove (§ "What George is waiting to see"). */

.pdp[b-ml5cn0zmxv] {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--topbar-h, 56px));
    min-height: 0;
    padding: 8px 12px 0;
    gap: 8px;
}

.pdp-title[b-ml5cn0zmxv] { flex: none; }

/* DashChrome (scope + leaderboard) sits between title and body — its own height, never stretched. */
.pdp[b-ml5cn0zmxv]  .dash-chrome { flex: none; }

/* MASTER-DETAIL row fills the rest. */
.pdp-body[b-ml5cn0zmxv] {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    gap: 12px;
}

/* ── SINGLE-COLUMN second layout (§6c) — the selector sits on top, the detail takes the full width below.
   Replaces the side-by-side split with a vertical stack; the detail column is unchanged and simply widens. */
.pdp-body-single[b-ml5cn0zmxv] {
    flex-direction: column;
    gap: 8px;
}

.pdp-selector[b-ml5cn0zmxv] {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border: 1px solid var(--border, #d8d8d8);
    border-radius: var(--radius-sm, 4px);
    background: var(--surface, #fff);
}

.pdp-selector-label[b-ml5cn0zmxv] { font-weight: 600; font-size: var(--font-small, .85rem); white-space: nowrap; }
.pdp-selector-combo[b-ml5cn0zmxv] { max-width: 28rem; }

/* ── LIST PANE — fixed width, scrolls internally. ───────────────────────────── */
.pdp-list[b-ml5cn0zmxv] {
    flex: 0 0 340px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    border: 1px solid var(--border, #d8d8d8);
    border-radius: var(--radius-sm, 4px);
    background: var(--surface, #fff);
}

.pdp-list-head[b-ml5cn0zmxv] {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 8px;
    border-bottom: 1px solid var(--border, #d8d8d8);
}

.pdp-list-title[b-ml5cn0zmxv] { font-weight: 600; font-size: var(--font-small, .85rem); }

.pdp-list-scroll[b-ml5cn0zmxv] { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

.pdp-table[b-ml5cn0zmxv] { margin: 0; font-size: var(--font-small, .85rem); }
.pdp-table thead th[b-ml5cn0zmxv] {
    position: sticky; top: 0; z-index: 1;
    background: var(--surface, #fff);
    border-bottom: 1px solid var(--border, #d8d8d8);
}
.pdp-col-date[b-ml5cn0zmxv] { width: 5.5rem; white-space: nowrap; }
.pdp-col-status[b-ml5cn0zmxv] { width: 5.5rem; }
.pdp-col-x[b-ml5cn0zmxv] { width: 2rem; text-align: center; }

.pdp-name-link[b-ml5cn0zmxv] { text-decoration: none; }
.pdp-name-link:hover[b-ml5cn0zmxv] { text-decoration: underline; }
.pdp-row-sel[b-ml5cn0zmxv] { background: var(--row-selected, #eef4fb); }

/* Group-header row (a page-supplied grouping key, e.g. a Financial sub-type). */
.pdp-group-row td[b-ml5cn0zmxv] {
    font-weight: 600;
    background: var(--group-bg, #eef1f4);
    border-top: 1px solid var(--border, #d8d8d8);
    font-size: var(--font-min, .72rem);
    text-transform: uppercase;
    letter-spacing: .02em;
    color: #555;
}
.pdp-empty-row[b-ml5cn0zmxv] { text-align: center; padding: 16px 8px; }

/* A cadenced occurrence that does not exist (§1b) — the row nobody wrote.

   It is DELIBERATELY not styled like a record: hatched, unclickable, no hover. A missed review and a late
   review are different facts, and the whole reason this row is generated is that the reader cannot
   otherwise see the difference between "five green occurrences" and "five green occurrences with a
   six-week hole in the middle". */
.pdp-gap-row td[b-ml5cn0zmxv] {
    background: repeating-linear-gradient(
        45deg,
        var(--gap-bg, #fbfbfb),
        var(--gap-bg, #fbfbfb) 6px,
        var(--gap-stripe, #f2f2f2) 6px,
        var(--gap-stripe, #f2f2f2) 12px);
    cursor: default;
}

.pdp-status[b-ml5cn0zmxv] {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 10px;
    font-size: var(--font-min, .72rem);
    line-height: 1.5;
    white-space: nowrap;
}
.pdp-x[b-ml5cn0zmxv] { line-height: 1; padding: 0 .4rem; }

/* ── DETAIL COLUMN — the detail body scrolls, the footer bands are flex:none and stay put. ─────────
   This is the geometry risk: two bands must not push the form off-screen. */
.pdp-detail-col[b-ml5cn0zmxv] {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border, #d8d8d8);
    border-radius: var(--radius-sm, 4px);
    background: var(--surface, #fff);
}

.pdp-detail-empty[b-ml5cn0zmxv] {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 12px;
    border: 2px dashed var(--border, #cfcfcf);
    border-radius: var(--radius-sm, 4px);
    text-align: center;
    padding: 24px;
}

.pdp-detail-bar[b-ml5cn0zmxv] {
    flex: none;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 8px 12px;
    background: var(--detail-bar, #eef3f8);
    border-bottom: 1px solid var(--border, #d8d8d8);
    border-radius: var(--radius-sm, 4px) var(--radius-sm, 4px) 0 0;
}
.pdp-detail-title[b-ml5cn0zmxv] { font-weight: 700; }

.pdp-detail-body[b-ml5cn0zmxv] {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 12px;
}

/* The two-band follow-up footer's styles moved to FollowUpFooter.razor.css when it was extracted into its own
   component — the shell now just drops <FollowUpFooter> into the detail column (flex:none lives on the
   component's own root, so the sticky-footer geometry is unchanged). */
/* /Components/Shared/ProjectFeverPanel.razor.rz.scp.css */
/* Header fever panel — moved verbatim from VpmView (Stage 1a). The host wraps
   .fever-placeholder in its right-column container (VPM's .vpm-top-right). */

/* Top panel = flex row of two equal halves: left hosts breadcrumbs/Undo-Redo/
   Debug, right hosts the fever chart. Adjust the flex basis to change the split. */
.fever-placeholder[b-trbaal572b] { height: 80px; background: #fff; flex-shrink: 0; display: flex; }

/* overflow:auto contains the left content within its half so a narrow screen
   doesn't let the Undo/Redo group intrude over the chart. */
.fever-left[b-trbaal572b] {
    flex: 1 1 50%; min-width: 0; background: #fff;
    display: flex; flex-direction: column; justify-content: space-between;
    padding: 4px 8px; box-sizing: border-box;
    overflow: auto;
}
.fever-right[b-trbaal572b] { flex: 1 1 50%; min-width: 0; position: relative; }

/* Top row: breadcrumbs left, conflict-sim + Undo/Redo grouped right. */
.fever-left-top[b-trbaal572b] { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.fever-left-top-actions[b-trbaal572b] { display: flex; gap: 4px; align-items: center; }
/* Bottom row: Debug anchored left, then the control cluster to its right.
   Stays present (empty for non-admin) so the layout doesn't reflow when admin
   status changes mid-session. */
.fever-left-bottom[b-trbaal572b] { display: flex; justify-content: flex-start; align-items: center; gap: 4px; }
/* Control-cluster buttons (Today, and — next — Fit). Neutral chrome matching
   the Debug button so the cluster reads as one group. */
.ph-ctl-btn[b-trbaal572b] {
    font-size: var(--font-min); padding: 1px 10px;
    background: #fff; color: #495057;
    border: 1px solid #adb5bd; border-radius: 3px;
    cursor: pointer;
}
.ph-ctl-btn:hover[b-trbaal572b] { background: #e9ecef; }
/* Debug button — neutral chrome so it doesn't compete with the Undo treatment. */
.banner-debug-btn[b-trbaal572b] {
    font-size: var(--font-min); padding: 1px 10px;
    background: #fff; color: #495057;
    border: 1px solid #adb5bd; border-radius: 3px;
    cursor: pointer;
}
.banner-debug-btn:hover[b-trbaal572b] { background: #e9ecef; }

/* ── Time Machine (MultiChannelVpmRenderSpec Phase 1) ────────────────────── */

/* Disabled pills: the layer is read-only, so Undo/Redo must LOOK unavailable, not just be inert. */
.ph-ctl-btn:disabled[b-trbaal572b] { opacity: .45; cursor: default; background: #f8f9fa; }

/* Toggle state — outlined off, filled on. */
.ph-ctl-btn-on[b-trbaal572b] {
    background: #0d6efd; color: #fff; border-color: #0d6efd;
}
.ph-ctl-btn-on:hover[b-trbaal572b] { background: #0b5ed7; }

/* Scrub strip — one horizontal stack: earliest date | track | latest date, all on the same
   vertical level. Centred in the frame with a 25px margin each side so it can't run off the edge. */
.tm-strip[b-trbaal572b] {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    padding: 4px 25px;
    font-size: var(--font-min); color: #495057;
}

/* Movie transport — reverse · pause · forward. Square, flat, black: they read as film controls
   rather than app buttons, and at this size the glyph IS the affordance. */
.tm-movie[b-trbaal572b] { display: flex; align-items: flex-end; gap: 6px; flex: 0 0 auto; }

/* Each control is a column: speed preview above, glyph below. The label sits in its own reserved
   row (kept even when empty) so showing/hiding it can't jog the buttons up and down. */
.tm-movie-cell[b-trbaal572b] { display: flex; flex-direction: column; align-items: center; }
.tm-speed[b-trbaal572b] {
    /* Box grew with the text: font-min (0.8rem ≈ 12.8px) will not fit an 11px line box. Raised together so the
       badge still reads as one line — the alternative was leaving 9px text, which the minimum-font rule forbids. */
    height: 14px; line-height: 14px;
    font-size: var(--font-min); font-weight: 700; color: #0d6efd;
    user-select: none; pointer-events: none;
}
.tm-movie-btn[b-trbaal572b] {
    width: 22px; height: 22px; padding: 0; line-height: 1;
    background: none; border: none; cursor: pointer;
    color: #212529; font-size: 15px;
}
.tm-movie-btn:hover:not(:disabled)[b-trbaal572b] { color: #0d6efd; }
/* Disabled = Pause while nothing is playing. Visibly unavailable, not merely inert. */
.tm-movie-btn:disabled[b-trbaal572b] { opacity: .3; cursor: default; }
/* The direction currently running. */
.tm-movie-on[b-trbaal572b] { color: #0d6efd; }

/* Range ends — BLACK, not grey. They're real data (the scale's bounds), not chrome. */
.tm-end-date[b-trbaal572b] { color: #212529; font-size: var(--font-min); white-space: nowrap; }

/* The band above the track carries only the floating pill now. */
/* ── Thumb geometry — the basis for ALL positioning on this track ───────────────────────────
   A range thumb's CENTRE travels from thumbW/2 to trackW − thumbW/2; it does NOT sweep the full
   width. Anything positioned by naive percentage therefore drifts from the thumb by up to half a
   thumb, worst at the ends. So the thumb size is PINNED here (never left to the browser default,
   which varies) and every marker below derives from the same expression:

       centre(f) = thumbW/2 + (100% − thumbW) · f      where f is the value fraction 0..1

   Ticks, the date pill and the park ring all use it, so they stay registered with the thumb at any
   width or zoom instead of being tuned to one screen. */
.tm-track-wrap[b-trbaal572b] {
    --tm-thumb: 16px;
    --tm-track-h: 6px;
    /* Park ring, ~30% larger than the thumb+4 it started at. Deliberate SLACK: centre(1) resolves
       to a sub-pixel value the browser rounds, so the ring can be a fraction out no matter how
       exact the formula is. A larger ring makes that error invisible — the eye reads "the dot is
       inside the ring", not "the dot is perfectly concentric" — which is cheaper and more robust
       than chasing precision the renderer won't honour. */
    --tm-park: calc(var(--tm-thumb) + 10px);
    position: relative; flex: 1 1 auto; min-width: 200px; padding-top: 20px;
}
.tm-track[b-trbaal572b] {
    width: 100%; margin: 0; display: block;
    -webkit-appearance: none; appearance: none;
    height: 6px; border-radius: 3px; background: #ced4da;
}
/* Both vendor thumbs pinned to --tm-thumb so the formula above is true in either engine. */
.tm-track[b-trbaal572b]::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: var(--tm-thumb); height: var(--tm-thumb);
    border-radius: 50%; background: #0d6efd; border: none; cursor: pointer;
}
.tm-track[b-trbaal572b]::-moz-range-thumb {
    width: var(--tm-thumb); height: var(--tm-thumb);
    border-radius: 50%; background: #0d6efd; border: none; cursor: pointer;
}

/* Notches marking days that HOLD a snapshot. They rise ~1/4in ABOVE the track and are double
   thickness, so the stops are findable at a glance rather than being hairlines you hunt for.
   Non-interactive so they can never swallow a drag. */
.tm-notch[b-trbaal572b] {
    position: absolute; top: 12px; width: 2px; height: 26px;
    background: #495057; transform: translateX(-50%);
    pointer-events: none;
}
/* Left offset is supplied inline as centre(f) — see the thumb-geometry note above. */

/* The PARK ("off") position — the ring the scrub dot parks inside. Centred on where the thumb
   actually sits at maximum, i.e. centre(1) = 100% − thumbW/2, NOT the track's right edge. Same
   formula as the ticks, so the dot lands concentric rather than approximately so. */
.tm-park[b-trbaal572b] {
    position: absolute;
    /* Horizontal: centre(1) — where the thumb actually stops, not the track's edge. */
    left: calc(100% - (var(--tm-thumb) / 2));
    transform: translateX(-50%);
    /* Vertical: centred on the track's own centreline, DERIVED rather than eyeballed — so resizing
       the ring or the track can't knock it off centre again. */
    bottom: calc((var(--tm-track-h) / 2) - (var(--tm-park) / 2));
    width: var(--tm-park); height: var(--tm-park);
    border-radius: 50%;
    border: 2px solid #212529; box-sizing: border-box;
    pointer-events: none;
}

/* Floating date pill. translateX(-50%) centres it on the thumb; the inline clamp keeps it from
   overhanging either end of the track. */
.tm-pill[b-trbaal572b] {
    position: absolute; top: 0; transform: translateX(-50%);
    background: #212529; color: #fff; border-radius: 3px;
    padding: 0 7px; font-size: var(--font-min); white-space: nowrap;
    pointer-events: none;
}
/* The comparison readout rides in the pill, so it must not wrap the pill onto two lines and cover
   the track. nowrap above already holds it to one line. */

/* Opacity control — occupies the vacated Undo/Redo slots on the top row. */
/* "Drag edits TODAY" — the affordance that replaced the read-only lockout (spec §6).
   Centred on its own line directly above the scrub strip, so it reads as a property of the whole
   Time Machine layer rather than a label on one control.

   Deliberately NOT a red warning: editing while the overlay is up is the intended, normal use, and a
   red banner on every frame of normal use is one people stop seeing — which is exactly how it would
   fail to be there on the one drag that mattered. Amber-on-cream, quiet but distinct from the grey
   furniture around it. */
.tm-editing-live[b-trbaal572b] {
    display: flex; align-items: center; justify-content: center; gap: 5px;
    padding: 2px 25px;
    font-size: var(--font-min); color: #8a6100;
    background: #fff8e6; border-bottom: 1px solid #f0e0b8;
}
.tm-editing-live b[b-trbaal572b] { font-weight: 600; letter-spacing: .02em; }

.tm-op-label[b-trbaal572b] { color: #6c757d; text-transform: uppercase; letter-spacing: .04em;
               font-size: var(--font-min); white-space: nowrap; }
.tm-op-field[b-trbaal572b] { display: inline-flex; align-items: center; gap: 2px;
               font-size: var(--font-min); color: #6c757d; }
.tm-op-input[b-trbaal572b] { width: 26px; font-size: var(--font-min); padding: 1px 2px; text-align: right;
               border: 1px solid #adb5bd; border-radius: 3px; }
/* Hide the spinner arrows — at 26px they'd eat the digits. */
.tm-op-input[b-trbaal572b]::-webkit-outer-spin-button,
.tm-op-input[b-trbaal572b]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.tm-op-input[b-trbaal572b] { -moz-appearance: textfield; }

/* Pull Today + Time Machine ~1cm left to clear room for the opacity control. The margin goes on
   the TRAILING pill only — on both it would open two gaps instead of shifting the pair. */
.tm-shift-left[b-trbaal572b] { margin-right: 38px; }
/* /Components/Shared/RarBand.razor.rz.scp.css */
/* K9 RAR band (r4 §8.1) — sticky footer, three rows visible, scroll for the rest. */

.rar-band[b-bq04kc7lmy] {
    position: sticky;
    bottom: 0;
    background: #fff;
    border-top: 2px solid #dee2e6;
    box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.06);
    padding: 6px 12px 8px;
    z-index: var(--z-sticky-footer, 10);
}

.rar-head[b-bq04kc7lmy] {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 4px;
}

/* Pushes the caller's add control to the right of the heading line. */
.rar-head-actions[b-bq04kc7lmy] {
    margin-left: auto;
}

.rar-title[b-bq04kc7lmy] {
    font-weight: 700;
    color: #212529;
    font-size: var(--font-small);
    text-transform: uppercase;
    letter-spacing: .03em;
}

.rar-count[b-bq04kc7lmy] {
    color: #6c757d;
    font-size: var(--font-min);
}

.rar-empty[b-bq04kc7lmy] {
    color: #adb5bd;
    font-style: italic;
    font-size: var(--font-small);
    padding: 4px 0;
}

.rar-rows[b-bq04kc7lmy] {
    /* three rows, then scroll — the row is ~28px, so ~84px shows exactly three (§8.1). */
    max-height: 90px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.rar-row[b-bq04kc7lmy] {
    display: grid;
    grid-template-columns: 84px 1fr auto auto;
    align-items: center;
    gap: 10px;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    font-size: var(--font-small);
}

.rar-clickable[b-bq04kc7lmy] {
    cursor: pointer;
}

.rar-clickable:hover[b-bq04kc7lmy] {
    background: #f1f3f5;
}

.rar-badge[b-bq04kc7lmy] {
    justify-self: start;
    padding: 0 6px;
    border-radius: var(--radius-sm);
    font-size: var(--font-min);
    font-weight: 700;
    white-space: nowrap;
}

.rar-late[b-bq04kc7lmy] {
    background: #ffe3e3;
    color: #c92a2a;
}

.rar-open[b-bq04kc7lmy] {
    background: #fff3bf;
    color: #856404;
}

.rar-done[b-bq04kc7lmy] {
    background: #d3f9d8;
    color: #2b8a3e;
}

.rar-muted[b-bq04kc7lmy] {
    background: #e9ecef;
    color: #868e96;
}

.rar-text[b-bq04kc7lmy] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #212529;
}

.rar-who[b-bq04kc7lmy] {
    color: #495057;
    font-size: var(--font-min);
    white-space: nowrap;
}

.rar-due[b-bq04kc7lmy] {
    color: #6c757d;
    font-size: var(--font-min);
    white-space: nowrap;
}
/* /Components/Shared/RightDock.razor.rz.scp.css */
/* One docked, tabbed right panel (Messages + AI). Scoped to this component. Its width is a CSS var so MainLayout's
   content margin (the shrink) reads the same value — the drag handle updates the var, content tracks it. */

.right-dock[b-qcu806cujy] {
    position: fixed;
    top: 3.5rem;   /* below the top banner (Hello/version row) — aligns with .vpm-wrapper's top */
    right: 0;
    bottom: 0;
    width: var(--right-dock-width, 460px);
    max-width: 95vw;
    background: #fff;
    border-left: 1px solid #dee2e6;
    box-shadow: -6px 0 18px rgba(0, 0, 0, 0.18);
    z-index: 1066;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.right-dock-hidden[b-qcu806cujy] {
    display: none;
}

.right-dock-tabs[b-qcu806cujy] {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 4px 8px;
    border-bottom: 1px solid #dee2e6;
    background: #f8f9fa;
}

.right-dock-tab[b-qcu806cujy] {
    border: 1px solid transparent;
    background: transparent;
    padding: 4px 12px;
    border-radius: 5px;
    font-size: 0.85rem;
    cursor: pointer;
    color: #495057;
}

    .right-dock-tab.active[b-qcu806cujy] {
        background: #fff;
        border-color: #dee2e6;
        font-weight: 600;
        color: #212529;
    }

.right-dock-body[b-qcu806cujy] {
    flex: 1;
    min-height: 0;
    display: flex;
}

.right-dock-pane[b-qcu806cujy] {
    flex: 1;
    min-height: 0;
    min-width: 0;
    display: flex;
}

    /* Inactive tab's pane hides so the ACTIVE pane fills the single body. Compound selector (0,2,0) outranks
       `.right-dock-pane`'s display:flex (0,1,0) — otherwise, being later in the file, flex would win and show both
       panes side-by-side (the "tab does nothing / split window" bug). */
    .right-dock-pane.right-dock-hidden[b-qcu806cujy] {
        display: none;
    }

/* Left-edge drag handle. */
.right-dock-resize[b-qcu806cujy] {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 8px;
    cursor: ew-resize;
    z-index: 5;
}

    .right-dock-resize:hover[b-qcu806cujy] {
        background: rgba(13, 110, 253, 0.18);
    }
/* /Components/Shared/ShowBufferToggle.razor.rz.scp.css */
/* Copied verbatim from VpmView's former inline .banner-toggle so VPM looks
   pixel-identical after switching to this shared component, and the Gantt gets
   the same look (BufferedGantt.md E5). */
.banner-toggle[b-nn0rztye3f] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: var(--font-min);
    color: #D4A843;
    cursor: pointer;
    margin: 0;
}
.banner-toggle input[b-nn0rztye3f] {
    margin: 0;
    accent-color: #D4A843;
    cursor: pointer;
}
.banner-toggle.sbt-disabled[b-nn0rztye3f] {
    opacity: 0.45;
    cursor: default;
}
.banner-toggle.sbt-disabled input[b-nn0rztye3f] { cursor: default; }
/* /Components/Shared/VpmFindPanel.razor.rz.scp.css */
/* VPM Find — right-dock tab (SpecVpmFind r1). */

.vf-panel[b-erkvf28r5d] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 12px;
    font-size: var(--font-min);
    overflow-y: auto;
}

.vf-row[b-erkvf28r5d] { display: flex; align-items: center; gap: 8px; }

.vf-term[b-erkvf28r5d] { font-size: var(--font-min); }

/* The count line. Kept its own row rather than tucked beside the box, because it changes on every
   keystroke and a value that moves next to a control the user is typing in reads as instability. */
.vf-status[b-erkvf28r5d] { min-height: 1.4em; gap: 10px; }
.vf-count[b-erkvf28r5d] { font-weight: 600; color: #495057; }
.vf-pos[b-erkvf28r5d] { color: #6c757d; }

/* The wrap notice. Distinct colour, because its whole job is to be noticed exactly once — at the seam —
   and it disappears on the next move. */
.vf-wrap[b-erkvf28r5d] { color: #8a6100; }

/* What the walk is standing on — "Deliverable · Housing Detail Design". The only thing left that says
   what KIND a hit is, now the level checkboxes are gone (r2). Wraps rather than truncates: a name cut
   off mid-word is worse than a two-line panel, because the name is the whole point of the line. */
.vf-current[b-erkvf28r5d] {
    color: #495057;
    font-weight: 600;
    word-break: break-word;
}

.vf-walk[b-erkvf28r5d] { gap: 6px; }
/* /Components/Shared/WorkingRecordEditor.razor.rz.scp.css */
/* The Working Record editor (ProjectNotebookSpec r4 §4). Green is where a human writes — kept light and legible. */

.wr-editor[b-kpsg4j3k6b] {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.wr-toolbar[b-kpsg4j3k6b] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.wr-title[b-kpsg4j3k6b] {
    font-weight: 700;
    color: #212529;
}

.wr-spacer[b-kpsg4j3k6b] {
    flex: 1 1 auto;
}

.wr-asof[b-kpsg4j3k6b] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: var(--font-small);
    color: #495057;
}

.wr-error[b-kpsg4j3k6b] {
    background: var(--bs-warning-bg-subtle);
    color: var(--bs-warning-text-emphasis);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    font-size: var(--font-small);
}

.wr-stream[b-kpsg4j3k6b] {
    border: 1px solid #e9ecef;
    border-radius: var(--radius);
    padding: 10px 12px;
    background: #fbfdf9;            /* the faintest green wash — this is the "green" writing surface */
}

/* SideBySide (George 2026-08-13): the two streams become half-width columns rather than a stack, so the
   record reads as a pair and whatever follows it — the Review Action Register — moves up into the space
   the stack used to occupy. Heights are untouched: only the width halves.
   flex-wrap so a narrow window drops back to one column instead of crushing both. */
.wr-streams-row[b-kpsg4j3k6b] {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: flex-start;
}

.wr-stream-half[b-kpsg4j3k6b] {
    /* HALF THE FRAME EACH, and the frame is set by the caller — on Escalation that is the Title field's
       width. flex-basis 50% is the whole rule; the floor exists only so a phone-width window wraps rather
       than crushing both to nothing, and it must stay WELL BELOW half the frame or it silently overrides
       the 50% and pushes the columns apart. Getting that wrong is how these ended up 4x too wide twice
       (George 2026-08-13). Height is untouched — the textarea's rows set it. */
    flex: 1 1 calc(50% - 12px);
    min-width: 240px;
}

.wr-stream-head[b-kpsg4j3k6b] {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 8px;
}

.wr-stream-title[b-kpsg4j3k6b] {
    font-weight: 600;
    color: #2b8a3e;
}

.wr-stream-sub[b-kpsg4j3k6b] {
    font-size: var(--font-min);
    color: #868e96;
}

.wr-note[b-kpsg4j3k6b] {
    border-top: 1px solid #eef0f2;
    padding: 8px 0;
}

.wr-note-text[b-kpsg4j3k6b] {
    white-space: pre-wrap;
    color: #212529;
}

.wr-committed .wr-note-text[b-kpsg4j3k6b] {
    color: #343a40;                /* committed = settled; nothing special beyond staying readable */
}

.wr-note-meta[b-kpsg4j3k6b] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
    margin-top: 4px;
    font-size: var(--font-min);
    color: #868e96;
}

.wr-role[b-kpsg4j3k6b] {
    color: #adb5bd;
    font-weight: 700;
}

.wr-entered[b-kpsg4j3k6b] {
    font-style: italic;
}

.wr-ver[b-kpsg4j3k6b] {
    background: #e7f5ff;
    color: #1971c2;
    border-radius: var(--radius-sm);
    padding: 0 5px;
    font-weight: 600;
}

.wr-open[b-kpsg4j3k6b] {
    background: #fff3bf;
    color: #856404;
    border-radius: var(--radius-sm);
    padding: 0 5px;
}

.wr-link[b-kpsg4j3k6b] {
    border: none;
    background: transparent;
    color: #1971c2;
    cursor: pointer;
    padding: 0 2px;
    font-size: var(--font-min);
    margin-left: auto;
}

.wr-add[b-kpsg4j3k6b] {
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.wr-add-attrib[b-kpsg4j3k6b] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
}

.wr-field[b-kpsg4j3k6b] {
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: var(--font-min);
    color: #495057;
    font-weight: 600;
}

.wr-entered-by[b-kpsg4j3k6b] {
    font-size: var(--font-min);
    color: #adb5bd;
    font-style: italic;
    padding-bottom: 4px;
}

/* MIN-SIZE AUDIT (George 2026-08-15, item 9). `.wr-field` is a caption-sized LABEL, and `.wr-input` is
   `font: inherit` — so every control nested in one rendered its VALUE at --font-min, the hard floor. A
   label may be fine print; a date the user typed is content and must not sit on the floor. Lifts the
   date / select / forum inputs only — the note textarea is not inside a .wr-field and keeps body size. */
.wr-field .wr-input[b-kpsg4j3k6b] {
    font-size: var(--font-small);
}

.wr-input[b-kpsg4j3k6b] {
    border: 1px solid #ced4da;
    border-radius: var(--radius-sm);
    padding: 6px 8px;
    font: inherit;
    font-weight: 400;
    color: #212529;
    width: 100%;
    box-sizing: border-box;
}

.wr-note-actions[b-kpsg4j3k6b] {
    display: flex;
    justify-content: flex-end;
    gap: 6px;
}

.wr-btn[b-kpsg4j3k6b] {
    border: 1px solid #ced4da;
    background: #fff;
    border-radius: var(--radius-sm);
    padding: 5px 12px;
    cursor: pointer;
    color: #495057;
    font-size: var(--font-small);
}

.wr-save[b-kpsg4j3k6b] {
    background: #2b8a3e;
    border-color: #2b8a3e;
    color: #fff;
    font-weight: 600;
}

.wr-close[b-kpsg4j3k6b] {
    border-color: #2b8a3e;
    color: #2b8a3e;
    font-weight: 600;
}
