/* Listing pages: the "nearest first" card list shown once a category has
   been drilled into (e.g. /eat/pubs/). Builds on css/common.css. */

header.listing-header {
    text-align: left;
    position: sticky;
    top: 0;
    z-index: 10;
}

.logo-area {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
}

h1.listing-title {
    font-size: 1.4rem;
    text-align: left;
}

/* Nearest/Soonest toggle - only shown (see js/sortmode.js) when the
   category actually has known individual events to switch to. */
.sort-toggle {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
}

.sort-toggle-btn {
    flex: 1;
    padding: 8px 12px;
    border-radius: 20px;
    border: 1px solid #ddd;
    background: white;
    color: var(--text-dark);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    font: inherit;
}

.sort-toggle-btn.active {
    background: var(--primary-blue);
    border-color: var(--primary-blue);
    color: white;
}

.event-when {
    background: var(--bg-beige);
    color: var(--primary-blue);
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 700;
}

.event-pattern {
    font-size: 12px;
    color: var(--primary-blue);
    font-weight: 600;
    margin-bottom: 4px;
}

.event-venue {
    font-size: 13px;
    color: var(--text-light);
    margin-bottom: 12px;
}

.event-venue a {
    color: var(--primary-blue);
    font-weight: 600;
    text-decoration: none;
}

/* Only shown when an event has its own location, distinct from its host
   venue's - see js/detail.js's buildEventDetailHtml. */
.event-location {
    font-size: 13px;
    color: var(--text-light);
    margin-bottom: 12px;
}

.event-section-header {
    font-size: 13px;
    color: var(--text-light);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 700;
    margin: 18px 0 8px 0;
}

.event-section-header:first-child {
    margin-top: 0;
}

/* Sibling-category quick links */
.filters {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    padding-bottom: 5px;
    scrollbar-width: none;
}
.filters::-webkit-scrollbar {
    display: none;
}

.filter-chip {
    background-color: var(--bg-beige);
    padding: 8px 16px;
    border-radius: 20px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-dark);
    white-space: nowrap;
    text-decoration: none;
    border: 1px solid transparent;
    flex-shrink: 0;
}

.filter-chip.active {
    background-color: var(--primary-blue);
    color: white;
}

.filter-chip.map-view {
    margin-left: auto;
    background-color: white;
    border: 1px solid var(--primary-blue);
    color: var(--primary-blue);
    cursor: pointer;
    font: inherit;
}

/* Section "list" layout's filter bar (server/views/section-list.ejs) - same
   width as the big square .nav-item buttons (same grid, same gap/padding),
   just half the height and laid out as a row (icon beside label) instead
   of a column, since there's a lot more of them to fit on screen. */
.section-filter-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 15px;
    padding: 0;
}

.section-filter-btn {
    background-color: var(--bg-beige);
    border-radius: var(--radius);
    border: none;
    padding: 10px 14px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--primary-blue);
    transition: transform 0.2s, background-color 0.2s;
    box-shadow: 0 2px 4px rgba(0,0,0,0.05);
    aspect-ratio: 1 / 0.4;
    cursor: pointer;
    font: inherit;
}

.section-filter-btn:active {
    transform: scale(0.98);
    background-color: #e0e0d0;
}

.section-filter-btn.active {
    background-color: var(--primary-blue);
    color: white;
}

.section-filter-btn.map-view {
    background-color: white;
    border: 1px solid var(--primary-blue);
}

.section-filter-icon {
    font-size: 1.4rem;
}

.section-filter-label {
    font-weight: 600;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-align: center;
}

.listing-card.filtered-out { display: none !important; }

/* Content List */
.content-list {
    flex: 1;
    overflow-y: auto;
    padding: 10px 16px 40px 16px;
    background-color: #FAFAFA;
}

.loading-msg,
.empty-msg,
.error-msg {
    color: var(--text-light);
    font-size: 0.9rem;
    text-align: center;
    padding: 30px 10px;
}

/* !important: this utility must always win over a component's own
   `display` rule (e.g. .detail-overlay's display:flex) regardless of which
   is declared later in the cascade - without it, whichever rule happens to
   come second in the file wins a same-specificity tie, which is exactly
   what let the detail overlay show up open on page load. */
.hidden {
    display: none !important;
}

.listing-card {
    background: white;
    border-radius: 12px;
    padding: 16px;
    margin-bottom: 16px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.04);
    border: 1px solid #E5E5EA;
    display: flex;
    gap: 12px;
    cursor: pointer;
}

.listing-card:focus-visible {
    outline: 2px solid var(--primary-blue);
    outline-offset: 2px;
}

.thumbnail {
    width: 80px;
    height: 80px;
    border-radius: 8px;
    background-color: #ddd;
    background-size: cover;
    background-position: center;
    flex-shrink: 0;
    overflow: hidden;
    position: relative;
}

/* Placeholder thumbnail gradients, cycled per-card until real photos are
   supplied by the crawler/admin-edited API data. */
.thumb-a { background-image: linear-gradient(135deg, var(--primary-blue) 0%, var(--accent-blue) 100%); }
.thumb-b { background-image: linear-gradient(135deg, #5D4037 0%, #A1887F 100%); }
.thumb-c { background-image: linear-gradient(135deg, #F4A460 0%, #ffd399 100%); }

.card-details {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-width: 0;
}

.card-header h2 {
    font-size: 17px;
    font-weight: 700;
    color: var(--text-dark);
    margin-bottom: 4px;
}

.meta-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 13px;
    color: var(--text-light);
    margin-bottom: 6px;
    gap: 8px;
}

.tags-row {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    min-width: 0;
}

.tag-pill {
    background: var(--bg-beige);
    color: var(--primary-blue);
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 10px;
    font-size: 11px;
    white-space: nowrap;
}

.distance {
    background: var(--bg-beige);
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    color: var(--primary-blue);
    white-space: nowrap;
    flex-shrink: 0;
}

/* Compliment badges replace the old tags-row wherever a listing renders
   (cards, detail card, map popups) - see js/complimentBadges.js. Sized by
   weight (1-2.5rem, server/lib/complimentWeight.js), never a count. The
   row is clickable - tap/Enter opens .compliment-modal-* below, since the
   emoji-only row has no room to say what each badge actually means. */
.compliment-badges-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    min-width: 0;
    cursor: pointer;
}

.compliment-badge {
    line-height: 1;
}

/* The compliment-meaning modal (js/complimentBadges.js's openComplimentModal)
   - the same badges as the row, stacked vertically with room for a label
   beside each one. Injected once into <body> on first open, reused after. */
.compliment-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 20px;
}

.compliment-modal-card {
    position: relative;
    background: #fff;
    border-radius: 14px;
    padding: 20px;
    max-width: 320px;
    width: 100%;
    max-height: 80dvh;
    overflow-y: auto;
}

.compliment-modal-close {
    position: absolute;
    top: 8px;
    right: 8px;
    background: none;
    border: none;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    color: var(--text-light);
    padding: 4px;
}

.compliment-modal-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 8px;
}

.compliment-modal-row {
    display: flex;
    align-items: center;
    gap: 14px;
}

.compliment-modal-emoji {
    line-height: 1;
    flex-shrink: 0;
}

.compliment-modal-label {
    font-size: 14px;
    font-weight: 600;
    color: var(--primary-blue);
}

/* The "give a compliment" control - detail card only (js/detail.js). */
.compliment-action {
    margin: 6px 0;
}

.compliment-btn {
    background: var(--bg-beige);
    color: var(--primary-blue);
    font-weight: 600;
    font-size: 13px;
    border: none;
    border-radius: 14px;
    padding: 6px 12px;
    cursor: pointer;
}

.compliment-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

.compliment-type-btn {
    background: #fff;
    border: 1px solid var(--bg-beige);
    color: var(--primary-blue);
    font-size: 13px;
    border-radius: 12px;
    padding: 5px 10px;
    cursor: pointer;
}

.compliment-type-btn.given,
.compliment-type-btn:disabled {
    background: var(--bg-beige);
    color: var(--text-light);
    cursor: default;
}

.venue-meta {
    list-style: none;
    margin: 0 0 10px 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 12px;
    color: var(--text-light);
}

.venue-meta a {
    color: var(--primary-blue);
    text-decoration: none;
}

.venue-meta li {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


.description {
    font-size: 13px;
    color: #333;
    line-height: 1.4;
    margin-bottom: 12px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.action-btn {
    font-size: 13px;
    font-weight: 600;
    color: var(--primary-blue);
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
    padding: 0;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-decoration: none;
    display: inline-block;
}

/* Detail card overlay - opened by tapping a listing card (js/detail.js).
   Full viewport backdrop; the card itself is capped to the same width as
   the app shell and fills the height, scrolling internally. */
.detail-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    z-index: 1000;
}

body.detail-open {
    overflow: hidden;
}

.detail-card {
    position: relative;
    width: 100%;
    max-width: 400px;
    height: 100vh;
    height: 100dvh;
    background: var(--t-card-bg, var(--card-white));
    box-shadow: 0 0 30px rgba(0,0,0,0.3);
}

.detail-close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: rgba(0,0,0,0.55);
    color: white;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* A venue's own page (server/views/venue.ejs) floating back control -
   mirrors the overlay's close button above (round, translucent, floating
   over the card's hero) so the two views of the same detail card read as
   one design: X top-right on the overlay, <- top-left on the page.
   Fixed (not sticky) because .app-container is overflow:hidden, which
   would otherwise become the sticky scrollport and let the button scroll
   away with the card; the max() left keeps it pinned to the 400px column
   on desktop while staying at the screen edge on mobile, where the column
   is full-width. .detail-body.no-thumbnail's 56px top padding clears it
   exactly as it clears the close button. */
.detail-back-btn {
    position: fixed;
    top: 12px;
    left: 12px;
    left: max(12px, calc(50% - 200px + 12px));
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: rgba(0,0,0,0.55);
    color: white;
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.25);
}

.detail-scroll {
    height: 100%;
    overflow-y: auto;
}

.detail-thumbnail {
    width: 100%;
    height: 200px;
    background-color: #ddd;
    background-size: cover;
    background-position: center;
}

.detail-body {
    padding: 20px;
    /* The card's default text colour - every element without its own
       colour picks up the theme's text colour (--t-text). The size is
       baseline-relative like the headings (--t-fs-body-inc, default 0px). */
    color: var(--t-text, var(--text-dark));
    font-size: calc(var(--t-fs-body, 1rem) + var(--t-fs-body-inc, 0rem));
}

/* No hero image - .detail-thumbnail is omitted entirely (js/detail.js), so
   the card's real content starts immediately instead of below a 200px
   placeholder block. Extra top padding just clears the close button
   (absolute, top:12/right:12 over .detail-card) so a long/wrapping name
   doesn't run under it. */
.detail-body.no-thumbnail {
    padding-top: 56px;
}

.detail-name {
    /* Baseline-relative: the theme editor can nudge the size via the
       --t-fs-*-inc vars (default 0px = the baseline unchanged). */
    font-size: calc(var(--t-fs-heading, 1.3rem) + var(--t-fs-heading-inc, 0rem));
    font-weight: 800;
    color: var(--t-heading, var(--text-dark));
    margin-bottom: 8px;
}

.detail-rating-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 10px 0;
}

.detail-description {
    font-size: 14px;
    color: var(--t-text, #333);
    line-height: 1.5;
    margin-bottom: 14px;
}

.detail-meta-list {
    list-style: none;
    margin: 0 0 14px 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 14px;
}

.detail-meta-list a {
    color: var(--t-link, var(--primary-blue));
    text-decoration: none;
}

.detail-categories {
    font-size: calc(var(--t-fs-label, 12px) + var(--t-fs-label-inc, 0rem));
    color: var(--t-label, var(--text-light));
    margin-bottom: 14px;
}

.detail-map {
    height: 160px;
    border-radius: var(--radius);
    overflow: hidden;
}

/* The small preview map + its "tap to open a full interactive map" overlay
   (js/mapModal.js) - .map-preview-overlay is a SIBLING of the map div, not
   a child of it, so it sits above Leaflet's own tile/marker panes without
   becoming part of Leaflet's internal DOM. .map-preview-wrap owns the
   bottom margin .detail-map used to have itself, now that something else
   sits after it inside the same wrapper. */
.map-preview-wrap {
    position: relative;
    margin-bottom: 14px;
}
.map-preview-overlay {
    position: absolute;
    inset: 0;
    z-index: 15;
    cursor: pointer;
    background: transparent;
    border-radius: inherit;
}

/* The full-screen modal .map-preview-overlay opens (js/mapModal.js) - a
   freely interactive copy of whichever small map was tapped. Hidden by
   default; .open (added/removed by openMapModal/closeMapModal) toggles
   both visibility and the flex centering that sizes .map-modal-card. */
.map-modal-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(0, 0, 0, 0.6);
    align-items: center;
    justify-content: center;
}
.map-modal-backdrop.open {
    display: flex;
}
.map-modal-card {
    position: relative;
    width: 95vw;
    width: 95dvw;
    height: 95vh;
    height: 95dvh;
    background: var(--card-white, #fff);
    border-radius: var(--radius);
    overflow: hidden;
}
.map-modal-map {
    width: 100%;
    height: 100%;
}
.map-modal-close {
    position: absolute;
    top: 10px;
    right: 10px;
    /* Leaflet's own panes/controls inside .map-modal-map aren't isolated
       into their own stacking context (.leaflet-container gets
       position:relative but no z-index, so it doesn't create one) - their
       z-index values (up to 1000 for the zoom control corners, 700 for an
       open marker popup) compare directly against this button's in the
       shared .map-modal-card stacking context. A low value here
       (previously 11) meant a popup that happened to render near the
       top-right corner could sit visually on top of the close button and
       swallow its clicks - confirmed as the actual "close button doesn't
       work" cause. Comfortably above Leaflet's own maximum. */
    z-index: 2000;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 2px solid grey;
    background: rgba(255, 255, 255, 1);
    color: #000;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}
/* Background-scroll lock while the modal's open (js/mapModal.js toggles
   this on <body>) - a touch drag on the map shouldn't also scroll the
   page underneath it. */
body.map-modal-open {
    overflow: hidden;
}

/* Emoji marker icons (js/mapModal.js's emojiMarkerIcon) - an L.divIcon,
   so this replaces Leaflet's default pin/shadow image entirely rather
   than layering on top of it (className on a divIcon substitutes for
   its own default class, it doesn't add to it). */
.emoji-marker {
    background: none;
    border: none;
}
.emoji-marker-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    background: #fff;
    border: 2px solid var(--primary-blue, #1e6091);
    border-radius: 50%;
    font-size: 16px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}

.detail-directions-btn {
    display: block;
    text-align: center;
    background: var(--t-button-bg, var(--primary-blue));
    color: var(--t-button-color, white);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-size: calc(var(--t-fs-button, 13px) + var(--t-fs-button-inc, 0rem));
    padding: 12px;
    border-radius: var(--radius);
    text-decoration: none;
}
/* This class's own display:block above ties with the browser's native
   [hidden]{display:none} rule (equal specificity, this one declared
   later) and wins - js/bundle.js's renderBundleLocation setting
   linkEl.hidden on #bundle-directions-link (a bundle with no address/
   lat/lon at all, e.g. Minehead Bay Festival, which points visitors at
   real member venues instead) had no visible effect without this. Same
   root cause the .hidden utility class further down exists to solve
   generally - this is the one place the native attribute is used
   instead, so it needs its own explicit override. */
.detail-directions-btn[hidden] {
    display: none;
}

/* A listing's theme background (server/config/theme.js's --t-bg: up to
   three colour stops or any raw gradient) replacing the hashed
   thumb-a/b/c gradient - see js/detail.js's buildDetailHtml. The legacy
   single-colour themeColor falls back through --venue-accent (set
   inline by older code paths), so pre-theme listings keep their accent
   gradient untouched. Same gradient recipe css/bundle.css uses, so a
   listing's page and a bundle's page read as one consistent idea. */
.detail-thumbnail.themed {
    background-image: var(--t-bg, linear-gradient(135deg, var(--venue-accent, #4facfe) 0%, #4facfe 100%));
}

/* Admin-defined linktr.ee-style link block. */
.detail-links-section {
    background: var(--t-bg, var(--bg-beige));
    padding: 20px;
}

.detail-links-heading {
    font-size: calc(var(--t-fs-subheading, 0.75rem) + var(--t-fs-subheading-inc, 0rem));
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--t-label, var(--text-light));
    font-weight: 700;
    margin-bottom: 10px;
}

.detail-links-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.detail-custom-link {
    display: block;
    text-align: center;
    background: var(--t-button-bg-links, var(--t-card-bg-links, var(--card-white)));
    color: var(--t-button-color-links, var(--t-link, var(--primary-blue)));
    font-weight: 700;
    font-size: calc(var(--t-fs-links, 0.95rem) + var(--t-fs-links-inc, 0rem));
    padding: 14px;
    border-radius: 24px;
    text-decoration: none;
    box-shadow: 0 2px 4px rgba(0,0,0,0.06);
    border: 1px solid var(--t-border, #eee);
}

.detail-links-section.events-section .detail-meta-list li {
    font-size: calc(var(--t-fs-events, 1rem) + var(--t-fs-events-inc, 0rem));
}

/* Owner/admin-uploaded images grouped by purpose (js/detail.js's
   renderImageGallery) - stacked sections, same visual language as the
   custom-links block above. */
.detail-gallery-section {
    background: var(--card-white);
    padding: 20px;
    border-top: 1px solid var(--t-border, #eee);
}

.detail-gallery-heading {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-light);
    font-weight: 700;
    margin-bottom: 10px;
}

.detail-gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
}

.detail-gallery-item {
    background: var(--bg-beige);
    border-radius: 12px;
    padding: 8px;
}

.detail-gallery-thumb {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: 8px;
    display: block;
}

.detail-gallery-description {
    font-size: 0.75rem;
    color: var(--text-light);
    margin: 6px 0 0;
}

/* Deliberately understated - this is a way in for the rare visitor who
   actually runs a business that's missing or wrong, not a call to action
   for casual browsing (see js/account.js's header comment). */
.add-entry-link {
    display: block;
    text-align: center;
    padding: 14px 16px 18px;
    font-size: 0.75rem;
    color: var(--text-light);
    text-decoration: none;
    background-color: #FAFAFA;
}
.add-entry-link:hover { text-decoration: underline; }

/* Inline "click to edit" affordances (js/inlineEdit.js) - an admin or a
   listing's own owner editing real content directly on the page it's
   shown on, instead of only through /admin/ or /account/. Shared by the
   category-page overlay, /:id/, and /bundles/:id/ (see
   css/bundle.css's small additions for the bundle-hero-specific bits). */
.inline-edit-pencil {
    display: inline-block;
    margin-left: 6px;
    padding: 0 4px;
    border: none;
    background: none;
    color: var(--text-light);
    font-size: 0.85em;
    cursor: pointer;
    opacity: 0.55;
    vertical-align: middle;
}
.inline-edit-pencil:hover { opacity: 1; }

.inline-edit-form {
    margin: 8px 0;
    padding: 10px;
    background: var(--bg-beige);
    border-radius: 8px;
    border: 1px solid #e5ddd0;
}
.inline-edit-input {
    width: 100%;
    box-sizing: border-box;
    padding: 8px 10px;
    border-radius: 6px;
    border: 1px solid #ccc;
    font-size: 0.85rem;
    font-family: inherit;
}
textarea.inline-edit-input { min-height: 70px; resize: vertical; }

.inline-edit-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}
.inline-edit-actions button {
    padding: 6px 14px;
    border-radius: 6px;
    border: none;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}
.inline-edit-save { background: var(--primary-blue); color: white; }
.inline-edit-cancel { background: #e5e5e5; color: var(--text-dark); }

.inline-edit-status {
    display: block;
    margin-top: 6px;
    font-size: 0.75rem;
    color: var(--text-light);
}

.inline-custom-links-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 8px;
}
.inline-custom-links-list .custom-link-row {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: 6px;
}
.inline-custom-links-list .custom-link-row input {
    padding: 6px 8px;
    border-radius: 6px;
    border: 1px solid #ccc;
    font-size: 0.8rem;
}
.inline-custom-links-list .custom-link-remove {
    border: none;
    background: none;
    color: var(--danger, #c0392b);
    cursor: pointer;
    font-size: 1rem;
}
.inline-edit-add-link {
    padding: 6px 10px;
    border-radius: 6px;
    border: 1px dashed #ccc;
    background: none;
    color: var(--text-light);
    font-size: 0.8rem;
    cursor: pointer;
}

/* Phone numbers in the inline editor (js/inlineEdit.js's phonesEditorHtml)
   - same shape as .inline-custom-links-list above, one extra column for
   the type picker. */
.inline-phones-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 8px;
}
.inline-phones-list .phone-row {
    display: grid;
    grid-template-columns: 1fr 1fr auto auto;
    gap: 6px;
}
.inline-phones-list .phone-row input, .inline-phones-list .phone-row select {
    padding: 6px 8px;
    border-radius: 6px;
    border: 1px solid #ccc;
    font-size: 0.8rem;
}
.inline-phones-list .phone-remove {
    border: none;
    background: none;
    color: var(--danger, #c0392b);
    cursor: pointer;
    font-size: 1rem;
}
.inline-edit-add-phone {
    padding: 6px 10px;
    border-radius: 6px;
    border: 1px dashed #ccc;
    background: none;
    color: var(--text-light);
    font-size: 0.8rem;
    cursor: pointer;
}

.inline-missing-fields {
    padding: 4px 20px 14px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.inline-edit-add-missing {
    padding: 5px 10px;
    border-radius: 20px;
    border: 1px dashed #bbb;
    background: none;
    color: var(--text-light);
    font-size: 0.75rem;
    cursor: pointer;
}
.inline-edit-add-missing:hover { border-color: var(--primary-blue); color: var(--primary-blue); }
.inline-missing-field-row { display: contents; }

/* Seasonal opening hours section on the detail card (js/detail.js's
   renderOpeningHours) - shown only when showOpeningHours is set. */
.detail-hours {
    margin: 10px 0;
    padding: 10px 12px;
    background: #f6f8fa;
    border-radius: 8px;
    border: 1px solid #e3e8ee;
}
.detail-hours-status {
    font-weight: 700;
    font-size: 0.9rem;
    margin-bottom: 6px;
}
.detail-hours-status .oh-open { color: #147a4c; }
.detail-hours-status .oh-closed { color: #b3541e; }
.oh-season {
    font-size: 0.8rem;
    color: #445;
    padding: 4px 0;
    border-top: 1px dashed #dde3ea;
}
.oh-season:first-of-type { border-top: none; }
.oh-season-dates {
    font-weight: 600;
    color: #334;
}

/* A themed listing's own page: the theme's background gradient (up to
   three colour stops, or any raw gradient via bgCss) becomes the page
   backdrop behind the 400px column, and the column itself takes the
   theme's card background. The --t-* vars are set inline on <body> by
   js/venue.js's applyVenuePageTheme; the fallbacks keep an unthemed
   page exactly as it is today. */
body[data-venue-id] {
    background-image: var(--t-bg, linear-gradient(to bottom, #87CEEB 0%, #E0F7FA 50%, #F4A460 100%));
    background-color: #f0f4f8;
}

body[data-venue-id] .app-container {
    background: var(--t-card-bg, var(--card-white));
}

/* Linktree-inspired social icon row (js/detail.js's renderSocialLinks):
   known-platform custom links (Facebook/Instagram/WhatsApp/X/TikTok/
   YouTube/TripAdvisor/email) as a compact icon row under the intro,
   icons from js/socials.js. Non-social custom links stay as the big
   .detail-custom-link buttons below. */
.detail-social-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 12px 0 4px 0;
}
.detail-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid var(--t-border-links, var(--t-border, #dfe5ec));
    background: var(--t-button-bg-links, var(--t-card-bg-links, var(--t-card-bg, var(--card-white))));
    color: var(--t-button-color-links, var(--t-link, var(--primary-blue)));
    text-decoration: none;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.detail-social-link:hover,
.detail-social-link:focus-visible {
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    outline: none;
}
.detail-social-link svg {
    display: block;
}

/* Phone-type hint in the detail meta row (" · can text" / " · landline") -
   js/detail.js renderDetailMeta; the type also tags the tel: link for the
   click analytics (mobile vs landline). */
.phone-type-hint {
    opacity: 0.65;
    font-size: 0.85em;
}
.phone-sms-link { margin-left: 8px; text-decoration: none; opacity: 0.9; }
.phone-sms-link:hover { opacity: 1; }

/* Multiple numbers on one listing (js/detail.js renderDetailMeta) - one
   row per entry inside the single data-field="phone" <li>; identical to a
   single plain row when there's only one entry. */
.phone-list { display: flex; flex-direction: column; gap: 6px; }
.phone-entry { display: flex; align-items: center; }

/* ---- Timetables route overview (js/listing.js renderTimetablesOverview) ---- */

.timetables-overview {
    margin: 6px 0 4px;
    padding: 10px 12px;
    background: rgba(30, 96, 145, 0.06);
    border-radius: 12px;
}
.overview-title { font-size: 1.15rem; margin: 0 0 2px; }
.overview-note { font-size: 0.8rem; color: #667; margin: 0 0 10px; }
.route-rows { display: flex; flex-direction: column; gap: 6px; }
.route-row {
    display: flex;
    align-items: center;
    gap: 10px;
    background: #fff;
    border: 1px solid #e3e7ec;
    border-radius: 10px;
    padding: 8px 12px;
    cursor: pointer;
    flex-wrap: wrap;
}
.route-row:hover, .route-row:focus-visible { border-color: #1E6091; outline: none; }
.route-badge {
    background: #1E6091;
    color: #fff;
    border-radius: 8px;
    font-weight: 700;
    min-width: 2.2em;
    text-align: center;
    padding: 3px 8px;
    font-size: 1rem;
}
.route-dest { color: #445; font-size: 0.9rem; flex: 1 1 140px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.route-stop { font-size: 0.85rem; color: #667; }
.route-distance { font-size: 0.8rem; color: #889; }
.route-time { font-weight: 700; font-size: 1.05rem; color: #0e3a57; }
.all-stops-title { font-size: 1.05rem; margin: 16px 0 8px; }

/* Train nature on the route rows (js/listing.js renderTimetablesOverview -
   "Steam" / "Diesel" / "DMU" from the WSR table column headers). */
.route-type {
    font-size: 0.78rem;
    color: #7a4a12;
    background: rgba(122, 74, 18, 0.08);
    border: 1px solid rgba(122, 74, 18, 0.2);
    border-radius: 999px;
    padding: 1px 8px;
    white-space: nowrap;
}

/* "Is this your business?" removal/claim link on the detail card (js/detail.js) */
.detail-claim-link { font-size: 0.75rem; margin: 10px 0 0; }
.detail-claim-link a { color: var(--text-light, #667); text-decoration: underline; }

/* Pencil-in-a-circle edit-mode button (js/detail.js setupEditAccess) -
   the same circle language as the back/close buttons, opposite whichever
   circle the page already shows (venue page: top-right; overlay: 
   top-left). Only rendered for admins/owners of the listing. */
.detail-edit-btn {
    position: absolute;
    top: 12px;
    /* Above the Leaflet map (800 max), below the edit modals (1100). */
    z-index: 900;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: none;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.detail-edit-btn.right { right: 14px; }
.detail-edit-btn.left { left: 14px; }
.detail-edit-btn:hover,
.detail-edit-btn.active { background: rgba(0, 0, 0, 0.78); }

/* Edit mode is explicit: the click-to-edit affordances (per-field
   pencils + "+ Add" missing-fields) stay hidden until the admin/owner
   toggles the pencil button. */
.detail-scroll .inline-edit-pencil,
#venue-page-body .inline-edit-pencil,
.detail-scroll .inline-missing-fields,
#venue-page-body .inline-missing-fields { display: none; }

.detail-scroll.edit-mode .inline-edit-pencil,
#venue-page-body.edit-mode .inline-edit-pencil { display: inline-block; }
.detail-scroll.edit-mode .inline-missing-fields,
#venue-page-body.edit-mode .inline-missing-fields { display: block; }

/* app-container transform when theme editor open - the class goes ON the
   container itself (js/inlineEdit.js), scale 75% anchored right so the
   page sits beside the left theme panel. */
.app-container.inline-edit-active {
    transform-origin: right;
    scale: 75%;
}

/* ---- Edit-mode modals (js/inlineEdit.js) - the tick/trashcan convention */
.inline-edit-modal {
    position: fixed;
    inset: 0;
    display: flex;
    justify-content: left;
    /* Above the Leaflet map (its panes sit at 400, controls at 800). */
    z-index: 1100;
    padding: 16px;
}
.inline-edit-modal-box {
    background: #fff;
    border-radius: 16px;
    max-width: 460px;
    width: 100%;
    max-height: 96vh;
    overflow: auto;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
}
.inline-edit-modal-title {
    font-weight: 700;
    font-size: 1.05rem;
    padding: 16px 18px 0;
}
.inline-edit-modal-body { padding: 12px 18px; }
.inline-edit-modal-body .inline-edit-input { width: 100%; box-sizing: border-box; }
.inline-edit-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 0 18px 14px;
}
.ie-btn {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    font-size: 1.1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.ie-revert { background: #f1f3f5; color: #c0392b; }
.ie-revert:hover { background: #fdecea; }
.ie-accept { background: var(--header-blue, #1e6091); color: #fff; }
.ie-accept:hover { filter: brightness(1.1); }
.inline-edit-status { display: block; text-align: right; padding: 0 18px 12px; font-size: 0.8rem; color: #667; min-height: 1em; }
.ie-section-info { margin: 0; line-height: 1.5; color: #445; }

/* Edit-mode bottom buttons - only visible while edit mode is on */
.edit-mode-buttons { display: none; padding: 12px 20px; }
.detail-card.edit-mode .edit-mode-buttons,
#venue-page-body.edit-mode .edit-mode-buttons,
.detail-scroll.edit-mode .edit-mode-buttons { display: flex; gap: 8px; }
.edit-mode-theme-btn,
.edit-mode-map-btn {
    background: var(--header-blue, #1e6091);
    color: #fff;
    border: none;
    border-radius: 999px;
    padding: 8px 18px;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}

/* ---- The theme editor modal (half-screen, live preview) ---- */
.theme-modal .inline-edit-modal-box { max-width: 25%; }
.theme-editor-body { display: flex; flex-direction: column; gap: 10px; }
.theme-bg-row { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 6px; }
.theme-label { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #667; }
.theme-bg-row input[type="color"], .theme-widget-row .t-value, .theme-section-row input[type="color"] {
    width: 34px; height: 34px; border: 1px solid #dde2e7; border-radius: 8px; padding: 2px; cursor: pointer; background: #fff;
}
.theme-bg-row .t-bgcss { width: 100%; box-sizing: border-box; padding: 8px; border: 1px solid #dde2e7; border-radius: 8px; font-size: 0.85rem; }
.theme-widget-grid { display: flex; flex-direction: column; gap: 6px; }
.theme-widget-row { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.theme-sections { display: flex; flex-direction: column; gap: 6px; border-top: 1px solid #eef1f4; padding-top: 10px; }
.theme-section-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px; }
.theme-section-row .theme-font-row { flex-basis: 100%; justify-content: center; }

/* The size control: the up/down arrows above the big A (no wheel on
   mobile). */
.theme-font-row { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
.tsc-arrows { display: flex; gap: 10px; }
.tsc-arrows button {
    border: none;
    background: none;
    font-size: 0.7rem;
    line-height: 1;
    padding: 1px 4px;
    border-radius: 5px;
    color: var(--text-dark);
    cursor: pointer;
}
.tsc-arrows button:hover { background: rgba(0, 0, 0, 0.07); }
.tsc-a {
    font-size: 1.2rem;
    font-weight: 800;
    line-height: 1;
    cursor: ns-resize;
    user-select: none;
    color: var(--text-dark);
    padding: 4px 7px;
    border-radius: 8px;
    border: 1px solid transparent;
}
.tsc-a:hover { border-color: #dde2e7; background: rgba(0, 0, 0, 0.04); }

/* The textless panel - no title bar, the controls are the whole story. */

/* Per-panel theme overrides: each panel consumes --t-<widget>-<section>
   with the base theme (--t-<widget>) as the fallback, so an unset
   override inherits the theme exactly as before. */
.detail-links-section { background: var(--t-card-bg-links, var(--t-card-bg, var(--bg-beige))); }
.events-section { background: var(--t-card-bg-events, var(--t-card-bg, var(--bg-beige))); }
.detail-gallery-section { background: var(--t-card-bg-gallery, var(--t-card-bg, var(--card-white))); }
.events-section .detail-links-heading { color: var(--t-heading-events, var(--t-heading, inherit)); }
.events-section .detail-meta-list { color: var(--t-text-events, var(--t-text, inherit)); }

/* Bundle pages get the same explicit edit mode: pencils + the bottom
   buttons stay hidden until the pencil toggle (js/inlineEdit.js's
   setupBundleEditAccess). */
.bundle-hero .inline-edit-pencil,
.bundle-hero .edit-mode-buttons,
.bundle-hero .inline-missing-fields { display: none; }
.bundle-hero.edit-mode .inline-edit-pencil { display: inline-block; }
.bundle-hero.edit-mode .edit-mode-buttons { display: flex; }
.bundle-hero.edit-mode .inline-missing-fields { display: flex; }

/* The theme panel is click-to-target: the page beside it must stay
   clickable, so the modal's full-screen shell swallows no clicks - only
   the box is live. Field-editor modals (not .theme-modal) keep their
   normal backdrop behaviour. */
.inline-edit-modal.theme-modal { pointer-events: none; }
.inline-edit-modal.theme-modal .inline-edit-modal-box { pointer-events: auto; }

.theme-show-all {
    background: none;
    border: 1px solid #dde2e7;
    border-radius: 8px;
    color: #445;
    font-size: 0.72rem;
    padding: 2px 8px;
    margin-left: 8px;
    cursor: pointer;
    vertical-align: middle;
}
.theme-show-all:hover { background: #f0f3f6; }

.theme-target-hint {
    font-size: 0.78rem;
    color: #889;
    margin: 0 0 10px;
    line-height: 1.4;
}

/* Theme panel font-size rows (js/inlineEdit.js) */
.theme-font-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
}
.theme-font-row .theme-label { flex: 1; }
.theme-font-row .f-inc {
    width: 72px;
    padding: 4px 6px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.9rem;
}

/* The ring around the surface currently being themed (js/inlineEdit.js
   themeRing) - a soft glow that follows the element's shape. */
.theme-target-ring {
    box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.75), 0 0 16px rgba(13, 110, 253, 0.35);
}

/* The ?open= overlay gets the same 1:3 treatment as the app-container
   when the theme panel opens - it's the visible "page" in that mode. */
.detail-overlay.inline-edit-active {
    transform-origin: right;
    scale: 75%;
}

/* The emoji thumbs for imageless listings live in common.css (loaded on
   every page) - see the .thumb-emoji rules there. */
