/*
 * Vision System application layout.
 *
 * The page shell supplies AppKit. This sheet owns only Vision's page-specific
 * composition; cards, filterbar, chips, rows, badges, type, and materials are
 * shared AppKit components and tokens.
 */

.vision-system-page .vs-data > .portal-rise-in {
    animation-delay: 60ms;
}

/* The application page header already names the page. The fragment's title is
   for the public/empty composition, so only its event date remains here. */
.vision-system-page .vs-title {
    display: none;
}

.vision-system-page .vs-header {
    margin-bottom: var(--portal-space-3);
}

.vision-system-page .vs-date,
.vision-system-page .vs-priority-meta,
.vision-system-page .vs-priority-empty,
.vision-system-page .vs-lane-meta,
.vision-system-page .vs-lane-empty {
    color: var(--portal-c-text-muted);
    font-family: var(--portal-font-mono);
    font-size: var(--portal-text-xs);
}

.vision-system-page .vs-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--portal-space-2);
    padding: var(--portal-space-7) var(--portal-space-4);
}

.vision-system-page .vs-empty-title {
    color: var(--portal-c-text);
    font-size: var(--portal-text-lg);
    font-weight: var(--portal-weight-label);
}

.vision-system-page .vs-empty-note {
    color: var(--portal-c-text-muted);
    font-size: var(--portal-text-sm);
}

.vision-system-page .vs-no-matches {
    margin-top: var(--portal-space-4);
}

/* QR needs a light quiet zone to remain scannable; Bootstrap's theme token is
   the shared source for that surface rather than a page-owned colour. */
.vision-system-page .vs-qr-code {
    display: inline-block;
    margin-bottom: var(--portal-space-3);
    padding: var(--portal-space-4);
    border-radius: var(--bs-border-radius);
    background: var(--bs-white);
}

.vision-system-page .vs-qr-code svg {
    display: block;
    width: 14rem;
    height: 14rem;
}

.vision-system-page .vs-qr-url,
.vision-system-page .vs-qr-hint {
    color: var(--portal-c-text-muted);
    font-size: var(--portal-text-sm);
}

.vision-system-page .vs-qr-url {
    margin-bottom: var(--portal-space-2);
    color: var(--portal-c-text);
    word-break: break-all;
}

/* "How it works" guide: a label column beside each explanation, stacking on
   a phone. */
.vision-system-page .vs-help {
    color: var(--portal-c-text);
    font-size: var(--portal-text-sm);
}

.vision-system-page .vs-help .vs-help-lead {
    font-size: var(--portal-text-base);
}

.vision-system-page .vs-help .portal-stat-label {
    margin-top: var(--portal-space-4);
    margin-bottom: var(--portal-space-2);
}

.vision-system-page .vs-help-list {
    display: grid;
    grid-template-columns: minmax(8.5rem, max-content) minmax(0, 1fr);
    gap: var(--portal-space-2) var(--portal-space-3);
    align-items: baseline;
    margin-bottom: var(--portal-space-3);
}

.vision-system-page .vs-help-list dt {
    color: var(--portal-c-text);
    font-family: var(--portal-font-mono);
    font-size: var(--portal-label-size);
    font-weight: var(--portal-label-weight);
    letter-spacing: var(--portal-label-tracking);
    text-transform: uppercase;
}

.vision-system-page .vs-help-list dd {
    margin: 0;
    color: var(--portal-c-text-muted);
}

.vision-system-page .vs-help-notes {
    margin-bottom: 0;
    padding-left: var(--portal-space-4);
    color: var(--portal-c-text-muted);
}

.vision-system-page .vs-help-notes li + li {
    margin-top: var(--portal-space-1);
}

@media (max-width: 575.98px) {
    .vision-system-page .vs-help-list {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .vision-system-page .vs-help-list dd {
        margin-bottom: var(--portal-space-2);
    }
}

/* AppKit filterbar + interactive chips. The shared chip's aria-pressed style
   is the selected state; no second button skin lives on this page. */
/* The wrapper is the size container the bar queries. It is not the page
   itself: containment on <main> would trap the help modal's fixed positioning. */
.vision-system-page .vs-filter-wrap {
    container-type: inline-size;
}

/* Narrow and mid widths: everything left-aligned, one tidy stack. View and TV
   layout are never pushed to the far edge on a line of their own. */
.vision-system-page .vs-filter-bar {
    position: relative;
    z-index: 20;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--portal-space-3);
    /* A quiet rule closes the controls off from the cages below. */
    padding-bottom: var(--portal-space-3);
    border-bottom: 1px solid var(--portal-c-edge-control);
    margin-bottom: var(--portal-space-4);
}

/* A label never separates from its chips: each label+chips pair is one
   .vs-filter-set that wraps as a unit, and only the chips inside a set wrap
   among themselves. */
.vision-system-page .vs-filter-group {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--portal-space-3) var(--portal-space-5);
    min-width: 0;
}

/* Wide enough for both clusters on one line (measured: ~55rem of chips, labels
   and gaps): Show cages hugs the left, View +
   TV layout hug the right. */
@container (min-width: 57rem) {
    .vision-system-page .vs-filter-bar {
        flex-direction: row;
        justify-content: space-between;
        gap: var(--portal-space-3) var(--portal-space-5);
    }

    .vision-system-page .vs-filter-group--end {
        justify-content: flex-end;
        margin-left: auto;
    }
}

.vision-system-page .vs-filter-set {
    display: flex;
    align-items: baseline;
    gap: var(--portal-space-2);
    min-width: 0;
}

.vision-system-page .vs-filter-bar .portal-stat-label {
    flex: 0 0 auto;
}

.vision-system-page .vs-filter-pills {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--portal-space-2);
}

.vision-system-page .vs-filter-pill {
    min-width: 2.25rem;
    justify-content: center;
}

.vision-system-page .vs-portal-priority {
    margin-bottom: var(--portal-space-5);
}

.vision-system-page .vs-portal-queues {
    margin-bottom: var(--portal-space-4);
}

.vision-system-page .vs-portal-priority > .portal-group-head,
.vision-system-page .vs-portal-queues > .portal-group-head {
    margin-bottom: var(--portal-space-2);
}

.vision-system-page .vs-priority-grid,
.vision-system-page .vs-portal-lanes {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--portal-space-3);
}

.vision-system-page .vs-portal-lanes {
    align-items: start;
}

.vision-system-page .vs-priority-card,
.vision-system-page .vs-cage-lane {
    min-width: 0;
}

.vision-system-page .vs-priority-card .card-body,
.vision-system-page .vs-cage-lane .portal-card-header {
    padding: var(--portal-space-3);
}

.vision-system-page .vs-priority-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--portal-space-2);
}

.vision-system-page .vs-priority-matchup,
.vision-system-page .vs-lane-bots {
    display: flex;
    align-items: baseline;
    gap: var(--portal-space-1);
    min-width: 0;
    overflow: hidden;
    color: var(--portal-c-text);
    font-size: var(--portal-text-sm);
    font-weight: var(--portal-weight-label);
    white-space: nowrap;
}

.vision-system-page .vs-priority-matchup {
    margin-top: var(--portal-space-2);
}

.vision-system-page .vs-priority-matchup > span:not(.vs-vs),
.vision-system-page .vs-lane-bots > span:not(.vs-vs) {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.vision-system-page .vs-vs {
    flex: 0 0 auto;
    color: var(--portal-c-text-muted);
    font-size: var(--portal-text-xs);
    font-style: italic;
    font-weight: var(--portal-weight-body);
}

.vision-system-page .vs-priority-meta {
    margin-top: var(--portal-space-1);
}

.vision-system-page .vs-priority-empty {
    margin-top: var(--portal-space-3);
}

.vision-system-page .vs-cage-lane {
    overflow: hidden;
}

.vision-system-page .vs-cage-lane .portal-card-header-hint {
    margin-left: 0;
}

.vision-system-page .vs-lane-list {
    border-top: 1px solid var(--portal-c-border-subtle);
}

.vision-system-page .vs-lane-fight {
    display: grid;
    grid-template-columns: 3.8rem minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--portal-space-2);
    min-height: 4.1rem;
    padding: var(--portal-space-2) var(--portal-space-3);
}

.vision-system-page .vs-lane-position {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.vision-system-page .vs-lane-position .vs-queue-num {
    color: var(--portal-c-text);
    font-family: var(--portal-font-mono);
    font-size: var(--portal-text-sm);
    font-variant-numeric: tabular-nums;
}

.vision-system-page .vs-lane-position .vs-queue-label {
    overflow: hidden;
    color: var(--portal-c-text-muted);
    font-family: var(--portal-font-mono);
    font-size: var(--portal-label-size-sm);
    font-weight: var(--portal-label-weight);
    letter-spacing: var(--portal-label-tracking);
    text-overflow: ellipsis;
    text-transform: uppercase;
}

.vision-system-page .vs-lane-match {
    min-width: 0;
}

/* Alert deep link (?highlight=<bot>): the called bot's queue rows glow.
   Inset ring — .vs-cage-lane clips overflow, so an outer shadow would be
   cut off at the card edge. */
.vision-system-page .vs-cell--highlight {
    box-shadow: inset 0 0 0 2px var(--portal-c-accent-border);
    background: color-mix(in srgb, var(--portal-c-accent) 8%, transparent);
}

.vision-system-page .vs-lane-empty {
    padding: var(--portal-space-5) var(--portal-space-3);
    text-align: center;
}

@media (max-width: 1399.98px) {
    .vision-system-page .vs-priority-grid,
    .vision-system-page .vs-portal-lanes {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767.98px) {
    .vision-system-page .vs-filter-bar,
    .vision-system-page .vs-filter-group {
        flex-direction: column;
        align-items: stretch;
        width: 100%;
    }

    .vision-system-page .vs-filter-group--end {
        justify-content: flex-start;
        margin-left: 0;
    }

    /* Both are about driving a TV from a desk; on a phone they are noise. */
    .vision-system-page .vs-filter-set--tv,
    .vision-system-page #vs-open-tv {
        display: none;
    }

    .vision-system-page .vs-priority-grid,
    .vision-system-page .vs-portal-lanes {
        grid-template-columns: 1fr;
    }

    /* Wide enough for "STAGING" on one line — a mid-word break ("STAGIN/G")
       read as a typo. Two-word labels may still wrap between words. */
    .vision-system-page .vs-lane-fight {
        grid-template-columns: 4.8rem minmax(0, 1fr);
    }

    .vision-system-page .vs-lane-position .vs-queue-label {
        overflow-wrap: normal;
        word-break: keep-all;
    }

    .vision-system-page .vs-lane-fight > .portal-status-badge {
        grid-column: 2;
        justify-self: start;
    }
}

@media (prefers-reduced-motion: reduce) {
    .vision-system-page .vs-data > .portal-rise-in {
        animation-delay: 0ms;
    }
}

/* ── Two views of the same feed ───────────────────────────────────────────
   Classic (default): the at-cage strip, then each cage's queue.
   Cages: one card per cage — the TV wall's own card (tv-page-vision-system.css).
   The View chips set [data-vs-view] on #vs-data; with no attribute yet the
   page is classic. */
.vision-system-page .vs-view--cages,
.vision-system-page .vs-data[data-vs-view="cages"] .vs-view--classic {
    display: none;
}

.vision-system-page .vs-data[data-vs-view="cages"] .vs-view--cages {
    display: block;
}

.vision-system-page .vs-view--cages .vs-tv-grid {
    grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
    align-items: start;
}

.vision-system-page .vs-tv-cage {
    min-width: 0;
}

/* ── Sport: the BrettZone card finish for the classic view ───────────────
   Same notched corner, gradient and heavy caps as the TV wall, so both views
   read as one product. Gated on the theme; the other themes keep AppKit's
   own card. */
html[data-portal-theme="sport"] .vision-system-page .vs-priority-card,
html[data-portal-theme="sport"] .vision-system-page .vs-cage-lane {
    position: relative;
    border-color: var(--bz-border-strong);
    background: linear-gradient(105deg, var(--bz-surface-2), var(--bz-surface-1));
    clip-path: polygon(0 0, calc(100% - 0.75rem) 0, 100% 0.75rem, 100% 100%, 0 100%);
}

html[data-portal-theme="sport"] .vision-system-page .vs-priority-card::after,
html[data-portal-theme="sport"] .vision-system-page .vs-cage-lane::after {
    position: absolute;
    top: 0.3rem;
    right: -0.15rem;
    width: 1.05rem;
    height: 2px;
    background: var(--bz-border-strong);
    transform: rotate(45deg);
    content: '';
}

html[data-portal-theme="sport"] .vision-system-page .vs-priority-matchup,
html[data-portal-theme="sport"] .vision-system-page .vs-lane-bots {
    font-weight: var(--portal-weight-strong);
}

html[data-portal-theme="sport"] .vision-system-page .vs-priority-matchup {
    font-size: var(--portal-text-lg);
}

html[data-portal-theme="sport"] .vision-system-page .portal-ios-group-title {
    color: var(--bz-w3);
    letter-spacing: var(--portal-label-tracking);
}

/* The gradient above would otherwise paint over the alert glow's tint. */
html[data-portal-theme="sport"] .vision-system-page .vs-priority-card.vs-cell--highlight,
html[data-portal-theme="sport"] .vision-system-page .vs-cage-lane.vs-cell--highlight {
    background: color-mix(in srgb, var(--portal-c-accent) 14%, var(--bz-surface-1));
}
