/* ===========================================================================
   Entity detail pages — venue and artist.

   Replaces details_page.css and the first 235 lines of artist_page.css, which
   were the same file twice. One naming system, prefixed dp- (detail page):

     .dp-hero      page header, with or without a backdrop image
     .dp-stats     the at-a-glance figure strip under it
     .dp-layout    main column + sidebar
     .dp-section   a titled block, .dp-head its hairline header
     .dp-list      date-railed gig rows, the shape used on the homepage
     .dp-chips     compact link sets (cities, venues, bill-mates)
     .dp-card      a sidebar widget
     .dp-strip     horizontally scrolling media/album rail

   Deliberately mirrors home.css so a visitor moving from the homepage to a
   venue or artist page is looking at one site rather than three.
   =========================================================================== */

:root {
    --dp-max: 1280px;
    --dp-gut: 1.5rem;
    /* What the free-tools strip at the foot of the page matches itself to.
       It is rendered outside .dp-layout, so it carries its own width --
       see .tl-more--standalone in components.css. */
    --tl-strip-max: 1280px;
    --tl-strip-gut: 1.5rem;
    --dp-red: #ff0000;
    --dp-red-dim: #cc0000;
    --dp-red-soft: #ff4444;
    --dp-line: rgba(255, 255, 255, 0.10);
    --dp-line-soft: rgba(255, 255, 255, 0.06);
    --dp-surface: #101010;
    --dp-surface-2: #161616;
    --dp-muted: #8a8a8a;
    --dp-text: #d8d8d8;
}

/* ---------------------------------------------------------------------------
   Breadcrumb
   --------------------------------------------------------------------------- */

.dp-crumbs {
    max-width: var(--dp-max);
    margin: 0 auto;
    /* The fixed header is 89px tall but layout.css only reserves 60px on
       <main>, so the first 29px of any page sits behind it. Rather than move a
       site-wide value under two pages' worth of testing, the crumbs carry
       enough top padding to clear it. */
    padding: 3rem var(--dp-gut) 0;
    font-size: 0.78rem;
    color: var(--dp-muted);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.dp-crumbs a {
    color: var(--dp-muted);
    text-decoration: none;
    transition: color 0.2s ease;
}

.dp-crumbs a:hover {
    color: #fff;
}

.dp-crumbs span[aria-current] {
    color: #fff;
}

.dp-crumbs .sep {
    opacity: 0.45;
    font-size: 0.7rem;
}

/* ---------------------------------------------------------------------------
   Hero
   --------------------------------------------------------------------------- */

.dp-hero {
    position: relative;
    overflow: hidden;
    margin-top: 0.9rem;
    /* No fixed height. The old header was locked to 400px, so a venue with a
       long name and four facts was cramped while an artist with a name and
       nothing else got 320px of empty gradient. */
    padding: clamp(2rem, 5vw, 3.25rem) 0 clamp(1.75rem, 4vw, 2.5rem);
    border-top: 1px solid var(--dp-line-soft);
    border-bottom: 1px solid var(--dp-line);
    background: linear-gradient(150deg, #141414 0%, #1b0c0c 55%, #240808 100%);
}

/* Backdrop, used only when the page actually has a picture of its subject —
   an approved fan photo, the next gig's artwork, or the artist portrait. The
   old design put the same stock crowd shot behind all 1,298 venues. */
.dp-hero-media {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    filter: blur(22px) saturate(0.8);
    transform: scale(1.12);
    opacity: 0.5;
}

.dp-hero::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(120% 100% at 15% 0%, rgba(255, 0, 0, 0.12), transparent 60%),
        linear-gradient(to top, rgba(0, 0, 0, 0.92), rgba(0, 0, 0, 0.55));
    pointer-events: none;
}

.dp-hero-inner {
    position: relative;
    z-index: 1;
    max-width: var(--dp-max);
    margin: 0 auto;
    padding: 0 var(--dp-gut);
    display: flex;
    align-items: flex-end;
    gap: clamp(1.25rem, 3vw, 2rem);
}

/* Round portrait, artist pages with a real image only. */
.dp-hero-portrait {
    flex: 0 0 auto;
    width: clamp(96px, 14vw, 152px);
    height: clamp(96px, 14vw, 152px);
    border-radius: 50%;
    overflow: hidden;
    border: 2px solid rgba(255, 255, 255, 0.18);
    background: var(--dp-surface);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
}

.dp-hero-portrait img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.dp-hero-body {
    min-width: 0;
    flex: 1 1 auto;
}

.dp-eyebrow {
    margin: 0 0 0.55rem;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--dp-red-soft);
}

/* A band's own logo from the logo maker, above the name. Capped in height:
   logos are wide or square and the header still has to fit a phone. */
.dp-hero-logo {
    display: block; width: min(100%, 440px); height: auto; max-height: 200px;
    object-fit: contain; object-position: left center; margin: -.5rem 0 .4rem -1rem;
}

/* Inter, not the Lacquer grunge face the old headers used. At 3rem that font
   was close to unreadable, and it matched nothing else on the site. */
.dp-title {
    margin: 0;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: clamp(1.75rem, 5.5vw, 3.25rem);
    font-weight: 900;
    line-height: 1.05;
    letter-spacing: -0.03em;
    color: #fff;
}

.dp-sub {
    margin: 0.6rem 0 0;
    font-size: clamp(0.9rem, 2vw, 1.05rem);
    color: var(--dp-text);
    font-weight: 500;
}

.dp-sub a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: rgba(255, 255, 255, 0.3);
}

.dp-sub a:hover {
    color: #fff;
    text-decoration-color: var(--dp-red);
}

/* "In this band? Claim this page" on an act nobody runs yet. Quieter than
   the line above it: most people reading the page are not in the band. */
.dp-claimline {
    margin: 0.45rem 0 0;
    font-size: 0.82rem;
    color: var(--dp-muted, #9a9a9a);
}

.dp-claimline a {
    color: var(--dp-text);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: var(--dp-red);
}

.dp-claimline a:hover {
    color: #fff;
}

.dp-hero-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.55rem;
    margin-top: 1.15rem;
}

@media (max-width: 700px) {
    .dp-hero-inner {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* Buttons ----------------------------------------------------------------- */

.dp-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 1.1rem;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    color: #fff;
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}

.dp-btn:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.35);
    transform: translateY(-1px);
}

.dp-btn i {
    font-size: 0.85em;
}

.dp-btn--primary {
    background: var(--dp-red);
    border-color: var(--dp-red);
}

.dp-btn--primary:hover {
    background: var(--dp-red-dim);
    border-color: var(--dp-red-dim);
}

/* Liked state — filled heart plus a red wash, so it reads at a glance. */
.dp-btn--on {
    background: rgba(255, 0, 0, 0.22);
    border-color: var(--dp-red);
}

.dp-btn--on:hover {
    background: rgba(255, 0, 0, 0.3);
}

/* The venue Follow button (partials/_follow_venue_button.html). */
.dp-follow-form { display: inline; margin: 0; }
/* music_hub.js paints the in-place state with is-on; keep it looking like dp-btn--on. */
.dp-btn.is-on { background: rgba(255, 0, 0, 0.22); border-color: var(--dp-red); }
.dp-follow-count { opacity: 0.75; margin-left: 0.3rem; font-weight: 400; }
.dp-hero-actions .mh-consent {
    flex-basis: 100%;
    margin: 0.4rem 0 0;
    font-size: 0.85rem;
    color: #d8d8d8;
}
.dp-hero-actions .mh-consent .mh-btn {
    margin-left: 0.5rem;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--dp-red);
    border-radius: 4px;
    background: transparent;
    color: #fff;
    cursor: pointer;
}

.dp-btn .heart {
    color: var(--dp-red-soft);
}

.dp-btn--spotify:hover {
    background: rgba(30, 215, 96, 0.16);
    border-color: #1ed760;
}

/* ---------------------------------------------------------------------------
   At-a-glance figures
   --------------------------------------------------------------------------- */

.dp-stats {
    position: relative;
    z-index: 1;
    max-width: var(--dp-max);
    margin: 0 auto;
    padding: 1.5rem var(--dp-gut) 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0.75rem;
}

/* A single tile stretched across 1280px reads as a mistake rather than a
   figure, so a lone one keeps a sane width. */
.dp-stats:has(> .dp-stat:only-child) {
    grid-template-columns: minmax(150px, 260px);
}

.dp-stat {
    padding: 0.9rem 1.1rem;
    border: 1px solid var(--dp-line);
    border-radius: 6px;
    background: var(--dp-surface);
}

.dp-stat-value {
    display: block;
    font-size: 1.45rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: #fff;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}

.dp-stat-label {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--dp-muted);
}

/* ---------------------------------------------------------------------------
   Layout
   --------------------------------------------------------------------------- */

.dp-layout {
    max-width: var(--dp-max);
    margin: 0 auto;
    padding: 2rem var(--dp-gut) 4rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 2.5rem;
    align-items: start;
}

.dp-main {
    min-width: 0;
}

.dp-side {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: sticky;
    top: 76px;
}

@media (max-width: 940px) {
    .dp-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: 1.75rem;
    }

    .dp-side {
        position: static;
    }
}

/* ---------------------------------------------------------------------------
   Sections
   --------------------------------------------------------------------------- */

.dp-section {
    margin-bottom: 2.5rem;
}

.dp-section:last-child {
    margin-bottom: 0;
}

/* The quizzes and games a band turns up in (games.artist_games). */
.dp-play {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.6rem;
}

.dp-play a {
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    height: 100%;
    padding: 0.85rem 1rem;
    color: var(--dp-text);
    text-decoration: none;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--dp-line);
    border-radius: 8px;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.dp-play a:hover {
    border-color: var(--dp-red);
    background: rgba(255, 0, 0, 0.06);
}

.dp-play strong {
    font-size: 0.95rem;
    color: #fff;
}

.dp-play span {
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--dp-muted);
}

.dp-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.15rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--dp-line);
}

.dp-h {
    margin: 0;
    font-size: clamp(1.15rem, 2.6vw, 1.5rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    color: #fff;
}

.dp-h small {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.74rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--dp-muted);
}

.dp-more {
    flex-shrink: 0;
    color: var(--dp-red);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    transition: opacity 0.2s ease;
}

.dp-more:hover {
    opacity: 0.7;
}

/* Same affordance rendered as a <button> — the media panel's toggle is not a
   link, so it must not be marked up as one. */
.dp-more--btn {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--dp-red);
    cursor: pointer;
}

.dp-more i {
    margin-left: 0.3rem;
    font-size: 0.72rem;
}

/* Body copy: bios, venue descriptions. */
.dp-prose {
    color: var(--dp-text);
    font-size: 0.95rem;
    line-height: 1.75;
    max-width: 68ch;
    /* A long address or URL breaks rather than widening the page. */
    overflow-wrap: break-word;
}

.dp-prose p {
    margin: 0 0 0.9rem;
}

.dp-prose p:last-child {
    margin-bottom: 0;
}

.dp-prose a {
    color: var(--dp-red-soft);
}

.dp-empty {
    color: #777;
    font-size: 0.9rem;
    margin: 0;
}

.dp-empty a {
    color: var(--dp-red);
    text-decoration: none;
}

.dp-empty a:hover {
    text-decoration: underline;
}

/* The visible freshness line above a hub's listings — the body counterpart of
   the CollectionPage dateModified. */
.dp-updated {
    margin: -0.4rem 0 1rem;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    color: #6f6f6f;
}

/* Pager under a paginated hub list. The buttons are ordinary .dp-btn. */
.dp-pages {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
}

.dp-pages-note {
    font-size: 0.8rem;
    color: #777;
}

/* The hand-written city/genre introduction leads the column; a touch more
   presence than the generated answer block that follows it. */
.dp-prose--intro {
    font-size: 1.02rem;
}

/* ---------------------------------------------------------------------------
   Gig rows
   --------------------------------------------------------------------------- */

.dp-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.dp-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem;
    margin: 0 -0.75rem;
    border-radius: 6px;
    border-bottom: 1px solid var(--dp-line-soft);
    transition: background 0.18s ease;
}

.dp-row:last-child {
    border-bottom: none;
}

.dp-row:hover {
    background: rgba(255, 255, 255, 0.04);
}

.dp-row-date {
    flex: 0 0 54px;
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.1;
}

.dp-row-date em {
    font-style: normal;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--dp-red);
}

.dp-row-date b {
    font-size: 1.4rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    color: #fff;
}

.dp-row-date i {
    font-style: normal;
    font-size: 0.64rem;
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--dp-muted);
}

/* The time rail, for a list already grouped by day (/events/). */
.dp-row-date--time b {
    font-size: 0.95rem;
    letter-spacing: -0.02em;
}

/* "Cancelled" / "Postponed" / "Rescheduled" before the title, from the shared
   row partial. Inside the title link so the one-line ellipsis still holds. */
.dp-row-flag {
    display: inline-block;
    vertical-align: 1px;
    margin-right: 0.4rem;
    padding: 0.05rem 0.4rem;
    border: 1px solid rgba(255, 0, 0, 0.6);
    border-radius: 3px;
    font-size: 0.58rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--dp-red-soft);
}

.dp-row-thumb {
    flex: 0 0 56px;
    width: 56px;
    height: 56px;
    border-radius: 4px;
    overflow: hidden;
    background: var(--dp-surface);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #333;
}

.dp-row-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.dp-row-body {
    flex: 1 1 auto;
    min-width: 0;
}

/* Stretched link: the anchor is only around the title (so the accessible name
   is the gig, not the whole row) but its ::after covers the row, which keeps
   the row clickable without nesting a ticket link inside another anchor. */
.dp-row-title {
    display: block;
    font-size: 0.96rem;
    font-weight: 700;
    color: #fff;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.2s ease;
}

.dp-row-title::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 6px;
}

.dp-row:hover .dp-row-title {
    color: var(--dp-red);
}

.dp-row-meta {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.8rem;
    color: var(--dp-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dp-row-price {
    flex: 0 0 auto;
    font-size: 0.85rem;
    font-weight: 600;
    color: #bbb;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Above the stretched link so the ticket click isn't swallowed by the row. */
.dp-row-tickets {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.85rem;
    border: 1px solid rgba(255, 0, 0, 0.5);
    border-radius: 999px;
    color: #fff;
    font-size: 0.76rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.dp-row-tickets:hover {
    background: var(--dp-red);
    border-color: var(--dp-red);
}

/* The split-test engine's "filled" option for the listing-row Tickets link
   (experiment_surfaces: listing_row_tickets). Outlined is today's look. */
.dp-row-tickets--filled {
    background: var(--dp-red);
    border-color: var(--dp-red);
}

.dp-row-go {
    flex: 0 0 auto;
    color: #444;
    font-size: 0.78rem;
    transition: color 0.2s ease, transform 0.2s ease;
}

.dp-row:hover .dp-row-go {
    color: var(--dp-red);
    transform: translateX(3px);
}

/* The row stays on one line all the way down. Letting it wrap put the date
   and thumbnail alone on the first line and the title underneath, which read
   as two rows per gig. Dropping the price, the arrow and (on the narrowest
   screens) the thumbnail buys back the width instead. */
@media (max-width: 640px) {
    .dp-row {
        gap: 0.7rem;
        flex-wrap: nowrap;
    }

    .dp-row-thumb {
        flex-basis: 46px;
        width: 46px;
        height: 46px;
    }

    .dp-row-date {
        flex-basis: 44px;
    }

    .dp-row-date b {
        font-size: 1.2rem;
    }

    .dp-row-price,
    .dp-row-go {
        display: none;
    }
}

@media (max-width: 480px) {
    .dp-row-thumb {
        display: none;
    }

    .dp-row-tickets {
        padding: 0.4rem 0.7rem;
    }
}

/* "Show all N dates" — the rest of the listing is in the DOM either way, so
   every gig is crawlable; the class that hides it is only ever added by
   script, which is why a no-JS visitor sees the full list. */
.dp-js .dp-row.is-folded {
    display: none;
}

.dp-showall {
    display: none;
    width: 100%;
    margin-top: 1rem;
    padding: 0.7rem 1rem;
    border: 1px solid var(--dp-line);
    border-radius: 6px;
    background: transparent;
    color: #ddd;
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.dp-js .dp-showall {
    display: block;
}

.dp-showall:hover {
    background: rgba(255, 255, 255, 0.05);
    border-color: rgba(255, 255, 255, 0.25);
    color: #fff;
}

/* ---------------------------------------------------------------------------
   Chips
   --------------------------------------------------------------------------- */

.dp-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.dp-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.42rem 0.9rem;
    border: 1px solid var(--dp-line);
    border-radius: 999px;
    background: var(--dp-surface);
    color: #e4e4e4;
    font-size: 0.82rem;
    text-decoration: none;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.dp-chip:hover {
    border-color: var(--dp-red);
    background: rgba(255, 0, 0, 0.1);
    color: #fff;
}

/* A fold of more chips under a row of them (a city hub's other acts). The
   summary is itself a chip; opened, the rest sit under it. */
.dp-more-acts {
    margin-top: 0.5rem;
}

.dp-more-acts > summary {
    cursor: pointer;
    list-style: none;
    color: var(--dp-muted);
}

.dp-more-acts > summary::-webkit-details-marker {
    display: none;
}

.dp-more-acts[open] > summary {
    margin-bottom: 0.5rem;
}

/* A second heading inside one section (the tours page's by-name list). */
.dp-head--more {
    margin-top: 2rem;
}

.dp-chip span {
    font-size: 0.72rem;
    color: var(--dp-muted);
    font-variant-numeric: tabular-nums;
}

.dp-chip:hover span {
    color: var(--dp-red-soft);
}

/* ---------------------------------------------------------------------------
   Tabs — panels on one URL
   ---------------------------------------------------------------------------
   The festival hubs' strip (.fest-tabs) navigates between separate URLs; this
   one switches panels on a single page, the way the profile does. Both are
   built from .dp-chip so a visitor cannot tell which kind they are looking at.

   The links are real, carrying ?tab=…, so a tab is shareable, the back button
   works, and the page is usable with scripting off. .fest-tabs and .pf-tabs
   predate this block and still carry their own copies; folding them onto it is
   a separate tidy-up.
   --------------------------------------------------------------------------- */

.dp-tabs {
    position: sticky;
    /* Clear of the fixed site header. 89px is its measured height -- the same
       number cited above where .dp-crumbs pads past it. */
    top: 89px;
    z-index: 3;
    border-top: 1px solid var(--dp-line-soft);
    border-bottom: 1px solid var(--dp-line);
    background: rgba(8, 8, 8, 0.92);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.dp-tabs-inner {
    max-width: var(--dp-max);
    margin: 0 auto;
    padding: 0.8rem var(--dp-gut);
    display: flex;
    gap: 0.5rem;
    /* Scrolls rather than wraps: a city with every tab populated is eight
       chips, and three stacked rows of them push the page content off screen
       on a phone. */
    overflow-x: auto;
    scrollbar-width: none;
}

.dp-tabs-inner::-webkit-scrollbar { display: none; }

.dp-tabs .dp-chip { white-space: nowrap; }

.dp-tabs .dp-chip.is-active {
    border-color: var(--dp-red);
    background: rgba(255, 0, 0, 0.12);
    color: #fff;
}

.dp-tabs .dp-chip.is-active span { color: var(--dp-red-soft); }

/* The sidebar sticks at 76px, which is behind the tab strip. Nudge it clear
   wherever the two appear on the same page. */
.dp-tabs ~ .dp-layout .dp-side { top: 141px; }

/* Every panel is in the DOM on every request, so all of it is crawlable and a
   visitor with no scripting gets the whole page stacked under its headings.
   The class that hides the inactive ones is scoped to .dp-js, set by an inline
   script before first paint, so there is no flash either way. */
.dp-js .dp-panel.is-off {
    display: none;
}

/* Only shown when scripting is off, where the panels stack and would otherwise
   run together unlabelled. */
.dp-panel-label {
    display: none;
}

/* ---------------------------------------------------------------------------
   FAQ
   --------------------------------------------------------------------------- */

.dp-faq-q {
    margin: 1.4rem 0 0.35rem;
    font-size: 0.98rem;
    font-weight: 700;
    color: #fff;
}

.dp-faq-q:first-of-type {
    margin-top: 0;
}

.dp-faq-a {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.7;
    color: var(--dp-text);
    max-width: 68ch;
}

.dp-faq-a a {
    color: var(--dp-red-soft);
}

/* ---------------------------------------------------------------------------
   Sidebar cards
   --------------------------------------------------------------------------- */

.dp-card {
    padding: 1.15rem 1.25rem;
    border: 1px solid var(--dp-line);
    border-radius: 8px;
    background: var(--dp-surface);
}

.dp-card--accent {
    border-color: rgba(255, 0, 0, 0.35);
    background: linear-gradient(160deg, rgba(255, 0, 0, 0.08), transparent 60%), var(--dp-surface);
}

/* The line a band writes under their own name. */
.dp-tagline {
    margin: .4rem 0 .6rem;
    color: #ddd;
    font-size: 1.05rem;
    line-height: 1.4;
    max-width: 48ch;
}

/* The accent a band picked, defaulting to the site red. Set as a variable on
   the hero by the template so a page nobody runs keeps the house colour. */
#artist-page {
    --dp-accent: #ff0000;
}

.dp-hero--plain .dp-hero-inner {
    padding-top: 2rem;
}

/* A release with no cover art still gets a tile rather than a broken image. */
.dp-tile-blank {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 1;
    background: #161616;
    color: #3a3a3a;
    font-size: 2rem;
}

/* "Run by the band" — only ever on a page somebody verified runs. */
.dp-verified {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin: 0 0 .6rem;
    padding: .15rem .6rem;
    border-radius: 999px;
    background: rgba(29, 185, 84, .14);
    color: #4cd47a;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* The band's own links, under the hero buttons. */
.dp-socials {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    padding: 0;
    margin: .9rem 0 0;
}

.dp-socials a {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .35rem .7rem;
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: 999px;
    color: #ddd;
    font-size: .78rem;
    text-decoration: none;
}

.dp-socials a:hover {
    border-color: #ff4444;
    color: #fff;
}

/* A pull quote from the band's own page settings. */
.dp-quote {
    margin: 0 0 2rem;
    padding: 1rem 1.2rem;
    border-left: 3px solid #ff0000;
    background: rgba(255, 255, 255, .03);
}

.dp-quote p {
    margin: 0;
    color: #ddd;
    font-size: 1.05rem;
    font-style: italic;
    line-height: 1.6;
}

.dp-quote cite {
    display: block;
    margin-top: .5rem;
    color: #888;
    font-size: .82rem;
    font-style: normal;
}

/* Click-to-load third-party players (detail_embed.js). */
.dp-embed {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem;
}

.dp-embed iframe {
    width: 100%;
    border: 0;
    border-radius: 12px;
}

.dp-embed-note {
    color: #777;
    font-size: .78rem;
}

.dp-card-title {
    margin: 0 0 0.85rem;
    font-size: 0.76rem;
    font-weight: 800;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--dp-muted);
}

.dp-card p {
    margin: 0 0 0.85rem;
    font-size: 0.86rem;
    line-height: 1.65;
    color: var(--dp-text);
}

.dp-card p:last-child {
    margin-bottom: 0;
}

.dp-card .dp-btn {
    width: 100%;
    justify-content: center;
}

.dp-card .dp-btn + .dp-btn {
    margin-top: 0.5rem;
}

/* Definition rows — address, capacity, that sort of thing. */
.dp-facts {
    margin: 0;
    font-size: 0.86rem;
}

.dp-facts div {
    display: flex;
    gap: 0.75rem;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--dp-line-soft);
}

.dp-facts div:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.dp-facts dt {
    flex: 0 0 84px;
    color: var(--dp-muted);
    font-size: 0.76rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.dp-facts dd {
    flex: 1 1 auto;
    margin: 0;
    min-width: 0;
    color: #e4e4e4;
    overflow-wrap: anywhere;
}

.dp-facts dd a {
    color: var(--dp-red-soft);
    text-decoration: none;
}

.dp-facts dd a:hover {
    text-decoration: underline;
}

/* People rail — recent attendees, related artists. */
.dp-people {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.dp-person {
    width: 54px;
    text-align: center;
    text-decoration: none;
    color: var(--dp-muted);
}

.dp-person img {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid rgba(255, 255, 255, 0.15);
    transition: border-color 0.2s ease;
}

.dp-person:hover img {
    border-color: var(--dp-red);
}

.dp-person span {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.65rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dp-peer {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--dp-line-soft);
    text-decoration: none;
    color: inherit;
    /* Inside .dp-people (a wrapping flex row) a peer is a flex item, and a
       flex item will not go narrower than its longest unbroken line. The
       name and meta are nowrap, so a long article title on a city page made
       the row, and with it the whole page, wider than a phone. */
    min-width: 0;
    max-width: 100%;
}

.dp-peer:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.dp-peer img {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    flex: none;
}

.dp-peer-body {
    min-width: 0;
}

.dp-peer-name {
    display: block;
    font-size: 0.88rem;
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.2s ease;
}

.dp-peer:hover .dp-peer-name {
    color: var(--dp-red);
}

.dp-peer-meta {
    display: block;
    font-size: 0.74rem;
    color: var(--dp-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---------------------------------------------------------------------------
   Horizontal rails — fan media, album artwork, image gallery
   --------------------------------------------------------------------------- */

.dp-strip {
    display: flex;
    gap: 1rem;
    overflow-x: auto;
    padding-bottom: 0.6rem;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.dp-strip::-webkit-scrollbar {
    display: none;
}

/* The artist page's releases and images rails show a slim bar instead
   (dp-strip--bar): both regularly hold a dozen-plus tiles, and with the bar
   hidden nothing on the page says there is more to the right. A modifier
   rather than a change to .dp-strip so the venue and city media rails keep
   the hidden bar until someone decides otherwise. */
.dp-strip--bar {
    padding-bottom: 0.85rem;
    scrollbar-width: thin;
    scrollbar-color: var(--dp-red-dim) var(--dp-surface-2);
}

/* Safari's version of the same bar: it has no scrollbar-color, and Chrome
   and Firefox ignore these pseudo-elements once scrollbar-color is set. */
.dp-strip--bar::-webkit-scrollbar {
    display: block;
    height: 8px;
}

.dp-strip--bar::-webkit-scrollbar-track {
    background: var(--dp-surface-2);
    border-radius: 999px;
}

.dp-strip--bar::-webkit-scrollbar-thumb {
    background: var(--dp-red-dim);
    border-radius: 999px;
}

.dp-strip--bar::-webkit-scrollbar-thumb:hover {
    background: var(--dp-red);
}

.dp-tile {
    flex: 0 0 auto;
    width: 230px;
    min-width: 0;
    margin: 0;
    scroll-snap-align: start;
    border: 1px solid var(--dp-line);
    border-radius: 8px;
    overflow: hidden;
    background: var(--dp-surface);
}

.dp-tile img,
.dp-tile video {
    width: 100%;
    height: 172px;
    object-fit: cover;
    display: block;
    background: #000;
}

.dp-tile--square img {
    height: 230px;
}

.dp-tile figcaption,
.dp-tile-body {
    padding: 0.6rem 0.75rem;
    font-size: 0.76rem;
    color: var(--dp-muted);
    line-height: 1.5;
}

.dp-tile-name {
    display: block;
    font-size: 0.86rem;
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dp-tile figcaption strong {
    display: block;
    color: #ddd;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dp-tile a {
    color: var(--dp-red-soft);
    text-decoration: none;
}

.dp-tile a:hover {
    text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   Tracks
   --------------------------------------------------------------------------- */

.dp-track {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--dp-line-soft);
}

.dp-track:last-child {
    border-bottom: none;
}

.dp-track-body {
    flex: 1 1 auto;
    min-width: 0;
}

.dp-track-name {
    display: block;
    font-size: 0.92rem;
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dp-track-album {
    display: block;
    font-size: 0.78rem;
    color: var(--dp-muted);
}

.dp-track audio {
    height: 32px;
    max-width: 200px;
}

/* ---------------------------------------------------------------------------
   Upload form (venue media)
   --------------------------------------------------------------------------- */

.dp-upload {
    margin-bottom: 1.25rem;
    padding: 1.2rem;
    border: 1px solid var(--dp-line);
    border-radius: 8px;
    background: var(--dp-surface);
}

.dp-js .dp-upload[hidden] {
    display: none;
}

.dp-upload p {
    margin: 0 0 0.85rem;
    font-size: 0.84rem;
    color: var(--dp-muted);
    line-height: 1.6;
}

.dp-upload-fields {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 0.85rem;
}

.dp-upload label {
    font-size: 0.82rem;
    color: #ccc;
}

.dp-upload input[type="file"] {
    display: block;
    margin-top: 0.3rem;
    color: var(--dp-muted);
    font-size: 0.8rem;
}

.dp-upload input[type="text"] {
    width: 100%;
    margin-bottom: 0.85rem;
    padding: 0.6rem 0.8rem;
    border: 1px solid #333;
    border-radius: 4px;
    background: #0c0c0c;
    color: #eee;
    font: inherit;
    font-size: 0.86rem;
}

.dp-upload input[type="text"]:focus {
    outline: none;
    border-color: var(--dp-red);
}

/* ---------------------------------------------------------------------------
   Scrollbars — carried over from artist_page.css, which this file replaces
   --------------------------------------------------------------------------- */

html {
    scrollbar-width: thin;
    scrollbar-color: #444 #101010;
}

::-webkit-scrollbar {
    width: 10px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: #101010;
}

::-webkit-scrollbar-thumb {
    background: #444;
    border: 2px solid #101010;
    border-radius: 6px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--dp-red);
}

::-webkit-scrollbar-corner {
    background: #101010;
}

@media (prefers-reduced-motion: reduce) {
    .dp-btn,
    .dp-row-go,
    .dp-chip,
    .dp-hero-media {
        transition: none;
    }
}

/* Band notes on an artist page (ArtistNote; templates/views/bands/artist.html) */
.dp-note-list { list-style: none; margin: 0; padding: 0; }
.dp-note { border-left: 3px solid #ff0000; padding: 0.25rem 0 0.25rem 0.9rem; margin: 0 0 1rem; }
.dp-note p { margin: 0 0 0.3rem; line-height: 1.5; }
.dp-note-meta { font-size: 0.75rem; color: #888; text-transform: uppercase; letter-spacing: 0.08em; }

/* What's nearby on a venue page (NearbyPlace; templates/views/event/venue.html) */
.dp-nearby-lead { margin: 0 0 1rem; color: #cfcfcf; font-size: 0.92rem; }
.dp-nearby-group { margin: 0 0 1.1rem; }
.dp-nearby-h { margin: 0 0 0.5rem; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--dp-muted); }
.dp-attrib { margin: 0.75rem 0 0; font-size: 0.72rem; color: var(--dp-muted); }
.dp-attrib a { color: inherit; }

/* ---------------------------------------------------------------------------
   Seasonal accent (seasons.py): each season's hub, its city spokes, its
   sidebar card and the homepage row carry .szn-<season>, which re-points the
   red tokens to the season's colour -- a restrained orange for Halloween,
   pine green for Christmas, champagne gold for New Year's Eve. Same technique
   as .pf in profile.css: the few places detail.css paints a literal red wash
   take --szn-rgb below. Ticket links stay red -- that is what a Tickets button
   looks like everywhere.
   --------------------------------------------------------------------------- */

.szn-halloween {
    --szn-rgb: 240, 128, 30;
    --dp-red: #f0801e;
    --dp-red-dim: #b85c10;
    --dp-red-soft: #ffb070;
    --szn-hero: #1b1208 55%, #241406;
}
.szn-christmas {
    --szn-rgb: 62, 170, 104;
    --dp-red: #3eaa68;
    --dp-red-dim: #2a7a4a;
    --dp-red-soft: #8fd9a8;
    --szn-hero: #0f1a13 55%, #10241a;
}
.szn-new-years-eve {
    --szn-rgb: 226, 184, 74;
    --dp-red: #e2b84a;
    --dp-red-dim: #a8862f;
    --dp-red-soft: #f3d98a;
    --szn-hero: #1a170c 55%, #242010;
}
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) {
    --szn-wash: rgba(var(--szn-rgb), 0.12);
}

:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-hero {
    background: linear-gradient(150deg, #141414 0%, var(--szn-hero) 100%);
}
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-hero::after {
    background:
        radial-gradient(120% 100% at 15% 0%, var(--szn-wash), transparent 60%),
        linear-gradient(to top, rgba(0, 0, 0, 0.92), rgba(0, 0, 0, 0.55));
}
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-btn--on,
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-btn.is-on { background: rgba(var(--szn-rgb), 0.22); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-btn--on:hover { background: rgba(var(--szn-rgb), 0.3); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-play a:hover { background: rgba(var(--szn-rgb), 0.06); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-row-flag { border-color: rgba(var(--szn-rgb), 0.6); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-chip:hover { background: rgba(var(--szn-rgb), 0.1); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-tabs .dp-chip.is-active { background: var(--szn-wash); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-card--accent {
    border-color: rgba(var(--szn-rgb), 0.35);
    background: linear-gradient(160deg, rgba(var(--szn-rgb), 0.08), transparent 60%), var(--dp-surface);
}
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-socials a:hover { border-color: var(--dp-red-soft); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-quote,
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-note { border-left-color: var(--dp-red); }
:is(.szn-halloween, .szn-christmas, .szn-new-years-eve) .dp-row-tickets {
    --dp-red: #ff0000;
    --dp-red-dim: #cc0000;
    border-color: rgba(255, 0, 0, 0.5);
}
