/*
 * CRM Lists CSS - Contact & Organization List Views
 * Extracted from inline styles and standardized to STYLES.md
 * Modern CSS with design system integration
 */

/* ===== LIST CONTAINER OVERRIDES ===== */
main.container {
    max-width: 1500px;
}

/* ===== SEARCH FILTERS SECTION ===== */
.search-filters {
    background: var(--bs-tertiary-bg);
    border-radius: 12px;
    padding: var(--space-5);
    margin-bottom: var(--space-8);
    border: 1px solid var(--bs-border-color);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
}

[data-bs-theme="dark"] .search-filters {
    background: #2d3748;
    border: 1px solid #4a5568;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

/* Filters Container Grid.
   align-items:start keeps every filter's LABEL on one baseline — the old
   `end` bottom-aligned unequal-height controls (the tall Tags multi-select)
   which made the labels float raggedly. */
.filters-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: var(--space-4);
    align-items: start;
    margin-top: var(--space-4);
}

.filter-item {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Vertically center the lone checkbox against the neighbouring select height. */
.filter-item.checkbox-filter {
    justify-content: flex-start;
}

.filter-label {
    font-weight: 600;
    margin-bottom: var(--space-2);
    color: var(--text-primary);
    font-size: 0.9rem;
}

/* ===== TAG CHIP PICKER (replaces the native multi-select) ===== */
.tag-picker { position: relative; }
.tag-picker-control {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    min-height: 38px;
    padding: 0.25rem 0.4rem;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 6px;
    cursor: text;
}
.tag-picker-control:focus-within {
    border-color: var(--primary-blue);
    box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.15);
}
.tag-picker-chips { display: contents; }
.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: var(--primary-blue);
    color: #fff;
    border-radius: 999px;
    padding: 0.12rem 0.3rem 0.12rem 0.6rem;
    font-size: 0.8rem;
    line-height: 1.5;
    max-width: 100%;
}
.tag-chip-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag-chip-remove {
    border: 0;
    background: transparent;
    color: rgba(255, 255, 255, 0.85);
    padding: 0;
    width: 1.15rem;
    height: 1.15rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    cursor: pointer;
    font-size: 0.68rem;
    flex-shrink: 0;
}
.tag-chip-remove:hover { background: rgba(255, 255, 255, 0.25); color: #fff; }
.tag-picker-input {
    flex: 1 1 5rem;
    min-width: 5rem;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--text-primary);
    padding: 0.2rem 0.15rem;
    font-size: 0.9rem;
}
.tag-picker-menu {
    position: absolute;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    z-index: 1000;
    margin: 0;
    padding: 0.25rem;
    list-style: none;
    max-height: 12rem;
    overflow-y: auto;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
}
.tag-picker-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.9rem;
    color: var(--text-primary);
}
.tag-picker-option:hover,
.tag-picker-option.active { background: var(--bs-tertiary-bg); }
.tag-picker-count {
    font-size: 0.75rem;
    color: var(--bs-secondary-color, #6c757d);
    background: var(--bs-tertiary-bg);
    border-radius: 999px;
    padding: 0 0.5rem;
    min-width: 1.6rem;
    text-align: center;
}
.tag-picker-option.active .tag-picker-count { background: var(--bs-body-bg); }

.checkbox-content {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) 0;
}

/* Actions get their OWN full-width row below the filters (a distinct action
   zone, MD-style), instead of squeezing into a 210px auto-fit grid cell. */
.filter-buttons {
    grid-column: 1 / -1;
    display: flex;
    gap: var(--space-2);
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    border-top: 1px solid var(--bs-border-color);
    margin-top: var(--space-2);
    padding-top: var(--space-4);
}

/* ===== VIEW TOGGLE BUTTONS ===== */
.view-toggle {
    display: flex;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: all 0.2s ease;
}

.view-toggle button {
    border: none;
    padding: var(--space-2) var(--space-4);
    background: var(--bg-primary);
    color: var(--primary-blue);
    transition: all 0.15s ease-in-out;
    font-weight: 500;
    border-right: 1px solid var(--border-color);
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.view-toggle button:last-child {
    border-right: none;
}

.view-toggle button.active {
    background: var(--primary-blue);
    color: white;
    transform: translateY(-1px);
    box-shadow: 0 2px 6px rgba(13, 110, 253, 0.3);
}

.view-toggle button:hover:not(.active) {
    background: var(--primary-blue);
    color: white;
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(13, 110, 253, 0.2);
}

/* Dark mode view toggle */
[data-bs-theme="dark"] .view-toggle {
    border-color: var(--border-color);
    box-shadow: var(--shadow-md);
}

[data-bs-theme="dark"] .view-toggle button {
    background: transparent;
    color: var(--primary-blue);
    border-right-color: var(--border-color);
}

[data-bs-theme="dark"] .view-toggle button.active {
    background: var(--primary-blue);
    color: white;
    transform: translateY(-1px);
    box-shadow: 0 2px 6px rgba(13, 110, 253, 0.4);
}

[data-bs-theme="dark"] .view-toggle button:hover:not(.active) {
    background: var(--primary-blue);
    color: white;
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(13, 110, 253, 0.3);
}

/* Mobile responsiveness */
@media (max-width: 576px) {
    .view-toggle button {
        padding: var(--space-2) var(--space-3);
        font-size: 0.9rem;
    }
    
    .view-toggle {
        width: 100%;
        justify-content: center;
    }
}

/* ===== CARD COMPONENTS ===== */
/* Contact Cards */
.contact-card {
    background: var(--bg-primary);
    border: 1px solid var(--border-light);
    border-radius: 12px;
    padding: var(--space-5);
    margin-bottom: var(--space-4);
    transition: all 0.3s ease;
    box-shadow: var(--shadow-sm);
    border-left: 4px solid var(--info);
}

.contact-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.contact-card.inactive {
    border-left-color: var(--text-secondary);
    opacity: 0.8;
}

/* Organization Cards */
.organization-card {
    background: var(--bg-primary);
    border: 1px solid var(--border-light);
    border-radius: 12px;
    padding: var(--space-5);
    margin-bottom: var(--space-4);
    transition: all 0.3s ease;
    box-shadow: var(--shadow-sm);
    border-left: 4px solid var(--crm-primary);
}

.organization-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.organization-card.inactive {
    border-left-color: var(--text-secondary);
    opacity: 0.8;
}

/* Card Content Structure */
.contact-title,
.organization-title {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: var(--space-2);
    line-height: 1.3;
}

.contact-title a,
.organization-title a {
    color: inherit;
    text-decoration: none;
    transition: color 0.2s ease;
}

.contact-title a:hover,
.organization-title a:hover {
    color: var(--primary-blue);
}

.contact-details,
.organization-details {
    color: var(--text-secondary);
    font-size: 0.95rem;
    margin-bottom: var(--space-3);
    line-height: 1.4;
}

.contact-details div,
.organization-details div {
    margin-bottom: var(--space-1);
    display: flex;
    align-items: center;
}

.contact-details i,
.organization-details i {
    width: 20px;
    margin-right: var(--space-2);
    color: var(--text-muted);
    font-size: 0.9rem;
}

.contact-meta,
.organization-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: var(--space-4);
    font-size: 0.9rem;
    color: var(--text-secondary);
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* ===== SORTABLE TABLE ENHANCEMENTS ===== */
.sortable {
    cursor: pointer;
    position: relative;
    user-select: none;
    transition: all 0.2s ease;
}

.sortable:hover {
    background-color: rgba(var(--primary-blue-rgb), 0.05);
    color: var(--primary-blue);
}

[data-bs-theme="dark"] .sortable:hover {
    background-color: rgba(255,255,255,0.05);
}

.sortable::after {
    content: '\2195';
    opacity: 0.3;
    margin-left: var(--space-2);
    font-size: 0.8rem;
    transition: all 0.2s ease;
}

.sortable.asc::after {
    content: '\2191';
    opacity: 1;
    color: var(--primary-blue);
}

.sortable.desc::after {
    content: '\2193';
    opacity: 1;
    color: var(--primary-blue);
}

/* ===== ENHANCED FORM CONTROLS ===== */
.form-check-input {
    cursor: pointer;
    transition: all 0.2s ease;
}

.form-check-input:hover {
    transform: scale(1.1);
    box-shadow: var(--shadow-sm);
}

.form-check-label {
    cursor: pointer;
    transition: color 0.2s ease;
}

.form-check-label:hover {
    color: var(--primary-blue);
}

/* ===== EMPTY STATE STYLING ===== */
.empty-state {
    text-align: center;
    padding: var(--space-12) var(--space-4);
    color: var(--text-secondary);
}

.empty-state i {
    font-size: 4rem;
    margin-bottom: var(--space-5);
    opacity: 0.5;
    color: var(--text-muted);
}

.empty-state h5 {
    font-size: 1.5rem;
    font-weight: 600;
    margin-bottom: var(--space-3);
    color: var(--text-primary);
}

.empty-state p {
    font-size: 1rem;
    margin-bottom: var(--space-6);
    max-width: 400px;
    margin-left: auto;
    margin-right: auto;
}

/* ===== PAGINATION STYLING ===== */
.pagination .page-link {
    border-color: var(--border-color);
    color: var(--primary-blue);
    padding: var(--space-2) var(--space-4);
    transition: all 0.2s ease;
}

.pagination .page-link:hover {
    background-color: var(--primary-blue);
    border-color: var(--primary-blue);
    color: white;
    transform: translateY(-1px);
}

.pagination .page-item.active .page-link {
    background-color: var(--primary-blue);
    border-color: var(--primary-blue);
}

/* ===== RESPONSIVE DESIGN ===== */
@media (max-width: 768px) {
    .filters-container {
        grid-template-columns: 1fr;
    }
    
    .filter-buttons {
        grid-column: 1 / -1;
        flex-direction: row;
        justify-content: center;
        margin-top: var(--space-3);
    }
    
    .contact-card,
    .organization-card {
        padding: var(--space-4);
    }
    
    .contact-meta,
    .organization-meta {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--space-2);
    }
}

@media (max-width: 576px) {
    main.container {
        max-width: 100%;
        padding-left: var(--space-3);
        padding-right: var(--space-3);
    }
    
    .search-filters {
        padding: var(--space-4);
    }
}

/* ===== ACCESSIBILITY ENHANCEMENTS ===== */
@media (prefers-reduced-motion: reduce) {
    .contact-card,
    .organization-card,
    .view-toggle button,
    .sortable {
        transition: none;
    }
    
    .contact-card:hover,
    .organization-card:hover,
    .view-toggle button.active,
    .view-toggle button:hover:not(.active) {
        transform: none;
    }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    .contact-card,
    .organization-card {
        border-width: 2px;
    }
    
    .view-toggle {
        border-width: 2px;
    }
    
    .view-toggle button {
        border-right-width: 2px;
    }
}

/* ==================================================================
   LIST SECTION LABEL — small uppercase card caption with an optional
   right-hand control (a "view all" link, a sort select, …).

   Added 2026-08-11. This rule existed verbatim three times, once per app
   that wanted the pattern: .crm-dash-label (crm-enhanced.css),
   .cat-dash-label (catalog-enhanced.css) and .ops-dash-label
   (ops-jobs.css). It belongs in core — this file is loaded unconditionally
   from base.html on every page, so using it creates no dependency on any
   optional app in either direction. New consumers should use these names;
   the existing per-app copies can be retired as their pages are touched.
   ================================================================== */
.list-section-label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 12px 16px 6px;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--bs-secondary-color, #6c757d);
}

.list-section-label h2 {
    font-size: inherit;
    font-weight: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    color: inherit;
    margin: 0;
}

/* Right-hand control: a link, or a label paired with a small select. */
.list-section-label a,
.list-section-label label {
    font-size: 0.78rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
}

.list-section-label a {
    text-decoration: none;
}

/* ==================================================================
   DASHBOARD PANELS — opt in with .list-dash on the page wrapper.

   The chrome for a search-first dashboard built from short lists of
   clickable rows (CRM's dashboard is the reference): hairline cards with
   no shadow, hairline row separators, and a faint chevron + hover wash so
   an actionable row reads as actionable.

   Added 2026-08-11 when a third dashboard (inventory) needed it. The rules
   existed twice already, byte-identical apart from the scope class:
   .crm-dash (crm-enhanced.css) and .cat-dash (catalog-enhanced.css) — the
   latter a copy of the former. New consumers use .list-dash; the two
   per-app copies can be retired as those pages are next touched.

   Scoped to the wrapper rather than applied to .card/.list-group-item
   globally on purpose: these are dashboard values, not the platform's
   card style, and unscoping them would restyle every page at once.
   ================================================================== */
.list-dash .card {
    border: 1px solid var(--bs-border-color-translucent, rgba(0, 0, 0, 0.1));
    border-radius: 12px;
    box-shadow: none;
}

.list-dash .list-group-item {
    border-color: var(--bs-border-color-translucent, rgba(0, 0, 0, 0.06));
    background: transparent;
}

.list-dash .list-group-item-action {
    position: relative;
    padding-right: 28px;
    transition: background-color 0.12s ease;
}

.list-dash .list-group-item-action::after {
    content: "›";
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1rem;
    line-height: 1;
    color: var(--bs-tertiary-color, #adb5bd);
    opacity: 0.55;
}

.list-dash .list-group-item-action:hover,
.list-dash .list-group-item-action:focus-visible {
    background: var(--bs-tertiary-bg, #e9ecef);
}

.list-dash .list-group-item-action:hover::after,
.list-dash .list-group-item-action:focus-visible::after {
    opacity: 1;
    color: var(--bs-secondary-color, #6c757d);
}

/* ==================================================================
   LIST PAGE CHROME — the search/filter card and the stat strip that sit
   above a dense list.

   Added 2026-08-11 when a third list page (catalog items) was about to
   copy both rules for a third time. They carry no app-specific values,
   only design-system ones, so a token change should land in one place.

   .list-filter-row  wraps the row of small filter selects under the
                     search box; it only shrinks their type.
   .list-stat-strip  the quiet one-line "how big is my world" row that
                     replaced the old grids of big metric cards.
   ================================================================== */
.list-filter-row .form-select-sm,
.list-filter-row .form-control-sm {
    font-size: 0.82rem;
}

/* Carries its own layout: every consumer was repeating the identical
   `d-flex flex-wrap align-items-center gap-3` utility run just to get the
   strip to lay out, which is not a per-page decision. Margin is deliberately
   NOT included — pages set their own mb-3/mb-4, and baking one in here would
   win against the utility class and silently change their spacing. */
.list-stat-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    font-size: 0.82rem;
    color: var(--bs-secondary-color, #6c757d);
}

.list-stat-strip a {
    text-decoration: none;
}

.list-stat-strip strong {
    color: var(--bs-body-color, #212529);
}

/* ==================================================================
   TWO-LINE IDENTITY CELL — the "name on top, context underneath" cell
   every dense list's widest column uses.

   Added 2026-08-11 at the fourth copy. The same six declarations were
   written out per app: .item-name/.item-sub (catalog-items-list.css),
   .crew-name (crews-list.css), .job-name/.date-sub (ops-jobs.css) and
   .location-name/.location-sub (inventory-locations-list.css). Both lines
   must ellipsis rather than wrap, or the row stops being one line high,
   which is the entire point of a dense table.

   Requires the containing column to set `max-width: 0` — that is what makes
   a table cell honour text-overflow — so column widths stay per-app.
   New consumers use these names; the per-app copies retire on next touch.
   ================================================================== */
.list-cell-primary,
.list-cell-secondary {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.2;
}

.list-cell-primary {
    font-weight: 600;
}

.list-cell-secondary {
    font-size: 0.78rem;
    color: var(--text-secondary, #6c757d);
}

/* ==================================================================
   DENSE LIST TABLE
   Opt in with .dense-table on the <table> (and .dense-table-card on the
   card wrapping it). The chrome that every dense list wants — density,
   badge sizing, whole-row-click cursor, the slim left state edge, and the
   icon-only row action button — lives here; each consumer's own stylesheet
   keeps only what is genuinely its own (column widths, which state maps to
   which colour, app-specific cell classes).

   Consumers: operations jobs list, crews dashboard, catalog items list.
   timetracking's entries list still carries its own copy — fold it in when
   that page is next touched. Sharing this via core creates no optional-app
   coupling: this file loads unconditionally from base.html, so neither app
   depends on the other (CLAUDE.md, "Optional-app coupling" — which governs
   runtime references, not stylesheets).

   Behaviour to match: core/static/core/js/dense-list.js (whole-row click).
   ================================================================== */
.dense-table-card {
    overflow: hidden;
}

.dense-table {
    font-size: 0.85rem;
}

/* padding is core's .table th default (design-system.css) — not restated. */
.dense-table th {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

.dense-table td {
    padding: 6px 10px;
    vertical-align: middle;
}

.dense-table tbody tr {
    cursor: pointer;
}

/* Badges inherit the row's density rather than the page default. */
.dense-table .badge {
    font-size: 0.68rem;
    font-weight: 600;
    padding: 3px 7px;
}

/* Slim left edge for per-row state. The colour is the consumer's to set —
   by class where it is derived state, or inline where it is stored data. */
.dense-table tbody tr td:first-child {
    border-left: 3px solid transparent;
}

/* The one row state that is NOT app-specific: a retired record. Every dense
   list has an active/inactive (or archived) flag, and all four wrote the same
   two rules — grey edge, dimmed row — for it: catalog-items-list.css,
   catalog-suppliers-list.css, inventory-locations-list.css and
   availability-report.css. Promoted here at the fourth copy, same policy as
   .list-cell-primary; the other three retire on next touch.

   Selectors deliberately mirror the app copies' shape (no `tbody`) so they
   carry the SAME specificity: a consumer wanting different dimming — the
   availability report uses 0.7 — then wins on source order, since app
   stylesheets load in the app_css block after this file. Adding `tbody` here
   would raise specificity and silently override them instead. */
.dense-table tr.row-inactive td:first-child {
    border-left-color: var(--bs-secondary-color, #adb5bd);
}

.dense-table tr.row-inactive td {
    opacity: 0.65;
}

/* Icon-only row actions. */
.dense-table .action-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-secondary, #6c757d);
    font-size: 0.78rem;
    text-decoration: none;
    transition: background-color 0.12s ease, color 0.12s ease;
}

.dense-table .action-btn:hover {
    background: rgba(13, 110, 253, 0.12);
    color: #0d6efd;
}

[data-bs-theme="dark"] .dense-table .action-btn { color: #a0aec0; }
[data-bs-theme="dark"] .dense-table .action-btn:hover { background: rgba(77, 171, 247, 0.18); color: #4dabf7; }

@media (max-width: 768px) {
    .dense-table td,
    .dense-table th {
        padding: 6px 6px;
    }
}

/* ==================================================================
   SORTABLE COLUMN HEADERS
   Markup: core/templates/includes/sort_th.html. Opt-in per <th> via
   .col-sortable, so these rules only touch tables that asked for them.
   Lives here rather than in an app stylesheet because two apps
   (operations jobs, crews) now use it and this file loads globally.
   ================================================================== */
th.col-sortable {
    padding: 0;                     /* the link owns the whole cell */
}

th.col-sortable .sort-link {
    display: block;
    padding: 8px 10px;
    color: inherit;
    text-decoration: none;
    transition: color 0.12s ease;
}

/* text-end on the <th> aligns the cell, but the link is a block child —
   inherit the alignment so the label sits where the numbers do. */
th.col-sortable.text-end .sort-link {
    text-align: right;
}

th.col-sortable .sort-icon {
    margin-left: 4px;
    font-size: 0.68rem;
    opacity: 0;                     /* only the sorted column shows one… */
    transition: opacity 0.12s ease;
}

/* …until you hover the header, which is what advertises it as clickable. */
th.col-sortable .sort-link:hover .sort-icon {
    opacity: 0.55;
}

th.col-sortable.sorted .sort-link,
th.col-sortable .sort-link:hover {
    color: var(--bs-primary, #0d6efd);
}

th.col-sortable.sorted .sort-icon {
    opacity: 1;
}

/* Keyboard users get the same affordance the mouse gets. */
th.col-sortable .sort-link:focus-visible {
    outline: 2px solid var(--bs-primary, #0d6efd);
    outline-offset: -2px;
}

th.col-sortable .sort-link:focus-visible .sort-icon {
    opacity: 0.55;
}

@media (max-width: 768px) {
    th.col-sortable .sort-link {
        padding: 6px 6px;
    }

    /* No hover on touch, so the arrow can't be hover-revealed — show a faint
       one on every sortable header instead. */
    th.col-sortable .sort-icon {
        opacity: 0.35;
    }
}
