/* ── Admin: All enrollments (/admin/enrollments) ─────────────────────
   Cross-cohort enrollments table. Builds on the shared admin table,
   filter-bar and pill helpers in admin.css (reg-* family); this file
   only skins what is unique to the page. */

/* This page's UI copy is Hebrew - re-establish RTL inside the LTR-pinned
   .admin-main (same scoped-island pattern as contracts/leads). LTR-sensitive
   values (emails, phones, dates, amounts) carry dir="ltr" in the template. */
.enr-page {
    direction: rtl;
    text-align: right;
}

/* Mirror the search box adornments (admin.css positions them physically). */
.enr-page .admin-search .fa-search {
    left: auto;
    right: 10px;
}

.enr-page .search-clear {
    right: auto;
    left: 6px;
}

.enr-page .reg-filter-bar .form-select,
.enr-page .reg-filter-bar .form-input {
    text-align: right;
}

/* ── מחזור filter: the two states that are not a picker ──
   Cohort NAMES come from an endpoint gated on `course-cohorts:read`, which this
   page itself does not require. Where the picker cannot be populated it is not
   offered, and where a `?cohort=` from a shared link still narrows the table it
   is named and removable. Both states sit in the filter bar where the picker
   would have been, so the bar keeps its rhythm; neither may look like an empty
   dropdown. Sizing follows `.reg-filter-field .form-select` in admin.css. */

.enr-filter-locked {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    /* Same box as the picker it stands in for, so the labels along the filter
       bar stay on one baseline: 2 x 1px border + 2 x 0.45rem padding + the
       select's 18px content box. A shorter chip drops its own label 2px. */
    min-block-size: 2.15rem;
    padding: 0.45rem 0.7rem;
    background: #f6f8fb;
    border: 1px solid #e2e8f2;
    border-radius: 6px;
    font-size: 0.88rem;
    color: var(--adm-ink-2);
}

.enr-filter-locked-name {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.enr-filter-locked-clear {
    flex: none;
    margin-inline-start: auto;
    padding: 0 0.15rem;
    background: none;
    border: 0;
    color: var(--adm-ink-3);
    font-size: 0.82rem;
    line-height: 1;
    cursor: pointer;
}

.enr-filter-locked-clear:hover {
    color: #b3352c;
}

/* Sits under the picker, inside the same column flex - the picker stays usable
   while it shows, because a stale option list is still better than none. */
.enr-filter-note {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0;
    background: none;
    border: 0;
    color: #b3352c;
    font-family: inherit;
    font-size: 0.74rem;
    text-align: start;
    cursor: pointer;
}

.enr-filter-note:hover {
    text-decoration: underline;
}

/* ── KPI band: one glass instrument, hairline-separated tiles ── */

.enr-kpis {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.7rem 1rem;
    margin-bottom: 0.85rem;
    background: var(--adm-glass);
    -webkit-backdrop-filter: var(--adm-glass-blur);
    backdrop-filter: var(--adm-glass-blur);
    border: 1px solid var(--adm-glass-border);
    border-radius: 14px;
    box-shadow: var(--adm-glass-shadow);
}

/* Contents pinned to the TOP, not centred. The tiles stretch to a common
   height and the band now mixes THREE-line money tiles (figure / ex-VAT /
   label) with TWO-line count tiles; centring each tile's own column floats the
   count tiles' figures half a line below the money tiles' and the band stops
   reading as one instrument. Top-aligned, every figure sits on the same line -
   and the labels are pulled back down to the bottom edge by their own auto
   margin, so the second row lines up too. */
.enr-kpi {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 0.15rem;
    min-width: 110px;
    padding: 0.35rem 0.9rem;
    border: 1px solid transparent;
    border-radius: 12px;
}

.enr-kpi:not(:first-child) {
    border-inline-start-color: var(--adm-line);
    border-start-start-radius: 0;
    border-end-start-radius: 0;
}

/* Solid ink, weight 600 - the brand gradient stays off work-surface numerals. */
.enr-kpi-value {
    font-size: 1.18rem;
    font-weight: 600;
    color: #191A23;
    white-space: nowrap;
}

.enr-kpi--balance .enr-kpi-value {
    color: #C4551A;
}

/* Rows with no agreed amount: a caveat on the balance beside it, not a
   headline number of its own. */
.enr-kpi--unpriced .enr-kpi-value {
    color: #8E8F9E;
}

/* Every tile that explains itself in a tooltip gets the help cursor, so a new
   explained tile cannot be added without the affordance following it. */
.enr-kpi[title] {
    cursor: help;
}

/* The other half of the top-alignment above: the label takes whatever vertical
   slack its tile has, so a two-line tile's label drops to the same baseline as
   a three-line tile's instead of floating in the middle of the box. A tile with
   no slack (the money ones, which set the band's height) resolves this to zero
   and is unaffected. */
.enr-kpi-label {
    margin-block-start: auto;
    font-size: 0.72rem;
    color: #8E8F9E;
    white-space: nowrap;
}

/* The ex-VAT legend, as the band's own footer row rather than a line floating
   underneath it: the tiles and the table's three money columns both print the
   short "(10,331 ₪)" form, and this is the single place on the page that says
   what those parentheses are. `flex-basis: 100%` is what makes it a row of its
   own instead of a sixth tile - it carries no .enr-kpi class, so the hairline
   separator between tiles never reaches it. Alignment is left to the RTL
   island, so it starts under the first tile. */
.enr-kpi-legend {
    flex: 1 0 100%;
    margin: 0.1rem 0 0;
    padding-inline: 0.15rem;
}

/* ── Quick-filter pill rows ── */

.enr-pillbars {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-bottom: 0.6rem;
}

/* ── Failed load: stale data, and a load that never landed ──
   A failed refresh leaves the PREVIOUS filter's rows and money on screen. They
   stay readable (they were true a minute ago) but must not look current, so
   EVERY block rendered from that payload is visibly held back - the money band,
   the faceted pill counts, the table and the pagination footer - and the banner
   names why. Half a page dimmed is worse than none: the un-dimmed numbers then
   read as the current ones. The banner and its retry button stay at full
   contrast; they are the way out. */

.enr-stale {
    opacity: 0.5;
    filter: saturate(0.6);
    transition: opacity 0.15s;
}

.enr-stale-note {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
    padding: 0.55rem 0.85rem;
    background: #fff8e1;
    border: 1px solid #f0dca8;
    border-radius: 12px;
    font-size: 0.84rem;
    color: #7a5c12;
}

.enr-stale-note .fa-triangle-exclamation {
    color: #C4551A;
}

.enr-stale-note .btn {
    margin-inline-start: auto;
}

.enr-load-error {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.7rem;
}

.enr-load-error-text {
    margin: 0;
    color: #b3352c;
}

/* ── Sort control (phone / tablet only) ──
   Hidden here, shown by the 1024px block below where <thead> - and with it
   every sortable header - is dropped. */

.enr-sortbar {
    display: none;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}

.enr-sortbar-label {
    font-size: 0.78rem;
    color: #8E8F9E;
}

.enr-sort-select {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 44px;
    text-align: right;
}

/* ── Table ── */

/* Horizontal scroll lives here, never on the page body. */
.enr-table-wrap {
    overflow-x: auto;
}

.enr-table {
    min-width: 1080px;
}

.enr-table th,
.enr-table td {
    white-space: nowrap;
}

.enr-row--clickable {
    cursor: pointer;
}

.enr-row--clickable:hover td {
    background: #f5f9ff;
}

/* Cancelled rows stay visible for the record but read as history. */
.enr-row--cancelled td {
    opacity: 0.55;
}

/* The keyboard-reachable way into the sale's own page. It has to LOOK like the
   plain bold name it wraps - the row's own hover already says the row is live,
   and a blue underlined name in every row would turn the first column into a
   wall of links. The focus ring is the browser default, deliberately left
   alone: it is the only thing that shows a keyboard user where they are. */
.enr-name-link {
    color: inherit;
    text-decoration: none;
}

.enr-name-link:hover,
.enr-name-link:focus-visible {
    text-decoration: underline;
}

.enr-cell-contact,
.enr-cell-cohort,
.enr-cell-when {
    line-height: 1.35;
}

.enr-cell-contact span,
.enr-cell-cohort span,
.enr-cell-when span {
    display: block;
}

.enr-cell-contact {
    font-size: 0.82rem;
}

.enr-cell-sub {
    font-size: 0.74rem;
    color: #8E8F9E;
}

.enr-cell-muted {
    color: #b9c0cc;
}

.enr-col-num {
    text-align: left;
    font-variant-numeric: tabular-nums;
}

/* Two deliberate lines: the deep-link glyphs above, the labelled cancel/delete
   pair below. Wide enough that the pair never wraps onto a third line - the
   column drove row height to ~105px when it did. */
.enr-col-actions--manage,
.enr-cell-actions--manage {
    /* content box: the pair needs ~233px, plus the cell's 32px padding.
       Only reserved for a user who actually gets the buttons - a read-only
       staff member would otherwise stare at 272px of empty column. */
    min-width: 272px;
}

.enr-cell-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
}

/* Zero-height full-width flex item = a forced line break. */
.enr-actions-break {
    flex-basis: 100%;
    height: 0;
    margin: 0;
}

/* The two destructive row actions carry a label as well as a glyph - "cancel"
   and "delete permanently" keep different things, so an icon alone would be a
   coin flip. Compact so the pair still fits one line beside the deep links. */
.enr-action-btn {
    padding: 0.25rem 0.5rem;
    font-size: 0.74rem;
    line-height: 1.25;
}

.enr-action-btn i {
    margin-inline-end: 0.2rem;
}

.enr-btn-danger {
    color: #dc2626;
    border-color: rgba(220, 38, 38, 0.4);
}

.enr-btn-danger:hover:not(:disabled) {
    background: #fef2f2;
    border-color: #dc2626;
    color: #b91c1c;
}

/* Disabled is signalled by SHAPE, not by more transparency. These buttons sit
   inside .enr-table-wrap, which is already at 0.5 opacity whenever the stale
   wash is on - stacking another 0.5 would both bury the control and make "off"
   look like nothing more than a deeper wash. A flat grey face, a dashed edge
   and a blocked cursor survive the wash and read as inert on their own. */
.enr-action-btn:disabled {
    opacity: 1;
    cursor: not-allowed;
    background: #f2f4f8;
    border-color: #c9ced8;
    border-style: dashed;
    color: #8E8F9E;
    box-shadow: none;
}

/* RouterLinks share the icon-button look with real buttons. */
.enr-page a.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
}

/* ── Chips ── */

.enr-sku-chip,
.enr-contract-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.16rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
}

.enr-sku-chip--developer {
    background: #eaf3ff;
    color: #0b62c4;
}

.enr-sku-chip--architect {
    background: #f1ecff;
    color: #6d3fd6;
}

.enr-sku-chip--bundle {
    background: #fff3e6;
    color: #b35a12;
}

.enr-sku-chip--none {
    background: #f2f4f8;
    color: #8E8F9E;
}

.enr-contract-chip--signed {
    background: #e8f7ee;
    color: #1a7f45;
}

.enr-contract-chip--pending {
    background: #fff8e1;
    color: #9a7215;
}

.enr-contract-chip--cancelled {
    background: #fdeceb;
    color: #b3352c;
}

.enr-paystate--paid {
    color: #1a7f45;
    font-weight: 600;
}

.enr-paystate--partial {
    color: #9a7215;
    font-weight: 600;
}

.enr-paystate--unpaid {
    color: #b3352c;
}

/* ── A cancelled sale is not a debt ──
   The wire still carries a balance and a payment state for a cancelled row (no
   cancel path clears the agreed amount), so the ROW decides not to bill for it.
   The paid figure keeps its number but loses the red - on a sale nobody may
   collect on, "unpaid" red is a debt claim in colour. The יתרה cell carries
   where the money ended up instead of a figure: words, at label size, in the
   same muted ink as the rest of the row's context, and left-aligned with the
   numbers above it so the column keeps one edge. */
.enr-paystate--cancelled {
    color: var(--adm-ink-2);
}

/* `.enr-table td` in the selector on purpose: `.admin-table td` in admin.css
   sets `color: #444` at one class plus one element, so a lone class here loses
   the colour while keeping the size - measured in the browser, where the first
   version of this rule rendered #444 instead of the muted ink. */
.enr-table td.enr-cell-balance--cancelled {
    font-size: 0.74rem;
    color: var(--adm-ink-3);
}

/* ── Pagination ── */

.enr-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 0.9rem;
    flex-wrap: wrap;
}

.enr-pagination-mid {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

.enr-pagination-info {
    font-size: 0.84rem;
    color: #5A5B6A;
}

.enr-page-size {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    color: #8E8F9E;
}

.enr-page-size-select {
    padding: 0.2rem 0.45rem;
    border: 1px solid #dfe4ec;
    border-radius: 8px;
    background: #fff;
    font-size: 0.8rem;
    color: #47505c;
}

/* ── Tablet / phone: rows become cards ── */

@media (max-width: 1024px) {
    /* The card layout below throws away <thead>, so this is the only way to
       reorder the list at this width. */
    .enr-sortbar {
        display: flex;
    }

    .enr-table {
        display: block;
        min-width: 0;
        overflow: visible;
        background: transparent;
        border: none;
        box-shadow: none;
    }

    .enr-table thead {
        display: none;
    }

    .enr-table tbody {
        display: block;
        width: 100%;
    }

    .enr-table tbody tr {
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-areas:
            'name status'
            'contact cohort'
            'chips chips'
            'money money'
            'when actions';
        row-gap: 0.45rem;
        column-gap: 0.6rem;
        width: 100%;
        margin-bottom: 0.85rem;
        padding: 0.85rem 1rem 0.65rem;
        background: #fff;
        border: 1px solid #e6ebf2;
        border-radius: 14px;
        box-shadow: 0 1px 3px rgba(0, 60, 130, 0.05);
    }

    .enr-row--cancelled {
        background: #fafbfc;
    }

    .enr-table td {
        border: none;
        padding: 0;
        font-size: 0.86rem;
        white-space: normal;
    }

    .enr-cell-name {
        grid-area: name;
        font-size: 1rem;
    }

    .enr-table td:nth-child(5) {
        /* status badge */
        grid-area: status;
        justify-self: end;
    }

    .enr-cell-contact {
        grid-area: contact;
    }

    .enr-cell-cohort {
        grid-area: cohort;
        text-align: left;
    }

    /* Track + contract chips share one line. */
    .enr-table td:nth-child(4) {
        grid-area: chips;
    }

    .enr-table td:nth-child(6) {
        grid-area: chips;
        justify-self: end;
    }

    /* The three money cells become one labelled mini-band - a two-column GRID
       each, not a flex line, and the difference is what lets the ex-VAT
       parenthetical survive down here. The cell's label (::before) and its
       figure sit on row 1; the parenthetical takes row 2 of the FIGURE's
       column. In a flex line the block form is merely a third item beside the
       figure, and forcing it onto a second line there costs a
       `flex-basis: 100%` that also widens the cell by the parenthetical's full
       width - which is the one thing this layout cannot afford: the three cells
       share ONE grid area, spread start / center / end, and OVERLAP the moment
       one outgrows its third (see the note further down). Stacked, a cell is
       only as wide as its widest ROW, and "(10,331 ₪)" is narrower than
       "שולם 12,190.5 ₪" - so the figure costs a line of card HEIGHT, which the
       auto-sized row absorbs, and not a pixel of width. */
    .enr-cell-expected,
    .enr-cell-paid,
    .enr-cell-balance {
        grid-area: money;
        display: inline-grid;
        grid-template-columns: auto auto;
        align-items: baseline;
        column-gap: 0.35rem;
        direction: rtl;
        font-size: 0.84rem;
    }

    .enr-cell-expected::before,
    .enr-cell-paid::before,
    .enr-cell-balance::before {
        font-size: 0.72rem;
        color: #8E8F9E;
    }

    /* Column 2 is the FIGURE's column, and naming it is the whole trick: left to
       auto-placement the parenthetical would land in column 1, under the label,
       and read as a second caption. Its row is implicit - the grid only ever
       has one item to put there. */
    .enr-cell-expected .exvat,
    .enr-cell-paid .exvat,
    .enr-cell-balance .exvat {
        grid-column: 2;
    }

    .enr-cell-expected::before {
        content: 'לתשלום';
    }

    .enr-cell-paid::before {
        content: 'שולם';
    }

    .enr-cell-balance::before {
        content: 'יתרה';
    }

    /* On a cancelled row the cell holds where the money ended up, not a figure
       to collect - so the label in front of it has to say that too, or the card
       reads "יתרה הוחזר במלואו". */
    .enr-row--cancelled .enr-cell-balance::before {
        content: 'מצב הכסף';
    }

    .enr-cell-expected {
        justify-self: start;
    }

    .enr-cell-paid {
        justify-self: center;
    }

    .enr-cell-balance {
        justify-self: end;
    }

    /* The three money cells share ONE grid area, spread start / center / end, so
       they do not reflow - they sit side by side and would OVERLAP if one
       outgrew its third. On a cancelled row that cell holds a phrase
       ("הוחזר יותר ממה שנגבה") rather than a figure, which does not fit beside
       two amounts at ANY card width - a tablet card is wider than a phone's, but
       the phrase grew by more than the card did. So it gets a line of its own
       from the moment rows become cards, not only on a phone. The selector has
       to outrank `.enr-table tbody tr`, hence the element names. */
    .enr-table tbody tr.enr-row--cancelled {
        grid-template-areas:
            'name status'
            'contact cohort'
            'chips chips'
            'money money'
            'moneystate moneystate'
            'when actions';
    }

    .enr-row--cancelled .enr-cell-balance {
        grid-area: moneystate;
        justify-self: start;
    }

    .enr-cell-when {
        grid-area: when;
        color: #8E8F9E;
        font-size: 0.78rem;
    }

    .enr-cell-when span {
        display: inline;
        margin-inline-end: 0.5rem;
    }

    /* The desktop column reservation would overflow a 390px card. */
    .enr-col-actions--manage,
    .enr-cell-actions--manage {
        min-width: 0;
    }

    .enr-cell-actions {
        grid-area: actions;
        justify-self: end;
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 0.3rem;
    }

    .enr-kpi {
        min-width: 88px;
        padding-inline: 0.5rem;
    }
}

@media (max-width: 767px) {
    /* The cancelled row's own `moneystate` line is declared in the 1024 block
       above, which this one nests inside - it applies here unchanged. */

    .enr-kpis {
        gap: 0.4rem;
        padding: 0.55rem 0.6rem;
        justify-content: space-between;
    }

    .enr-kpi {
        min-width: 0;
        flex: 1 1 40%;
    }

    .enr-kpi:not(:first-child) {
        border-inline-start-color: transparent;
    }

    .enr-kpi-value {
        font-size: 1.02rem;
    }

    .enr-filter-bar {
        flex-wrap: wrap;
    }
}
