/* Catalogue surfaces: tests, suites, coverage and products.
   Everything here composes design-system tokens — no hex values, no px font sizes, no off-grid
   spacing. Anything that turns out to be needed by a third area belongs in the design system,
   not in another copy of it here. */

/* ── Filter bar ──────────────────────────────────────────────────────────────────────────── */

.qp-filters {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--qp-space-2);
    margin-bottom: var(--qp-space-4);
}

.qp-filters__search {
    flex: 1 1 260px;
    min-width: 200px;
    max-width: 380px;
}

/* ── Choose-a-product prompt ─────────────────────────────────────────────────────────────── */

.qp-product-prompt {
    display: flex;
    flex-direction: column;
    gap: var(--qp-space-2);
}

.qp-product-prompt__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 340px));
    justify-content: center;
    gap: var(--qp-space-3);
    margin: 0 auto var(--qp-space-8);
    width: 100%;
    max-width: 760px;
}

.qp-product-prompt__card {
    display: flex;
    flex-direction: column;
    gap: var(--qp-space-2);
    padding: var(--qp-space-4) var(--qp-space-5);
    border: 1px solid var(--qp-border-subtle);
    border-radius: var(--qp-radius-lg);
    background: var(--qp-surface);
    color: inherit;
    font: inherit;
    text-align: start;
    cursor: pointer;
    transition: border-color var(--qp-duration-fast) var(--qp-ease), box-shadow var(--qp-duration-fast) var(--qp-ease);
}

.qp-product-prompt__card:hover {
    border-color: var(--qp-accent-border);
    box-shadow: var(--qp-shadow-1);
}

.qp-product-prompt__name {
    color: var(--qp-text-strong);
    font-size: var(--qp-text-md);
    font-weight: var(--qp-weight-medium);
}

.qp-product-prompt__facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--qp-space-2);
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
}

/* ── Bulk selection bar ──────────────────────────────────────────────────────────────────── */

.qp-bulkbar {
    display: flex;
    align-items: center;
    gap: var(--qp-space-3);
    margin-bottom: var(--qp-space-3);
    padding: var(--qp-space-3) var(--qp-space-4);
    border: 1px solid var(--qp-accent-border);
    border-radius: var(--qp-radius-md);
    background: var(--qp-accent-subtle);
    color: var(--qp-accent-text);
    font-size: var(--qp-text-sm);
}

.qp-bulkbar__count {
    font-weight: var(--qp-weight-medium);
    font-variant-numeric: tabular-nums;
}

/* Stops a checkbox in a clickable row from also opening the row. */
.qp-row-select {
    display: inline-flex;
    align-items: center;
}

/* ── Meta panel extras ───────────────────────────────────────────────────────────────────── */

.qp-panel__title {
    margin: 0 0 var(--qp-space-3);
    color: var(--qp-text-strong);
    font-size: var(--qp-text-sm);
    font-weight: var(--qp-weight-semibold);
    letter-spacing: var(--qp-tracking-tight);
}

.qp-tag-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--qp-space-1);
    align-items: center;
}

/* In a table the tags have to stay on one line, or three tags triple the row height and the list
   stops being scannable. The metadata panel keeps the wrapping version. */
.qp-tag-row--inline {
    flex-wrap: nowrap;
    overflow: hidden;
    min-width: 0;
    max-width: 100%;
}

/* Identifiers are read as one token; wrapping "TC-0001" across two lines is never right. */
.qp-catalogue-id {
    white-space: nowrap;
}

/* ── Code-backed source panel ────────────────────────────────────────────────────────────── */

.qp-source {
    display: grid;
    gap: var(--qp-space-4);
}

.qp-source__path {
    padding: var(--qp-space-3) var(--qp-space-4);
    border-radius: var(--qp-radius-sm);
    background: var(--qp-surface-sunken);
    color: var(--qp-text);
    font-family: var(--qp-font-mono);
    font-size: var(--qp-text-xs);
    overflow-wrap: anywhere;
}

/* ── Suite membership list ───────────────────────────────────────────────────────────────── */

.qp-members {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--qp-border-subtle);
    border-radius: var(--qp-radius-lg);
    overflow: hidden;
}

.qp-member {
    display: flex;
    align-items: center;
    gap: var(--qp-space-3);
    padding: var(--qp-space-3) var(--qp-space-4);
    background: var(--qp-surface);
    border-bottom: 1px solid var(--qp-border-subtle);
}

.qp-member:last-child {
    border-bottom: 0;
}

.qp-member:hover {
    background: var(--qp-surface-hover);
}

/* SortableJS puts this on the row being dragged and on its placeholder. */
.qp-member--ghost {
    opacity: 0.4;
}

.qp-member--drag {
    box-shadow: var(--qp-shadow-2);
}

.qp-member__handle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border: 0;
    border-radius: var(--qp-radius-xs);
    background: transparent;
    color: var(--qp-text-faint);
    cursor: grab;
}

.qp-member__handle:hover {
    color: var(--qp-text-muted);
    background: var(--qp-surface-active);
}

.qp-member__order {
    min-width: 24px;
    color: var(--qp-text-faint);
    font-size: var(--qp-text-xs);
    font-variant-numeric: tabular-nums;
    text-align: end;
}

.qp-member__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1;
}

.qp-member__name {
    color: var(--qp-text-strong);
    font-size: var(--qp-text-sm);
}

.qp-member__meta {
    display: flex;
    align-items: center;
    gap: var(--qp-space-2);
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
}

/* ── Rule builder ────────────────────────────────────────────────────────────────────────── */

.qp-rules {
    display: flex;
    flex-direction: column;
    gap: var(--qp-space-3);
}

.qp-rule {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--qp-space-2);
    padding: var(--qp-space-3);
    border: 1px solid var(--qp-border-subtle);
    border-radius: var(--qp-radius-md);
    background: var(--qp-surface);
}

.qp-rule__joiner {
    min-width: 46px;
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
    text-transform: uppercase;
    letter-spacing: var(--qp-tracking-wide);
}

.qp-rule__field {
    min-width: 150px;
}

.qp-rule__op {
    min-width: 130px;
}

.qp-rule__value {
    flex: 1 1 200px;
    min-width: 160px;
}

.qp-rules__summary {
    padding: var(--qp-space-3) var(--qp-space-4);
    border-radius: var(--qp-radius-md);
    background: var(--qp-surface-sunken);
    color: var(--qp-text);
    font-size: var(--qp-text-sm);
    line-height: var(--qp-leading-relaxed);
}

/* ── Coverage ────────────────────────────────────────────────────────────────────────────── */

.qp-coverage {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--qp-border-subtle);
    border-radius: var(--qp-radius-lg);
    overflow: hidden;
    background: var(--qp-surface);
}

.qp-coverage__row {
    display: grid;
    grid-template-columns: minmax(180px, 1.4fr) minmax(160px, 2fr) 96px 64px;
    align-items: center;
    gap: var(--qp-space-4);
    padding: var(--qp-space-3) var(--qp-space-4);
    border-bottom: 1px solid var(--qp-border-subtle);
}

.qp-coverage__row:last-child {
    border-bottom: 0;
}

.qp-coverage__row[data-level="module"] {
    background: var(--qp-surface-sunken);
}

.qp-coverage__row[data-level="feature"] .qp-coverage__label {
    padding-inline-start: var(--qp-space-5);
    color: var(--qp-text-muted);
}

.qp-coverage__label {
    min-width: 0;
    color: var(--qp-text-strong);
    font-size: var(--qp-text-sm);
}

.qp-coverage__row[data-level="module"] .qp-coverage__label {
    font-weight: var(--qp-weight-medium);
}

.qp-coverage__head {
    color: var(--qp-text-muted);
    font-size: var(--qp-text-2xs);
    text-transform: uppercase;
    letter-spacing: var(--qp-tracking-wide);
}

/* A stacked bar rather than four numbers: the shape of the mix is the thing worth seeing. */
.qp-bar {
    display: flex;
    height: 8px;
    border-radius: var(--qp-radius-full);
    overflow: hidden;
    background: var(--qp-surface-active);
}

.qp-bar__part {
    height: 100%;
}

.qp-bar__part[data-kind="automated"] {
    background: var(--qp-pass);
}

.qp-bar__part[data-kind="partial"] {
    background: var(--qp-info);
}

.qp-bar__part[data-kind="manual"] {
    background: var(--qp-warn);
}

.qp-bar__part[data-kind="candidate"] {
    background: var(--qp-neutral);
}

.qp-coverage__share {
    color: var(--qp-text);
    font-size: var(--qp-text-sm);
    font-variant-numeric: tabular-nums;
    text-align: end;
}

.qp-coverage__total {
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
    font-variant-numeric: tabular-nums;
    text-align: end;
}

.qp-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--qp-space-4);
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
}

.qp-legend__item {
    display: inline-flex;
    align-items: center;
    gap: var(--qp-space-2);
}

.qp-legend__swatch {
    width: 10px;
    height: 10px;
    border-radius: var(--qp-radius-xs);
}

/* ── Requirement drill-down ──────────────────────────────────────────────────────────────── */

.qp-requirements {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--qp-border-subtle);
    border-radius: var(--qp-radius-lg);
    overflow: hidden;
}

.qp-requirement {
    border-bottom: 1px solid var(--qp-border-subtle);
}

.qp-requirement:last-child {
    border-bottom: 0;
}

.qp-requirement__row {
    display: flex;
    align-items: center;
    gap: var(--qp-space-2);
    width: 100%;
    min-width: 0;
    padding: var(--qp-space-3) var(--qp-space-4);
    border: 0;
    background: var(--qp-surface);
    color: var(--qp-text);
    font: inherit;
    font-size: var(--qp-text-sm);
    text-align: start;
    cursor: pointer;
}

.qp-requirement__row:hover {
    background: var(--qp-surface-hover);
}

.qp-requirement__key {
    flex: 0 0 auto;
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
}

.qp-requirement__title {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--qp-text-strong);
}

.qp-requirement__where {
    flex: 0 1 auto;
    max-width: 200px;
    color: var(--qp-text-faint);
    font-size: var(--qp-text-xs);
}

.qp-requirement__share {
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
    font-variant-numeric: tabular-nums;
}

/* An uncovered requirement carries a warning hairline, so the gaps are findable by scrolling rather
   than only by reading every badge. */
.qp-requirement[data-covered="false"] .qp-requirement__row {
    box-shadow: inset 3px 0 0 var(--qp-warn);
}

.qp-requirement__body {
    padding: var(--qp-space-4) var(--qp-space-5) var(--qp-space-4) var(--qp-space-10);
    background: var(--qp-surface-sunken);
}

@media (max-width: 899px) {
    .qp-requirement__where {
        display: none;
    }
}

/* ── Product cards ───────────────────────────────────────────────────────────────────────── */

.qp-product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: var(--qp-space-4);
}

.qp-product-card {
    display: flex;
    flex-direction: column;
    gap: var(--qp-space-3);
    padding: var(--qp-space-5);
    border: 1px solid var(--qp-border-subtle);
    border-radius: var(--qp-radius-lg);
    background: var(--qp-surface);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--qp-duration-fast) var(--qp-ease), box-shadow var(--qp-duration-fast) var(--qp-ease);
}

.qp-product-card:hover {
    border-color: var(--qp-border-strong);
    box-shadow: var(--qp-shadow-1);
}

.qp-product-card__facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--qp-space-4);
    color: var(--qp-text-muted);
    font-size: var(--qp-text-xs);
}

.qp-product-card__fact {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.qp-product-card__value {
    color: var(--qp-text-strong);
    font-size: var(--qp-text-md);
    font-variant-numeric: tabular-nums;
}

/* ── Environment rows ────────────────────────────────────────────────────────────────────── */

.qp-env {
    display: flex;
    align-items: flex-start;
    gap: var(--qp-space-3);
    padding: var(--qp-space-4);
    border-bottom: 1px solid var(--qp-border-subtle);
}

.qp-env:last-child {
    border-bottom: 0;
}

.qp-env__flags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--qp-space-2);
    margin-top: var(--qp-space-2);
}

/* A flag that is off should read as off without anyone having to resolve an 11px glyph.
   The strike-through is what says "off"; it used to be opacity: 0.55 as well, which took an 11px
   label to 3.11:1 in dark — axe flagged every one of them. Dimming by opacity always costs contrast,
   because it blends the text toward whatever is behind it. The muted token is AA by construction. */
.qp-env__flags [data-allowed="false"] {
    color: var(--qp-text-muted);
    text-decoration: line-through;
}

@media (max-width: 900px) {
    .qp-coverage__row {
        grid-template-columns: minmax(140px, 1fr) minmax(100px, 1.4fr) 72px;
    }

    .qp-coverage__total {
        display: none;
    }
}
