/**
 * YDO predictive search dropdown.
 *
 * Brand tokens are declared as CSS variables so the final navy / light-blue
 * palette (see redesign brief) can be dropped in during the styling phase
 * without touching markup or JS.
 */
:root {
    --ydo-navy: #1b2a4a;          /* menu / page titles brand navy */
    --ps-chip-blue: #a1d3da;      /* chip/tag hover accent — local to predictive search */
    --ydo-blue-tint: #eef7f9;     /* hover background */
    --ydo-border: #e3e7ee;
    --ydo-muted: #8a93a6;
    /* Brand orange for the location pills. Note home-redesign.css declares --ydo-orange: #ef711d
       for the hero/strip icons - all but identical, and worth collapsing into one token if the two
       are meant to be the same colour. */
    --ydo-orange: #EE7223;
    --ydo-orange-hover: #D1641F;
}

/* (Google Places is no longer bound to the search box, so there is no
   .pac-container to hide here; predictive search owns the input.) */

.ydo-suggest-menu {
    position: absolute;
    z-index: 100000;
    min-width: 240px;
    max-width: 520px;
    max-height: 70vh;
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--ydo-border);
    border-radius: 8px;
    box-shadow: 0 12px 28px rgba(27, 42, 74, 0.16);
    padding: 6px 0;
    font-family: 'Open Sans', Roboto, Arial, sans-serif;
}

.ydo-suggest-group + .ydo-suggest-group {
    border-top: 1px solid var(--ydo-border);
}

.ydo-suggest-group-title {
    padding: 8px 16px 4px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ydo-muted);
}

.ydo-suggest-item {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 8px 16px;
    color: var(--ydo-navy);
    text-decoration: none;
    cursor: pointer;
    line-height: 1.3;
}

.ydo-suggest-item:hover,
.ydo-suggest-item.active {
    background: var(--ydo-blue-tint);
    color: var(--ydo-navy);
    text-decoration: none;
}

.ydo-suggest-label {
    font-size: 14px;
    font-weight: 600;
    flex: 1 1 auto;
}

/* A pin in front of the Locations, so "Dublin" the place reads differently from "Dublin Zoo" the
   venue at a glance. Inline SVG rather than an icon font: the dropdown is the first thing drawn
   after a keystroke and must not wait on a font file. */
.ydo-suggest-item[data-type="city"] .ydo-suggest-label::before {
    content: "";
    display: inline-block;
    width: 13px;
    height: 15px;
    margin-right: 7px;
    vertical-align: -2px;
    background-repeat: no-repeat;
    background-size: contain;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23EE7223' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'/><circle cx='12' cy='10' r='3'/></svg>");
}

.ydo-suggest-sub {
    font-size: 12px;
    color: var(--ydo-muted);
    flex: 0 0 auto;
    white-space: nowrap;
}

.ydo-suggest-all {
    display: block;
    padding: 10px 16px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--ydo-border);
    font-size: 13px;
    font-weight: 600;
    color: var(--ydo-navy);
    text-decoration: none;
    cursor: pointer;
}

.ydo-suggest-all:hover {
    background: var(--ydo-blue-tint);
    text-decoration: none;
}

/* ---- Search tags (chips below the hero / reused on /search) ---- */
.ydo-search-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    /* Vertical only. The element also carries .container, and a `padding` shorthand
       here would reset that 20px gutter to zero - which is what left "Popular" sitting
       20px to the left of the hero panel and the Featured heading. */
    padding-top: 16px;
    padding-bottom: 4px;
    font-family: 'Open Sans', Roboto, Arial, sans-serif;
}

/* Bootstrap's clearfix ::before/::after come with .container. This element is a flex
   container, so they are laid out as real (zero-width) flex items and each one eats an
   8px `gap` slot, nudging "Popular" off the gutter. Same trap as .row - see style.css. */
.ydo-search-tags::before,
.ydo-search-tags::after {
    content: none;
}

.ydo-search-tags-label {
    font-weight: 700;
    font-size: 13px;
    color: var(--ydo-navy);
    margin-right: 4px;
}

.ydo-tag {
    display: inline-block;
    padding: 6px 14px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    border: 1px solid var(--ydo-border);
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

/* The four colours below can be dressed for a season from Home Page Content, which writes
   them onto the chip row as custom properties — orange chips through Halloween, say. The
   stylesheet's own colours are the fallback in each var(), so a chip whose colour nobody set
   is drawn exactly as before and needs no markup of its own. */

.ydo-tag--city {
    background: var(--ydo-tag-city-bg, var(--ydo-orange));
    color: var(--ydo-tag-city-text, #fff);
    border-color: var(--ydo-tag-city-bg, var(--ydo-orange));
}

/* Hover darkens whatever the chip is, instead of snapping back to the brand orange: a blue
   chip that turned orange under the cursor would read as a different control. */
.ydo-tag--city:hover {
    background: var(--ydo-tag-city-bg, var(--ydo-orange-hover));
    border-color: var(--ydo-tag-city-bg, var(--ydo-orange-hover));
    color: var(--ydo-tag-city-text, #fff);
    text-decoration: none;
    filter: brightness(0.92);
}

.ydo-tag--cat {
    background: var(--ydo-tag-cat-bg, #fff);
    color: var(--ydo-tag-cat-text, var(--ydo-navy));
}

.ydo-tag--cat:hover {
    background: var(--ydo-tag-cat-bg, var(--ydo-blue-tint));
    border-color: var(--ydo-tag-cat-bg, var(--ps-chip-blue));
    color: var(--ydo-tag-cat-text, var(--ydo-navy));
    text-decoration: none;
    filter: brightness(0.96);
}

/* While the browser is asking the visitor to share their location, after a click on a
   "near me" chip - see geo-chips.js. The wait is capped at a few seconds, but it must
   never look like the click was missed. */
.ydo-tag.is-locating {
    opacity: 0.65;
    cursor: progress;
}

/* ---- /search filter accordions (Date / Ages / Facilities / Categories) ----
   The redesigned theme only reveals an open section via a `.is-open` class
   ("driven by inline JS" that was never added), but the markup uses Bootstrap's
   data-toggle="collapse" — and the PJAX re-expand code — which toggle `.in`.
   That mismatch left every "Show" toggle adding `.in` while the section stayed
   display:none, so sub-options and sub-categories could never be expanded
   (worst felt on mobile). Honour both class names so the toggles actually work. */
.advanced-filters-wrap .collapse.in,
.advanced-filters-wrap .collapse.is-open {
    display: block !important;
}
.advanced-filters-wrap .collapsing {
    display: block;
    height: auto;
}

/* The per-category expander is an empty <a data-toggle="collapse"> with no glyph,
   so the arrow to open sub-categories was invisible/untappable. Give it a clear,
   finger-sized affordance. */
.advanced-filters-wrap .checkbox > a[data-toggle="collapse"] {
    display: inline-block;
    width: 28px;
    height: 28px;
    line-height: 28px;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    color: var(--ydo-navy);
}
.advanced-filters-wrap .checkbox > a[data-toggle="collapse"]::after {
    content: "\25BC"; /* ▼ */
    font-size: 10px;
}
.advanced-filters-wrap .checkbox > a[data-toggle="collapse"][aria-expanded="true"]::after {
    content: "\25B2"; /* ▲ */
}

/* ---- Mobile main menu ----
   Theme bug: inside the mobile media query the menu was shown by
   `.navbar-collapse:not(.collapsed)`, but `.collapsed` lives on the toggle
   *button*, never on `.navbar-collapse` — so that selector is always true and
   the menu was permanently open (couldn't be closed). Drive visibility off
   Bootstrap's `.in` (toggled by the hamburger) instead, so it opens AND closes. */
@media (max-width: 991.98px) {
    .navbar-collapse:not(.in):not(.collapsing) {
        display: none !important;
    }
    .navbar-collapse.in {
        display: block !important;
    }
}

/* Tablet only (768–991.98px): the filter panel stacks above the results here
   and there's no FAB/bottom-sheet drawer at this width, so it must NOT stay
   position:sticky — otherwise it pins to the top and the result cards scroll
   underneath it (content overlaps the filters), and the tall panel can't be
   scrolled through cleanly. Make it a normal in-flow block instead.
   NOTE: this must NOT reach down to phone widths (<768px) — below 767px
   style.css turns `.advanced-filters-wrap` into the fixed FAB/bottom-sheet
   drawer, and this rule (loaded after style.css) would silently override
   that back to `position: static`, leaving the closed-but-`visibility:hidden`
   drawer sitting in normal flow and reserving its own full height as a big
   blank gap above the results. */
@media (min-width: 768px) and (max-width: 991.98px) {
    .advanced-filters-wrap {
        position: static !important;
        top: auto !important;
    }
}

/* Roomier filter sidebar on desktop when shown (both /search and the
   "Things to do in …" landing results). Collapsed state stays narrow. */
@media (min-width: 992px) {
    .advanced-search > .advanced-filters-wrap:not(.hide-filters),
    #search-block-grid > .advanced-filters-wrap:not(.hide-filters) {
        flex: 0 0 320px !important;
        width: 320px !important;
        max-width: 320px;
    }
    #search-block-grid > .filters-content {
        flex: 1 1 auto;
        min-width: 0;
    }
}

/* ---- Home widget: top 3-column row (2 cards + 1 ad unit, each 300×250) ---- */
.ydo-top-row {
    display: grid;
    /* The row spans the full content width, the way the stacked cards do on a phone - three equal
       columns. Exactly three of them are ever grid items: whichever of the ad cell and the stand-in
       card is not showing is display:none and so takes no track (see .ydo-top-card--fallback). */
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin-bottom: 24px;
}
/* With an advert actually rendered the third column is sized to the creative rather than to a
   third of the row: an MPU is exactly 300x250 and cannot stretch, so an equal column would leave
   it adrift in ~76px of empty cell. The two cards absorb that width instead, and the row still
   ends flush. Desktop only - below 992px the row is a single column anyway. */
@media (min-width: 992px) {
    .ydo-top-row.has-ad,
    .ydo-top-row:has(.ydo-top-card--ad iframe),
    .ydo-top-row:has(.ydo-top-card--ad .tile-item) {
        grid-template-columns: 1fr 1fr 300px;
    }
}
.ydo-top-card {
    display: flex;
    flex-direction: column;
}
.ydo-top-card > .tile-item {
    flex: 1 1 auto;
    /* .tile-item carries 24px of bottom margin for grid layouts that space themselves that way. The
       row spaces itself with a gap, so here it was only making the slot 24px taller than the card
       it holds - a strip of empty page under the last card in every main row. The rail's slides
       already escape this because the flex stretch absorbs it; this slot does not. */
    margin-bottom: 0;
}
/* The image area inside top cards is fixed at 250px to match 300×250 ad unit
   (scoped to the linked photo so the .ydo-img-logo badge keeps its own size) */
.ydo-top-card .tile-header a img {
    height: 250px;
    width: 100%;
    object-fit: cover;
    display: block;
}
/* Ad slot: sized to match a content card image, but ONLY once an ad has actually
   rendered. GPT's collapseEmptyDivs() drops the slot on a no-fill, so reserving 250px
   unconditionally left a grey placeholder block sitting in the row for the life of the
   page whenever nothing was served. Browsers without :has() simply fall back to an empty
   cell. (This used to lean on a blanket hide in style.css as well; that rule reached every
   ad container on the site and has been removed — see the note there.) */
.ydo-top-card--ad {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    overflow: hidden;
}
/* `.is-filled` is set by the slotRenderEnded listener in layouts/landing.php — Ad Manager's own
   answer about this slot, which is the only one worth trusting. The :has() tests below stay as a
   second opinion for anything that renders without firing the event. */
.ydo-top-card--ad.is-filled,
.ydo-top-card--ad:has(iframe),
.ydo-top-card--ad:has(.tile-item) {
    min-height: 250px;
    background: var(--ydo-bg, #f7f8fa);
}
/* Nothing rendered into the slot: drop the cell out of the grid entirely rather
   than leaving an empty third column (desktop) or a blank band above the
   "More great venues" heading (mobile, where the row stacks). */
.ydo-top-card--ad:not(.is-filled):not(:has(iframe)):not(:has(.tile-item)) {
    display: none;
}
/* Slot three's stand-in listing. Visible by default, because that is the state the page has to be
   correct in - an advert that never fills must not leave a hole where a card could be - and it
   steps aside the moment GPT puts a creative in the ad cell. The test mirrors the ad cell's own,
   so the two can never both show or both hide. */
.ydo-top-card--fallback {
    display: flex;
}
/* Descendant selectors inside :has(), never a nested :has() - the spec forbids one :has() inside
   another and a browser drops the whole rule as invalid, which silently left the stand-in card
   showing beside a filled advert. */
.ydo-top-row.has-ad .ydo-top-card--fallback,
.ydo-top-row:has(.ydo-top-card--ad iframe) .ydo-top-card--fallback,
.ydo-top-row:has(.ydo-top-card--ad .tile-item) .ydo-top-card--fallback {
    display: none;
}
/* Mobile: stack the 3 top cards vertically */
@media (max-width: 991px) {
    .ydo-top-row {
        grid-template-columns: 1fr;
    }
    .ydo-top-card .tile-header a img {
        height: 200px;
    }
    /* Same no-fill guard as the desktop rule above: stacked to one column, an
       unconditional min-height left a ~250px blank band between the main row and
       the "More great venues" heading whenever no ad was served. */
    .ydo-top-card--ad.is-filled,
    .ydo-top-card--ad:has(iframe),
    .ydo-top-card--ad:has(.tile-item) {
        min-height: 250px;
    }
}

/* ---- Home widget smaller sliding carousel (below top row) ---- */
.ydo-widget-rail-wrap { position: relative; margin-top: 8px; }
.ydo-widget-rail {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scroll-behavior: smooth;
    /* No horizontal padding: it offset the cards from the rail's own edges by 2px, which is the
       line the arrows are centred on. The vertical padding stays, and is not decoration:
       overflow-x: auto makes the vertical axis clip too, and .tile-item:hover lifts a card 3px with
       a larger shadow, so without this the top of that lift is cut off. */
    padding: 4px 0 14px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.ydo-widget-rail::-webkit-scrollbar { display: none; }
.ydo-widget-slide {
    flex: 0 0 220px;
    scroll-snap-align: start;
    display: flex;
}
.ydo-widget-slide > .tile-item { width: 100%; }
/* Carousel card images are smaller than top-row
   (scoped to the linked photo so the .ydo-img-logo badge keeps its own size) */
.ydo-widget-slide .tile-header a img {
    height: 150px;
    width: 100%;
    object-fit: cover;
    display: block;
}
.ydo-widget-nav {
    position: absolute;
    /* Centred on the cards rather than on the rail box: the rail carries 4px of top and 14px of
       bottom padding (room for the hover lift), so its own midpoint sits 5px below theirs. */
    top: calc(50% - 5px);
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    border: 1px solid var(--ydo-border, #e3e7ee);
    border-radius: 50%;
    background: #fff;
    color: var(--ydo-navy, #1b2a4a);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(13, 17, 23, .12);
    z-index: 5;
    display: none;
    align-items: center;
    justify-content: center;
}
.ydo-widget-nav:hover { background: var(--ydo-navy, #1b2a4a); color: #fff; }
/* Half the button's own 36px width, so its centre lands exactly on the rail's edge - which is the
   edge of the first and last card. At -10px the 36px button reached only 10px past the edge and its
   centre sat 8px inside the cards. */
.ydo-widget-nav--prev { left: -18px; }
.ydo-widget-nav--next { right: -18px; }
/* Cards spanning the rail exactly, rather than fixed-width ones leaving a remainder: at 220px
   apiece five of them stopped 12px short of the rail's right edge, so the arrow centred on that
   edge no longer sat on a card edge. The count steps down before the width would: a card cannot
   shrink past the min-content width of its own foot (a Book Now button beside the rating, ~204px),
   and below that floor the row silently overflows its last card again. */
@media (min-width: 992px) {
    .ydo-widget-rail {
        --ydo-rail-per-view: 4;
        /* A slice of the next card, left visible on purpose: it is what tells a visitor the row
           carries on past the edge. The arrows say the same thing, but only once you look for them,
           and on touch there are no arrows at all - the row below 992px has always peeked for
           exactly this reason. Reserved out of the track, so the cards shrink to make room rather
           than the row overflowing. */
        --ydo-rail-peek: 40px;
    }
    .ydo-widget-slide {
        flex: 0 0 calc(
            (100% - var(--ydo-rail-peek) - var(--ydo-rail-per-view) * 12px)
            / var(--ydo-rail-per-view)
        );
    }
    .ydo-widget-nav { display: flex; }
}
/* Five across only from 1200px, not 1140. With the peek taken out of the track first, five cards at
   1140 would need to be 200px - below the ~204px min-content width of a card's own foot (a Book Now
   button beside the rating), which a flex item cannot go under, and the row would spill past its
   last card again. */
@media (min-width: 1200px) {
    .ydo-widget-rail { --ydo-rail-per-view: 5; }
}
/* Nothing to scroll: six 220px slides is the first count that overflows the rail at every width the
   arrows appear at (from 992px, which leaves 952px of content), so below that they would be dead
   controls. Specificity puts this above the media rule regardless of source order. */
.ydo-widget-rail-wrap:not(:has(.ydo-widget-slide:nth-child(6))) .ydo-widget-nav {
    display: none;
}

/* ---- Home rows: card height ---- */

/* A flex rail stretches every card to the tallest, and .stats is pinned to the card's foot with
   margin-top:auto, so a single three-line heading pushed all ten cards ~50px taller and opened that
   much void under the short ones. Two lines then ellipsis; the heading is still the link's full
   text, so nothing is lost to assistive tech or to search engines. */
.ydo-top-card .tile-body h4,
.ydo-widget-slide .tile-body h4 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    /* Exactly two line boxes, not at most two: a one-line heading otherwise pulled the location and
       the date up by a line, so neighbouring cards in the row read on different baselines. `lh` is
       the line box's own height, so this stays right if the type scale changes. */
    min-height: 2lh;
}

/* The rating row sits at the foot of a card that is already taller than its content; 12px of air
   above it was sized for a roomier card than these rows now need. */
.ydo-top-card .stats,
.ydo-widget-slide .stats {
    padding-top: 8px;
    /* Sit the foot's contents on the card's bottom edge rather than centring them in a box whose
       height depends on whether the listing sells tickets. The row is 40px tall with a Book Now
       button and 22px without, and it is pinned to the bottom of the card, so centring put the
       rating at two different heights along a row. Aligning to the end puts every rating the same
       distance from the card's foot without making the shorter cards taller to match. */
    align-items: flex-end;
}
