/* Site theming, ported from the legacy style.css. Pairs with collage.css (background)
   and postcard.css (hero cards). */

body {
    background-color: #424242;
    font-family: "Open Sans", sans-serif;
}

/* Offset anchor jumps (#listen, #watch, #full, ...) below the sticky navbar.
   Scoped to :target (the fragment's destination) rather than a container-wide
   scroll-padding-top on html — a global scroll-padding makes the caret in the
   sticky-nav search box read as "occluded", so every keystroke nudged the page
   upward (the sticky input can never clear the padding zone). scroll-margin-top
   is honored by fragment navigation and scrollIntoView, so jump offsets stay. */
:target {
    scroll-margin-top: 6rem;
}

a {
    text-decoration: none;
}

/* Underline text links on hover/focus so it's obvious they're clickable — the
   cursor change was previously the only cue. Two selectors cover the site's
   content links: (1) the .link-dark convention used for dark text links
   everywhere (song titles, dates, venues, play counts, ...) — the !important
   beats the Bootstrap .text-decoration-none utility many of them also carry;
   (2) plain text links inside data tables. Icon-only links (e.g. the media
   indicators, <a><i class="bi"></i></a>) and styled pills (.guest-pill) are
   excluded so their glyphs/chips don't get an underline. */
a.link-dark:hover,
a.link-dark:focus-visible,
.main-container td a:not(.guest-pill):not(:has(> i.bi)):hover,
.main-container td a:not(.guest-pill):not(:has(> i.bi)):focus-visible {
    text-decoration: underline !important;
}

/* The page content floats in a light card above the dark collage. */
.main-container {
    background-color: #fcfcfc;
    box-shadow: 0 0 12px 0 rgba(50, 50, 50, 0.75);
    border-radius: 2px;
    padding: 1.5rem;
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
}

.navbar {
    box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}

/* Display font for hero titles. */
.bebas-neue-regular,
.song_title {
    font-family: "Bebas Neue", sans-serif;
    font-weight: 400;
    font-style: normal;
}

.song_title {
    font-size: calc(1.475rem + 2.7vw);
    line-height: 1;
}

/* Wide data tables scroll horizontally (within .table-responsive) instead of squishing. */
.my-table-responsive {
    min-width: 1000px;
}

/* ---------------------------------------------------------------------------
   Responsive "card" tables (.table-cards).
   On phones, a wide record table (one row = one record with a handful of
   columns) is horizontally scrollable, which is poor mobile UX. Opting a table
   into `.table-cards` makes it collapse to a stack of cards below the `sm`
   breakpoint (<576px): the <thead> hides, each data <tr> becomes a bordered
   card, and each <td> renders its column name (from `data-label`) as an inline
   label. Desktop/tablet are untouched — the card layout only exists inside the
   media query.

   Group/section header rows (leg / tour-group / disc bands) are detected
   structurally — they're the only rows whose cell carries a `colspan` — so this
   works for EVERY such row regardless of its class (.album-track-group /
   .tour-leg-group / .plays-tour-group / .guest-tour-group / the .table-info
   concert-table header). They stay full-width headings, not cards.

   Per-cell modifiers (add as classes on the <td>):
     .tc-head    — the card's headline (bold, full-width, no label). Use for the
                   primary field (song title, date, guest name).
     .tc-icons   — value is a cluster of icons (a Media cell): pin the label left
                   and pack the icons together at the right instead of fanning
                   them across the row.
     .tc-bar     — value is a relative-frequency bar (% of shows / share of
                   plays): label on its own line, bar full-width below.
     .tc-hide-sm — drop this cell on mobile (e.g. a row-number column whose
                   order is already conveyed by the card sequence).
   A blank labeled cell auto-hides (no stray label); a whitespace-only cell
   (e.g. a Media cell with no icons) must instead be given .tc-hide-sm
   conditionally. Matrix/heatmap tables (date × album) are NOT candidates — they
   can't stack; leave those on horizontal scroll. */
@media (max-width: 575.98px) {
    table.table-cards {
        min-width: 0 !important; /* beat .my-table-responsive so no scroll box is needed */
        display: block;
    }
    table.table-cards thead {
        display: none;
    }
    table.table-cards tbody,
    table.table-cards tbody tr {
        display: block;
    }
    /* Group/section header rows: the single colspanned cell renders as a
       full-width heading (keeps its own band styling from the page's CSS). */
    table.table-cards tbody [colspan] {
        display: block;
    }
    /* Data rows (no colspanned cell) become cards. */
    table.table-cards tbody tr:not(:has(> [colspan])) {
        margin-bottom: 0.6rem;
        padding: 0.5rem 0.85rem;
        border: 1px solid rgba(0, 0, 0, 0.12);
        border-radius: 6px;
        background: #fff;
    }
    /* Status accent on mobile cards. The striping-neutralizer above wipes the
       desktop row tint (table-danger/table-warning cell backgrounds), so the odd
       show would otherwise be an indistinguishable white card. Re-introduce the
       "odd one out" whole-row scan as a colored LEFT EDGE (not a full background
       wash, which would fight the clean-panel look) — paired with the inline
       <x-status-badge> pill in the Detail cell. Class-scoped so it out-specifies
       the base card border above and overrides just the left edge. */
    table.table-cards tbody tr.table-danger:not(:has(> [colspan])) {
        border-left: 4px solid #e26d6d;
    }
    table.table-cards tbody tr.table-warning:not(:has(> [colspan])) {
        border-left: 4px solid #e6b34d;
    }
    /* Neutralize table-striped shading inside the cards so every card is a clean,
       uniform white panel. Bootstrap 5.3 paints stripes with an inset box-shadow
       (not a background), so `background: transparent` alone leaves the stripe on
       the cells but not the card's padding — an inset block with a white border.
       Kill the box-shadow (and the bg for good measure) to remove it entirely. */
    table.table-cards.table-striped > tbody > tr > * {
        background: transparent;
        box-shadow: none;
    }
    /* Each data cell = an inline "Label            value" line: label pinned left,
       value right-aligned; long values wrap onto further right-aligned lines. Kept
       intentionally low-specificity (single class, no `tbody`) so the per-cell
       modifiers below (also single class, WITH `tbody` → higher) reliably win the
       cascade. Header cells ([colspan]) are excluded. */
    table.table-cards td:not([colspan]) {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 1rem;
        padding: 0.2rem 0;
        border: none;
        text-align: right;
        white-space: normal;
    }
    table.table-cards td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-weight: 600;
        color: #6c757d;
        text-align: left;
    }
    /* Headline cell (song title, date, name): full-width, prominent, no label. */
    table.table-cards tbody .tc-head {
        display: block;
        text-align: left;
        font-size: 1.05rem;
        font-weight: 600;
        padding-bottom: 0.35rem;
        margin-bottom: 0.15rem;
        border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    }
    table.table-cards tbody .tc-head::before {
        content: none;
    }
    /* Icon-cluster cell (a Media cell): the generic space-between would fan the
       icons out across the row. Pin the label left (auto margin) and pack the
       icons together at the right — their own margins handle inter-icon spacing,
       so drop the flex gap. */
    table.table-cards tbody td.tc-icons {
        justify-content: flex-end;
        gap: 0;
    }
    table.table-cards tbody td.tc-icons::before {
        margin-right: auto;
    }
    /* Bar cell (a relative-frequency bar): cramming a bar into the right half of an
       inline row reads badly, so give it the label on its own line with the bar
       full-width below — a compact progress row. */
    table.table-cards tbody td.tc-bar {
        display: block;
        text-align: left;
    }
    table.table-cards tbody td.tc-bar[data-label]::before {
        display: block;
        margin-bottom: 0.25rem;
    }
    /* Hide a cell on mobile (e.g. a row-number column). Works on <td> or <th>. */
    table.table-cards tbody .tc-hide-sm {
        display: none;
    }
    /* An empty labeled cell (e.g. a show with no Detail) shows no stray label. */
    table.table-cards td[data-label]:empty {
        display: none;
    }
}

/* ── Show status: badge + softened row tints ─────────────────────────────────
   A self-labeling pill (<x-status-badge>) is the PRIMARY signal that a show
   didn't happen normally — it reads the same on desktop and mobile and doesn't
   depend on the viewer knowing "red row = cancelled". The desktop row tint is
   kept as whole-row reinforcement (softened below); the mobile card carries a
   left-edge accent (in the ≤575.98px block above). One event_type drives all
   three. Palette matches the compare pills (Tailwind red/amber families). */
.status-badge {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    gap: .3em;
    font-size: .78rem;
    font-weight: 600;
    line-height: 1;
    padding: .28em .62em;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
}
.status-badge .bi {
    font-size: .82em;
}
/* Collapse the cell's text-strut (the td's 1.5 line-height sits taller than the
   pill and biases it toward the bottom of the row) so the badge — which vertical-
   aligns middle above — is centered in its cell. Only cells whose content IS a
   badge; the rare muted note beside it restores a comfortable line-height. */
td:has(> .status-badge) {
    line-height: 1;
}
td:has(> .status-badge) .status-detail-text {
    line-height: 1.3;
}
.status-badge--danger {
    background: #fef2f2;
    color: #b91c1c;
    border-color: #fca5a5;
}
.status-badge--warning {
    background: #fffbeb;
    color: #b45309;
    border-color: #fcd34d;
}
/* Any real Detail text that survives beside a status badge (e.g. a postponed
   show's note) reads as a muted sub-note. */
.status-detail-text {
    color: #6c757d;
    font-size: .9em;
}
.status-badge--success {
    background: #ecfdf5;
    color: #15803d;
    border-color: #86efac;
}
.status-badge + .status-badge {
    margin-left: .4em;
}
.status-badge + .status-detail-text {
    margin-left: .4em;
}

/* Soften Bootstrap's default .table-danger / .table-warning row tints to the
   brand's lighter red/amber (its defaults are more saturated than the rest of
   the site). Used ONLY for cancelled/postponed/unconfirmed show rows across the
   six listing tables, so redefining them globally keeps all six consistent.
   Overriding the CSS variables (not a flat background) keeps the striped/hover
   interplay intact. Text stays the default dark. */
.table-danger {
    --bs-table-bg: #fdecec;
    --bs-table-border-color: #f5d5d5;
    --bs-table-striped-bg: #f8e3e3;
    --bs-table-striped-color: #212529;
    --bs-table-hover-bg: #f6dada;
    --bs-table-hover-color: #212529;
    --bs-table-color: #212529;
}
.table-warning {
    --bs-table-bg: #fdf4dd;
    --bs-table-border-color: #f4e3b0;
    --bs-table-striped-bg: #f8ecca;
    --bs-table-striped-color: #212529;
    --bs-table-hover-bg: #f6e6bb;
    --bs-table-hover-color: #212529;
    --bs-table-color: #212529;
}

/* Section header: left-aligned Bebas Neue title with a full-width underline.
   The generous top margin IS the section separator (whitespace + this underline);
   there are no divider elements between sections. */
.subsection-header {
    border-bottom: 0.1rem solid #aeb0b2;
    margin-top: 5rem;
}
/* A section header that is the very first thing in the content (e.g. the homepage's
   "1970s") has nothing above it to separate from, so drop the 5rem lead-in. On detail
   pages the hero postcard is the first child, so this only affects the homepage. */
.main-container > .subsection-header:first-child {
    margin-top: 0;
}
.subsection-header h2 {
    font-size: 2rem;
}
/* Optional small link at the right end of a section header (<x-slot:action>). */
.subsection-header__action a {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .25rem .8rem;
    border: 1px solid #c8102e;
    border-radius: 999px;
    color: #c8102e;
    font-size: .85rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.subsection-header__action a:hover,
.subsection-header__action a:focus-visible {
    background: #c8102e;
    color: #fff;
}

/* Centered logo divider: the page end mark, rendered once by the layout before the footer. */
.fr-divider-custom {
    margin: 1.25rem 0 1.5rem;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}
.fr-divider-custom .fr-divider-custom-line {
    width: 100%;
    max-width: 7rem;
    height: 0.1rem;
    background-color: #2c3e50;
    border-radius: 1rem;
}
.fr-divider-custom .fr-divider-custom-line:first-child {
    margin-right: 1rem;
}
.fr-divider-custom .fr-divider-custom-line:last-child {
    margin-left: 1rem;
}
.fr-divider-custom-icon img {
    height: 30px;
}

/* Back-to-top button. */
.back-to-top {
    width: 50px;
    height: 50px;
    position: fixed;
    z-index: 1079;
    right: 20px;
    bottom: 20px;
    line-height: 50px;
    border: 2px solid #f5f5f5;
    border-radius: 50%;
    color: #f5f5f5;
    text-align: center;
    background: #000;
    box-shadow: 0 0 3px gray;
    font-size: 20px;
}
.back-to-top:hover {
    background: #c8102e;
    color: #fff;
}

/* Video facade (click-to-load thumbnails) — used site-wide by <x-video-card> and
   <x-live-video-card>. The card shows the real YouTube thumbnail with a play
   overlay; the player iframe is injected on click (public/js/video-facade.js). */
.vlp-facade {
    /* No position override here — Bootstrap's `.ratio > *` makes this absolute so
       it overlays the aspect-ratio spacer. Setting position:relative would drop it
       below the spacer and add phantom top padding. It's still a containing block
       for the .vlp-play overlay either way. */
    display: block;
    padding: 0;
    border: 0;
    background: #000;
    cursor: pointer;
    overflow: hidden;
}
.vlp-thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.3s ease, opacity 0.2s ease;
}
.vlp-facade:hover .vlp-thumb,
.vlp-facade:focus-visible .vlp-thumb {
    transform: scale(1.04);
    opacity: 0.85;
}
.vlp-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 68px;
    height: 48px;
    border-radius: 14px;
    background: rgba(24, 21, 31, 0.78);
    transition: background-color 0.2s ease;
    pointer-events: none;
}
.vlp-play::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-40%, -50%);
    border-style: solid;
    border-width: 10px 0 10px 17px;
    border-color: transparent transparent transparent #fff;
}
.vlp-facade:hover .vlp-play,
.vlp-facade:focus-visible .vlp-play {
    background: #ff0000;
}

/* Site footer ("fat footer"): brand block + link columns over a slim bottom bar.
   Sits inside .main-container (white card), after the page-end logo divider.
   Rendered as a RECESSED TRAY, not a section: a full-bleed panel that reaches the
   card's edges (negative margins cancel the card's 1.5rem padding) with a whisper
   tint + an inset top shadow, so it reads as a sunken shelf / chrome — a different
   plane from the content sections above (which separate with whitespace + a hairline
   underline). A thin red keyline at the top adds brand punch. NO border-top hairline
   here (that's what made it look like just another section). The negative side/bottom
   margins must match .main-container's padding; the bottom radius matches the card. */
.site-footer {
    color: #495057;
    background: #eef0f2;
    margin: 5rem -1.5rem -1.5rem;
    padding: 2rem 1.5rem 1.25rem;
    border-top: 3px solid #c8102e;
    border-bottom-left-radius: 2px;
    border-bottom-right-radius: 2px;
    box-shadow: inset 0 8px 8px -8px rgba(0, 0, 0, 0.14);
}
/* On mobile the card padding tightens (Bootstrap default container gutters still apply
   inside .main-container's 1.5rem); keep the full-bleed correct there too. */
@media (max-width: 575.98px) {
    .site-footer {
        margin-top: 3.5rem;
    }
}
.site-footer__brandlink {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
    color: inherit;
}
.site-footer__logo {
    height: 34px;
    width: auto;
}
.site-footer__wordmark {
    font-size: 1.8rem;
    line-height: 1;
    color: #212529;
}
.site-footer__tagline {
    margin: 0.65rem 0 0;
    max-width: 30ch;
    font-size: 0.875rem;
    color: #6c757d;
}
/* Contribute CTA under the brand tagline (a pre-filled mailto). */
.site-footer__contribute {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.6rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: #c8102e;
    text-decoration: none;
}
.site-footer__contribute:hover,
.site-footer__contribute:focus {
    color: #a00d24;
    text-decoration: underline;
}
.site-footer__heading {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #212529;
    margin-bottom: 0.75rem;
}
.site-footer__col ul {
    margin: 0;
}
.site-footer__col li {
    margin-bottom: 0.4rem;
}
.site-footer__col a,
.site-footer__linkbtn {
    color: #6c757d;
    text-decoration: none;
    font-size: 0.925rem;
    transition: color 0.15s ease;
}
.site-footer__col a:hover,
.site-footer__col a:focus,
.site-footer__linkbtn:hover,
.site-footer__linkbtn:focus {
    color: #c8102e;
    text-decoration: underline;
}
/* "Sign out" is a POST form button styled to read as a plain footer link. */
.site-footer__linkbtn {
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}
.site-footer__note {
    margin-top: 0.35rem;
    font-size: 0.825rem;
    color: #adb5bd;
    max-width: 32ch;
}
.site-footer__legal {
    font-size: 0.825rem;
}
.site-footer__sep {
    margin: 0 0.4rem;
    opacity: 0.6;
}
.site-footer__social a:hover {
    color: #c8102e !important;
}
/* Stack the legal line's two clauses on very narrow screens. */
@media (max-width: 575.98px) {
    .site-footer__sep {
        display: none;
    }
    .site-footer__legal span {
        display: block;
    }
}
