/*
 * Design + UX refinements, layered over main.min.css.
 *
 * main.min.css has no Sass source in this repo. It is built in the ballyhass.ie
 * repo and copied here by ./bin/sync-theme-css.sh. Corrections therefore live
 * in this file and are enqueued after it.
 *
 * Every rule states the measured problem it addresses. Most fix a failure.
 * Section 11 is the exception and says so: it is a brand-correctness
 * preference over a value that already passes.
 *
 * Until 2026-10-03 main.min.css was maintained by hand, because the build it
 * comes from had not run since Node 14. Several rules here exist only because
 * that hand-maintenance went wrong. When the build output changes, re-check
 * whether a rule here is still needed, still correct, or now overriding a
 * better value. One already was: see the note at section 11.
 *
 * Contrast targets come from the brand guidelines' two documented WCAG
 * conflicts: white on Ballyhass Blue is 2.42:1 and white on Ballyhass Pink is
 * 3.11:1, both failing AA. Navy on Blue is 6.23:1 and Navy on Pink is 4.84:1.
 * #0B7A8E is the accessible blue for blue text on white, at 5.01:1.
 */

/* ---------------------------------------------------------------------------
 * 1. Hero search widget — four items at 33.33% never fit on one row
 *
 * .home .banner .user-select is a max-width:800px flex-wrap container, and
 * from 768px up every .form-group was flex: 0 0 33.3333%. Three fill the row
 * exactly, so the fourth — FIND ADVENTURE — wrapped to a second line at the
 * far left with 533px of dead space beside it. It read as a layout accident
 * rather than a search bar. Mobile stacks all four full-width and was already
 * correct, so nothing below 768px is touched.
 * ------------------------------------------------------------------------ */

/* Desktop: one row of four — location, activity, date, submit. */
@media (min-width: 992px) {
    .home .banner .user-select .form-group {
        flex: 0 0 25%;
    }
}

/* Tablet: keep three fields across, but let the button own its own full-width
   row so the arrangement looks deliberate instead of stranded. */
@media (min-width: 768px) and (max-width: 991.98px) {
    .home .banner .user-select .form-group:last-child {
        flex: 0 0 100%;
    }
}

/* ---------------------------------------------------------------------------
 * 2. The date field read as disabled
 *
 * Location and Activity are bootstrap-select toggles, which main.min.css
 * paints white !important. The date field is a flatpickr input that never got
 * the same treatment, so it sat at #EDEDED next to two white fields and looked
 * greyed out — the one field people most expect to be interactive.
 * ------------------------------------------------------------------------ */
form.user-select .user-select__calendar input,
form.user-select input[name="date"] {
    background-color: #fff;
}

/* ---------------------------------------------------------------------------
 * 3. Contrast failures
 * ------------------------------------------------------------------------ */

/* Selected/hovered item in the location + activity dropdowns was white on
   Ballyhass Blue — 2.42:1. Navy on the same blue is 6.23:1. */
form.user-select .dropdown-item.active,
form.user-select .dropdown-item:active,
form.user-select .dropdown-item:hover {
    color: #21272F;
}

/* .button--white rests on navy (15.04:1) but its hover rule sets both
   background Ballyhass Pink and colour white — 3.11:1. Navy on pink is
   4.84:1. (.button--dark is already corrected by a later rule in
   main.min.css; it is listed here only so the two variants cannot drift
   apart, and sets the same value.) focus-visible is included so keyboard
   users get the corrected pairing rather than an untested one. */
.button--white:hover,
.button--white:focus-visible,
.button--dark:hover,
.button--dark:focus-visible {
    color: #21272F;
}

/* Mobile menu CTAs ("Checkout Now", "Login"). The colour lives on the inner
   span, not the anchor: white on Ballyhass Blue, 2.42:1. Navy on that blue is
   6.23:1. The hover state swaps the background to navy, so the text has to
   flip back to white there or it would be navy-on-navy. */
.mmcta span {
    color: #21272F;
}

.mmcta span:hover,
.mmcta a:hover span,
.mmcta a:focus-visible span {
    color: #FFFFFF;
}

/* ---------------------------------------------------------------------------
 * 4. Activity card price — the two prices collided
 *
 * .product__text is a flex row and its span is flex: 0 0 45% with
 * margin-top: 8px, so "From €99pp" and "€79pp with Adventure Pass" sat side by
 * side with the second squeezed into 160px, wrapping onto two lines and
 * dropping 8px below the first's baseline. The parent is 40px tall and the
 * span 32px starting 8px down, so it overflowed its own container and clipped
 * on the last card in the row. Stacked, the Adventure Pass price reads as the
 * secondary line it is. Scoped to the homepage: .product--package and the
 * all-access-pass slider use the same class with different intent.
 * ------------------------------------------------------------------------ */
.home .product__text {
    flex-direction: column;
    align-items: flex-start;
}

.home .product__text span {
    flex: 0 0 auto;
    width: 100%;
    margin-top: 4px;
    white-space: normal;
}

/* ---------------------------------------------------------------------------
 * 5. Touch targets below WCAG 2.2 AA 2.5.8 (24x24 CSS px)
 *
 * Footer social icons render at 18x30 (too narrow) and the contact links at
 * 20px tall. Padding is added rather than font-size so nothing reflows.
 * ------------------------------------------------------------------------ */
.footer__social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    min-height: 24px;
}

a[href^="mailto:"],
a[href^="tel:"] {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
}

/* ---------------------------------------------------------------------------
 * 6. Visible keyboard focus (WCAG 2.2 1.4.11, 2.4.7, 2.4.13; 31 October 2026)
 *
 * Every control the keyboard reaches takes the same indicator: the tokens'
 * navy ring with white either side (tokens.css, "Focus"), which keeps 3:1 or
 * more on white, Ballyhass Blue, navy and photographs alike. The brand-blue
 * ring it replaces was 2.42:1 on white.
 *
 * It is written once, here, and wins over every other focus rule in the
 * theme, main.min.css and the legacy page styles (the :not(#bh-focus-none)
 * gives it an id's weight, and !important beats main.min.css's own
 * !important rings). The few elements that show their focus on something
 * else (a whole card, a tile's ::after) or that only a script focuses are
 * left out by name, and their stand-ins take the same ring below. A field
 * you type in takes it however it was focused, as browsers do: Chrome does
 * not count a date field reached by Tab on a phone as :focus-visible.
 * ------------------------------------------------------------------------ */
:focus-visible:not(#bh-focus-none, [tabindex="-1"], .bh-book__results, .bh-gj__title, .bh-dest-tile__link, .bh-ideas__rows .bh-row__cta, .bh-dest-feature__activity-name, .bh-news-card__link),
:is(input, textarea):focus-within:not(#bh-focus-none, [type=checkbox], [type=radio], [type=button], [type=submit], [type=reset], [type=range], [type=file], [type=color], [type=image]) {
    outline: var(--bh-focus-width) solid var(--bh-focus-color) !important;
    outline-offset: var(--bh-focus-offset) !important;
    box-shadow: var(--bh-focus-shadow) !important;
}

/* main.min.css drew Chrome's own ring on every :focus once the Tab key had been pressed
   (body.user-is-tabbing, !important), a mouse click included. Keyboard focus takes the ring
   above; anything else draws none. */
body.user-is-tabbing :focus:not(:focus-visible) {
    outline: none !important;
}

/* ---------------------------------------------------------------------------
 * 7. Activity summary facts
 *
 * Duration / suitable ages / minimum height, lifted out of the legacy body
 * copy into _activity_* meta by artifacts/migration/map-activity-summary.php.
 * The list is a direct child of .summary__body, so it already inherits the
 * label/value row layout from main.min.css — all it needs is separation from
 * the locations list above it.
 * ------------------------------------------------------------------------ */
.summary__facts {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid rgba(21, 66, 155, 0.15);
}

.summary__facts li + li {
    margin-top: 6px;
}

/* ---------------------------------------------------------------------------
 * 8. Header nav contrast (WCAG 2.2 AA, 1.4.3)
 *
 * Two separate failures, both from .c-navbar .nav-link{color:white}:
 *
 *   Transparent state — the nav floats over whatever the banner is. On the
 *   homepage that is a dark photo and white reads fine; on interior pages it
 *   is the cyan wave, where white measures 2.42:1.
 *   Scrolled / menu-open — .c-navbar.active sets background-color:#00B6D9,
 *   so white nav is 2.42:1 on EVERY page, homepage included. The current-page
 *   link is worse still: Bootstrap #007bff on that cyan is 1.65:1.
 *
 * Fixed without touching the templates or main.min.css:
 *
 *   1. A gradient scrim behind the transparent nav. White then passes over any
 *      banner (8.57:1 over the cyan wave) and the homepage hero is unchanged
 *      in character — it only deepens slightly at the very top.
 *   2. Navy nav text once the bar goes blue. #21272F on #00B6D9 is 6.23:1 and
 *      is already the documented house rule for this pairing (the brand guide
 *      shows white on blue, which fails; see docs/brand-guidelines.md).
 *
 * The current-page link also gets a non-colour cue, so it is not signalled by
 * colour alone (1.4.1).
 * ------------------------------------------------------------------------ */

/* 1. Scrim — transparent state only, so it never doubles up on the blue bar. */
.c-navbar:not(.active):not(.menu-open)::before {
    position: absolute;
    z-index: -1;
    top: 0;
    right: 0;
    left: 0;
    height: 100%;
    content: "";
    pointer-events: none;
    background: linear-gradient(
        to bottom,
        rgba(10, 22, 30, 0.62) 0%,
        rgba(10, 22, 30, 0.38) 55%,
        rgba(10, 22, 30, 0) 100%
    );
}

/* 2. Navy nav text wherever the bar is Ballyhass Blue. */
.c-navbar.active .nav-link,
.c-navbar.menu-open .nav-link {
    color: #21272F;
}

/* Current page: navy on the blue bar, white over the scrim, underlined in
   both so the state is not carried by colour alone. */
.c-navbar .nav-item.is-active .nav-link,
.c-navbar .nav-item.current-menu-item .nav-link {
    color: #FFFFFF;
    text-decoration: underline;
    text-underline-offset: 4px;
}

.c-navbar.active .nav-item.is-active .nav-link,
.c-navbar.active .nav-item.current-menu-item .nav-link,
.c-navbar.menu-open .nav-item.is-active .nav-link,
.c-navbar.menu-open .nav-item.current-menu-item .nav-link {
    color: #21272F;
}

/* Hover already resolves to navy on Activities Yellow (13.34:1) — leave it,
   but make sure the blue-bar state does not lose it to the rule above. */
.c-navbar.active .nav-link:hover,
.c-navbar.menu-open .nav-link:hover {
    color: #21272F;
    background-color: #E4FF1A;
}

/* ---------------------------------------------------------------------------
   Footer legal strip

   The footer had no route to the privacy policy, the cookie policy or the
   accessibility statement. All three were written and published, and nothing
   linked to them, so they were reachable only by typing the URL.

   Sits below the footer columns, quiet by design: these are links people go
   looking for rather than links that should compete with the navigation.
   --------------------------------------------------------------------------- */
.footer__legal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1.5rem;
    margin-top: 2.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(33, 39, 47, 0.22);
}

.footer__legal-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.footer__legal-links a,
.footer__copyright {
    /* The footer sits on Ballyhass cyan (#00B6D9), so this is dark on light,
       matching the rest of the footer. White at 72% composites to a pale tint
       against that cyan and lands around 1.8:1, which is unreadable and fails
       AA; the navy is 6:1 and matches the contrast work done elsewhere. */
    color: #21272F;
    font-size: 0.875rem;
    text-decoration: none;
}

.footer__legal-links a:hover,
.footer__legal-links a:focus-visible {
    color: #000000;
    text-decoration: underline;
    text-underline-offset: 3px;
}


.footer__copyright {
    margin: 0;
}

@media (max-width: 575.98px) {
    .footer__legal {
        justify-content: flex-start;
    }
}

/* ---------------------------------------------------------------------------
   Careers page

   /careers/ was rebuilt from careers.ballyhass.ie, which was an Elementor
   build. Its layout came from the builder, so the content needed markup of its
   own here. These are the classes that markup uses.

   Colours follow the brand and the accessibility overrides already recorded in
   this file: navy on yellow and navy on blue, and #0B7A8E where blue text sits
   on white, since #00B6D9 on white is 2.42:1 and fails AA.
   --------------------------------------------------------------------------- */

/* Logo strips: accreditations, awards, sustainability partners.
   The images were collapsing to zero because a bare list item gives an inline
   image no box to size against. */
.careers__logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 1.5rem 2.5rem;
    margin: 1.5rem 0 2.5rem;
    padding: 0;
    list-style: none;
}

.careers__logos li {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 90px;
}

.careers__logos img {
    width: auto;
    height: auto;
    max-width: 150px;
    max-height: 72px;
    object-fit: contain;
}

/* The "what you get" tags under Mission and values. Navy block, yellow text,
   square corners, which is the brand's highlighted-text treatment. */
.careers__benefits {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 1.5rem 0 2rem;
    padding: 0;
    list-style: none;
}

.careers__benefits li {
    padding: 0.4rem 0.85rem;
    background-color: #21272F;
    color: #E4FF1A;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.3;
}

/* Training and community sponsorship totals. */
.careers__stats {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem 3rem;
    margin: 2rem 0;
    padding: 1.5rem 0;
    border-top: 2px solid #21272F;
    border-bottom: 2px solid #21272F;
    list-style: none;
}

.careers__stats li {
    flex: 1 1 240px;
    color: #21272F;
}

.careers__stats strong {
    display: block;
    color: #0B7A8E;
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
}

.careers__courses {
    margin: 1rem 0 1.5rem;
    padding-left: 1.25rem;
}

.careers__courses li {
    margin-bottom: 0.4rem;
}

/* Team photographs. A fixed aspect ratio keeps the row even when the source
   images are a mix of landscape and portrait. */
.careers__gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    margin: 2rem 0;
    padding: 0;
    list-style: none;
}

.careers__gallery img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
}

/* The aerials are 2048px tall originals and would otherwise run the length of
   the screen on their own. Scoped to figures so it cannot reach the logo strips
   or the gallery, which set their own sizing above. */
.page-content .entry-content > figure img {
    width: 100%;
    max-height: 560px;
    object-fit: cover;
    display: block;
}

.page-content .entry-content video {
    width: 100%;
    max-width: 100%;
    height: auto;
    display: block;
}

/* ---------------------------------------------------------------------------
 * 10. Book Now button, hover state only (WCAG 2.2 AA, 1.4.3)
 *
 * The resting state of this button was already corrected: navy on Ballyhass
 * Yellow measures 13.34:1, and on the scrolled bar white on navy is 15.04:1.
 * Both pass comfortably.
 *
 * The hover state was missed. Both
 *
 *   .theme-25 .c-navbar .btn-booking:hover
 *   .theme-25 .c-navbar.active .btn-booking:hover
 *
 * set background-color:#FF4F8E with colour white, which measures 3.11:1. That
 * is below the 4.5:1 required for normal text, so the label is hardest to read
 * at the exact moment the pointer is on it.
 *
 * This is the site's primary call to action and the class appears on all 102
 * published pages, so it is the single most-rendered contrast failure on the
 * site rather than a corner case.
 *
 * Navy on Ballyhass Pink is 4.84:1 and passes. It is also the pairing the
 * brand guide's accessibility override already prescribes for pink, the same
 * rule section 8 applied to blue, so this needs no new decision.
 *
 * The pink background is deliberately kept: the hover still reads as pink, it
 * is only the label that changes colour.
 * ------------------------------------------------------------------------- */

.theme-25 .c-navbar .btn-booking:hover,
.theme-25 .c-navbar .btn-booking:focus,
.theme-25 .c-navbar .btn-booking:focus-visible,
.theme-25 .c-navbar.active .btn-booking:hover,
.theme-25 .c-navbar.active .btn-booking:focus,
.theme-25 .c-navbar.active .btn-booking:focus-visible {
    color: #21272F;
}

/* ---------------------------------------------------------------------------
 * 11. Body link colour (WCAG 2.2 AA, 1.4.3)
 *
 * Retired half of this section on 2026-10-03. It originally also corrected
 * .button--aqua, which was white on Pink at 3.11:1 in the hand-maintained
 * stylesheet. main.min.css is now generated by the repaired build and carries
 * the source's own #000 there at 6.76:1, which beats the 4.84:1 navy this
 * section used to impose, so the override would have made it worse. Gone.
 *
 * What remains is a genuine preference, not a fix for a broken artifact.
 * The generated stylesheet renders `a` at #15429B, which passes at 9.19:1, so
 * this is no longer fixing a failure. It is kept because #15429B is
 * `royal-blue` from the Bootstrap theme map and is not a Ballyhass colour at
 * all. #0B7A8E is the accessible blue the brand guide's own override
 * prescribes for blue text on white (5.01:1), and the theme already uses it
 * for .bh-jobs__meta. Brand-correct and passing beats passing alone.
 *
 * Equal specificity to the rule it overrides, so the 27 contextual link rules
 * that set their own colour (nav, footer, cards) still win, and the header
 * nav, which sets white at higher specificity, is unaffected.
 * ------------------------------------------------------------------------- */

a {
    color: #0B7A8E;
}

/* ---------------------------------------------------------------------------
 * 12. .button--bordered-aqua resting state (WCAG 2.2 AA, 1.4.3)
 *
 * This one is a fault in the Sass source, not in the copy shipped here, so
 * regenerating main.min.css from the repaired build does not clear it.
 * _brand-compliance.scss corrects this button's :hover and :focus and leaves
 * its resting state, and the build faithfully reproduces that omission.
 *
 * It stays a WordPress-side override because that partial is shared with the
 * live legacy ballyhass.ie site. Fix it at source when the two are no longer
 * shared.
 *
 * The button declares background-color #00B6D9 and color #00B6D9, which reads
 * as invisible text in a static audit. It is not: a ::before pseudo-element
 * paints white over it and the label sits above that on z-index 2, so what
 * renders at rest is Ballyhass Blue on white at 2.42:1. Measured in the
 * browser, not inferred: six instances on /activities/aqua-park/ alone, on
 * every activity card's EXPLORE link.
 *
 * #0B7A8E keeps the button reading as blue and passes at 5.01:1. On hover the
 * white overlay slides away to reveal the aqua background, and the
 * brand-compliance rule already sets navy there, which is 6.23:1.
 * ------------------------------------------------------------------------- */

.button--bordered-aqua {
    color: #0B7A8E;
}

/* ---------------------------------------------------------------------------
 * 13. Activity card price (WCAG 2.2 AA, 1.4.3)
 *
 * .product__text is the "From 12.00" price on every activity card. It renders
 * Ballyhass Blue on white at 2.42:1.
 *
 * At 22px and weight 900 it qualifies as large text, so the threshold it has
 * to clear is the relaxed 3:1 rather than 4.5:1. It fails that too.
 *
 * Checked every instance before changing it: all six on
 * /activities/aqua-park/ are the same colour, weight, size and white
 * background, so there is no dark-background variant this would break.
 *
 * #0B7A8E is the same accessible blue used in sections 11 and 12, and clears
 * the stricter 4.5:1 threshold at 5.01:1 rather than only the large-text one.
 *
 * This one is not a build artefact. The Sass source has the same value, so a
 * rebuild will not clear it. Fix it at source when _brand-compliance.scss is
 * no longer shared with the live legacy site.
 * ------------------------------------------------------------------------- */

.product__text {
    color: #0B7A8E;
}

/* The price line now carries the booking system's own label (inc/activity-
   offers.php), which can be long: "Wakepark - Learn to Wakeboard, from €40".
   main.min.css sets it nowrap, so it ran out of the card. It wraps into the
   two lines section 27 already reserves. */
.card.product .product__text {
    white-space: normal;
}

/* ---------------------------------------------------------------------------
 * 14. Activity pages whose body is a whole-page design
 *
 * An activity's body sits in the column left of the floated 350px summary.
 * The designs recovered from the legacy product categories were written for
 * that column. Team Challenge carries the Corporate page instead (the legacy
 * site had no Team Challenge category), a design for the full width, and in
 * the column its headings wrapped a word to a line.
 *
 * single-activity.php adds .main--wide when the body's design came from a
 * legacy page (ballyhass_legacy_body_is_page). The summary becomes a band
 * under the banner and the body takes the full container. The static map is
 * dropped from the band: it is a picture of the same two pins on every page
 * and the band is about booking.
 * ------------------------------------------------------------------------- */

@media (min-width: 768px) {
    .main--wide .main__side {
        float: none;
        width: 100%;
        margin-bottom: 48px;
    }

    .main--wide .main__body {
        margin: 0;
        padding: 0;
    }
}

@media (min-width: 992px) {
    .main--wide .main__side {
        margin-top: -96px;
    }

    .main--wide .summary {
        display: grid;
        grid-template-columns: minmax(220px, 280px) 1fr;
    }

    .main--wide .summary__head {
        display: flex;
        flex-direction: column;
        justify-content: center;
    }

    .main--wide .summary__body {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 16px 40px;
        background: #FFFFFF;
    }

    .main--wide .summary__body > ul {
        display: flex;
        gap: 32px;
    }

    .main--wide .summary__body > ul li p {
        gap: 12px;
        margin: 0;
    }

    .main--wide .summary__body .button,
    .main--wide .summary__body .c-booking-widget {
        margin: 0 0 0 auto;
    }

    .main--wide .summary__body .map {
        display: none;
    }
}

/* ---------------------------------------------------------------------------
 * 15. Homepage core values: one per row with 50px gaps
 *
 * .sellpoint__body is a wrapping flex row with gap:32px, and each value is
 * flex 0 0 50%. Two halves plus the gap is wider than the row, so every value
 * wrapped onto its own line, and the nth-child top margins written for the
 * pre-gap layout stacked another 50px on each. The seven values ran a narrow
 * column twice the height of the mission copy beside it.
 *
 * Same in the Sass source, so a rebuild will not clear it; it dates from
 * before browsers supported gap on flexbox, when the gap was ignored.
 * ------------------------------------------------------------------------- */

.sellpoint__body {
    row-gap: 40px;
}

.sellpoint__body li {
    flex: 0 0 calc(50% - 16px);
    max-width: calc(50% - 16px);
}

.sellpoint__body li:nth-child(n) {
    margin-top: 0;
}

@media (min-width: 768px) and (max-width: 991.98px) {
    .sellpoint__body li {
        flex-basis: calc(33.333% - 21.34px);
        max-width: calc(33.333% - 21.34px);
    }
}

/* ---------------------------------------------------------------------------
 * 16. Plain prose pages: a reading measure and heading rhythm
 *
 * Bodies that are ordinary prose (body class bh-prose, set in
 * inc/legacy-content.php) ran the full container, about 170 characters a
 * line, and their headings sat on the paragraph above with no space. Designed
 * bodies are untouched: they bring their own layout.
 * ------------------------------------------------------------------------- */

.bh-prose .entry-content {
    font-size: 1.0625rem;
    line-height: 1.7;
}

/* The measure is on the text, not the container, so a prose page's tables
   (the Cookie Policy's seven cookie tables) keep the full width. */
.bh-prose .entry-content :is(p, ul, ol, h2, h3, h4, blockquote, dl) {
    max-width: 46rem;
}

.bh-prose .entry-content h2 {
    margin: 2.5rem 0 0.75rem;
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.2;
}

.bh-prose .entry-content h3,
.bh-prose .entry-content h4 {
    margin: 2rem 0 0.5rem;
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.3;
}

.bh-prose .entry-content > :first-child {
    margin-top: 0;
}

.bh-prose .entry-content ul,
.bh-prose .entry-content ol {
    padding-left: 1.25rem;
    margin-bottom: 1.25rem;
}

.bh-prose .entry-content li + li {
    margin-top: 0.35rem;
}

.bh-prose .entry-content img {
    max-width: 100%;
    height: auto;
}

/* Wide tables (the cookie audit is 513px) scroll inside the measure instead
   of being clipped by the page's overflow-x: hidden on a phone. */
.bh-prose .entry-content table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
}

/* ---------------------------------------------------------------------------
 * 17. Space between the banner and the body on phones
 *
 * page.php's article carries Bootstrap's py-5 (48px, !important) and scraped
 * bodies open with .wysywig's 40px top margin: about 100px of white between
 * the banner's rip edge and the first line on a 390px screen.
 * ------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
    .page-content article.py-5 {
        padding-top: 1.25rem !important;
        padding-bottom: 2rem !important;
    }

    .entry-content > .wysywig:first-child,
    .entry-content > section.wysywig:first-child {
        margin-top: 0;
    }
}

/* ---------------------------------------------------------------------------
 * 18. Banner titles on phones
 *
 * The title is a fixed 60px with -2px tracking below 992px, so a long word
 * cannot fit a 390px screen: "Wakeboarding" was clipped to "Wakeboardin".
 * It scales with the viewport and may break inside a word as a last resort.
 * ------------------------------------------------------------------------- */

@media (max-width: 991.98px) {
    .banner figcaption h1 {
        font-size: clamp(2.25rem, 11vw, 3.75rem);
        letter-spacing: -0.03em;
        overflow-wrap: anywhere;
    }
}

/* ---------------------------------------------------------------------------
 * 19. The navy bar, for pages that open with their own designed hero
 *
 * page.php drops the photo banner and its title when the body opens with a
 * designed hero (ballyhass_body_has_own_hero). The first version kept the
 * photo as a short strip with no title, which reviewers read as a broken
 * hero, and on phones the strip's photo covered only part of its width.
 * Now it is a plain navy bar the height of the header, with the torn edge,
 * so the transparent header has something to sit on and the page's own hero
 * starts straight underneath.
 * ------------------------------------------------------------------------- */

body:not(.home) .banner.banner--slim {
    height: 100px;
    margin-bottom: 0;
    background-color: #21272F;
}

@media (min-width: 992px) {
    body:not(.home) .banner.banner--slim {
        height: 140px;
    }
}

body:not(.home) .banner.banner--slim::before,
body:not(.home) .banner.banner--slim::after {
    content: none;
}

body:not(.home) .banner.banner--slim figure {
    height: 100%;
    margin: 0;
}

body:not(.home) .banner.banner--slim figure::after {
    height: 36px;
}

/* ---------------------------------------------------------------------------
 * 20. Camp "at a glance" facts on the dark panel
 *
 * The recovered camp designs (Cadets, Cutting Edge, ASD Active Adventurers)
 * colour fact values navy and lighten only h3 and p on --dark panels, so on
 * Mallow Cadets the values were navy on navy: labels with empty boxes. A slip
 * in the legacy CSS, carried over with it.
 * ------------------------------------------------------------------------- */

.bh-cadets-v1__panel--dark .bh-cadets-v1__fact span,
.bh-cutting-edge-v1__panel--dark .bh-cutting-edge-v1__fact span,
.bh-asd-camp-v1__panel--dark .bh-asd-camp-v1__fact span {
    color: #FFFFFF;
}

.bh-cadets-v1__panel--dark .bh-cadets-v1__fact b,
.bh-cutting-edge-v1__panel--dark .bh-cutting-edge-v1__fact b,
.bh-asd-camp-v1__panel--dark .bh-asd-camp-v1__fact b {
    color: rgba(255, 255, 255, 0.72);     /* about 9:1 on the navy panel */
}

.bh-cadets-v1__panel--dark .bh-cadets-v1__fact,
.bh-cutting-edge-v1__panel--dark .bh-cutting-edge-v1__fact,
.bh-asd-camp-v1__panel--dark .bh-asd-camp-v1__fact {
    border-bottom-color: rgba(255, 255, 255, 0.14);
}

/* ---------------------------------------------------------------------------
 * 21. Embeds and wide tables inside page bodies
 *
 * A 640px YouTube iframe on Things To Do In Cork ran off a 390px screen, and
 * Wakeboarding's "Find the Right Session" table was clipped by the body
 * column, losing its booking buttons. Embeds scale; wide tables scroll.
 * ------------------------------------------------------------------------- */

/* :where() keeps these at the specificity of a bare element selector, so a
   designed block that sizes its own video frame still wins. */
:where(.entry-content, .wysywig) iframe {
    max-width: 100%;
}

:where(.entry-content, .wysywig) iframe[src*="youtube"] {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
}

.wakepark-table-wrap {
    overflow-x: auto;
}

/* ---------------------------------------------------------------------------
 * 22. Corporate package badges
 *
 * "Best fit for most teams" and "Flexible event option" are pinned to the
 * card's top-right corner on desktop and sat on the card's kicker and its
 * "04". The design already stacks them above the content on phones; that
 * works at every width. Parent classes added because the legacy rule loads
 * after this file and would win a tie.
 * ------------------------------------------------------------------------- */

.bh-corp-v3-package-card .bh-corp-v3-package-badge,
.bh-corp-v3-more-card .bh-corp-v3-more-badge {
    position: static;
    align-self: flex-start;
    margin-bottom: 14px;
}

/* Retreat package cards (Overnight Groups): the button is pushed down with
   margin-top:auto and the list has no bottom margin, so in the tallest card
   the last bullet sat under the button. */
.bh-rs-price-card .bh-rs-list {
    margin-bottom: 18px;
}

/* ---------------------------------------------------------------------------
 * 23. Second full-site review (24 Oct 2026)
 * ------------------------------------------------------------------------- */

/* "Popular Activities" on activity pages: cells are only sized under
   .product-slider, and this section is .section--reveal, so each cell took
   its image's width and the first card was twice the rest. */
.section--reveal .carousel-cell {
    width: 80%;
    min-width: 332px;
    max-width: 395px;
    margin-right: 20px;
}

/* News featured article: copy is absolutely positioned at 50% width with no
   phone rule (the legacy one was in dev.css, never loaded here), so the
   headline ran over the photo and went a word per line on a phone. */
@media (max-width: 991.98px) {
    .featured-article__content {
        position: static;
        width: 100%;
        margin-bottom: 24px;
    }

    /* A 26-word headline at the desktop size ran to eight lines on a phone. */
    .featured-article__content h2 {
        font-size: clamp(1.625rem, 6vw, 2.5rem);
        line-height: 1.15;
    }

    .featured-article__image img {
        width: 100%;
        margin-right: 0;
    }

    .section--featured-article {
        margin-bottom: 80px;
    }
}

/* Dark calculator panels whose notes kept a grey meant for white cards:
   Adventure Pass "Remember" (#47606a and #111 on near-black) and the
   Memberships sauna maths note. */
body .bh-ap-summary-note span {
    color: rgba(255, 255, 255, 0.82);
}

body .bh-ap-summary-note strong {
    color: #FFFFFF;
}

.bh-memberships-page .bh-summary-note {
    color: rgba(255, 255, 255, 0.82);
}

/* Paddle Boarding: three price cards in a half-width card inside the activity
   column; 1fr tracks would not shrink below their content, so the third was
   cut off. The design's own two-column split stacks in that column. */
body .bh-ksp-pricing {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.main__body .bh-ksp-grid-2 {
    grid-template-columns: minmax(0, 1fr);
}

/* The activity body column kept an 8.3% left margin from 1440px, ~115px the
   recovered designs needed: their sub-grids ran a word or three per line. */
@media (min-width: 1440px) {
    .main__body {
        margin-left: 0;
    }
}

/* Phones: the static "Find Us" map in the activity summary pushed the body
   ~300px down. The address and location are already in the summary. */
@media (max-width: 767.98px) {
    .summary__body .map {
        display: none;
    }
}

/* Showcase Day "Register your interest": the dashed drop-zone styling of a
   form slot read as unfinished; the panel now holds real contact copy. */
body .bh-showcase-form-placeholder {
    min-height: 0;
    border: 1px solid rgba(33, 39, 47, 0.12);
    padding: 24px;
}

/* Groups on phones: the CTA row turns into a column, and the buttons' 220px
   flex basis became their height (two ~220px ovals). The brochure stamp sits
   at left:-60px and was clipped off the screen edge. */
@media (max-width: 767.98px) {
    body .group-cta-row a {
        flex: 0 0 auto;
    }

    .sellpoint .download-brochure {
        left: 0;
    }
}

/* FAQs "Solve your issue quickly": a light .bh-card.soft nested in a
   .bh-card.dark inherited the dark card's white text, white on white. */
/* Every heading level: body headings are demoted a level on pages with
   their own H1, so this card's h3 is an h4 here. */
.bh-card.dark .bh-card.soft,
.bh-card.dark .bh-card.soft :is(h2, h3, h4, h5),
.bh-card.dark .bh-card.soft p {
    color: #21272F;
}

/* Designed lists inside a legacy accordion: .accordion .card-body ul sets
   list-style:disc at higher specificity, so lists that draw their own bullets
   showed two (Coachford sauna pricing). */
.accordion .card-body ul[class*="bh-"] {
    list-style: none;
}

/* "Best for most groups" (Sports & Youth) is pinned over the card kicker, the
   same collision as the Corporate badges; it sits above the content instead. */
body .bh-sy-build-card.featured::before {
    position: static;
    align-self: flex-start;
    margin-bottom: 12px;
}

/* Birthday Enquiries / Plan Your School Trip: the breadcrumb bar is absolute
   at the top of the hero, and the hero copy is bottom-aligned and taller than
   the hero, so its pill rose into the breadcrumb. Room is made at the top of
   the hero instead (moving the bar into the flow made it a flex item beside
   the copy and squeezed the copy into a narrow column). */
body .bh-se-hero {
    padding-top: 84px;
}

/* Off-brand green primary buttons (#46c48f, white text, about 2.3:1) on
   Feedback, Downloads and Experience Guarantee: the brand's yellow primary. */
body .bh-feedback-btn.primary,
body .bh-downloads-help-btn.primary,
body .bh-guarantee-btn.primary {
    background: #E4FF1A;
    color: #21272F;               /* 13.34:1 */
}

/* The black "Inspiring an Outdoor Generation" artwork sat straight on dark
   hero photos (Our Story, Sustainability) and was close to invisible. A light
   backing keeps its colours. */
body .bh-about-mission-logo,
body .susx-main-logo {
    background: rgba(255, 255, 255, 0.92);
    padding: 14px 18px;
    border-radius: 16px;
}

/* Mallow/Coachford hubs on phones: "Get directions" wrapped onto its own line
   with a stray indent; on a phone it is its own line on purpose. */
@media (max-width: 575.98px) {
    .bh-destination__directions {
        display: block;
        margin: 6px 0 0;
    }
}

/* Homepage: the sub-brand logos sat straight on top of the video. */
.logo-links {
    padding-bottom: 32px;
}

/* ---------------------------------------------------------------------------
 * 24. HubSpot enquiry forms: moved to hubspot-form.css
 *
 * HubSpot draws its forms inside iframes, so rules here never reached them.
 * assets/js/hubspot-forms.js links hubspot-form.css into each form's frame.
 * ------------------------------------------------------------------------- */

/* Pricing tables: on /pricing/ each price is "<strong>RRP / </strong>€20" in
   a span, and the spans wrapped mid-price ("Adventure Pass /" on one line,
   "€10" on the next). Each price stays whole; prices wrap between each other.
   /pricing-detailed/ puts a whole row of prices in one span ("Online / Adult /
   €19.50 U10 / €39.00 ..."), and holding that on one line pushed the table out
   of its container and the price column off a phone. So only a span with a
   single label is kept whole; a longer one wraps normally, labels intact. */
.pricing table td > span:not(:has(span, strong ~ strong)) {
    display: inline-block;
    white-space: nowrap;
    margin-right: 14px;
}

.pricing table td > span strong {
    white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * 25. Final review (24 Oct 2026)
 * ------------------------------------------------------------------------- */

/* All Activities tabs: inactive tabs were #BDBDBD on white, about 1.8:1. */
.pricing--alt .nav-tabs li a:not(.active) {
    color: #57606A;               /* 6.2:1 on white */
}

/* Slim banner on phones: the article padding plus .wysywig's 40px top margin
   left ~110px of white between the banner's rip edge and the page's own hero,
   which is meant to sit right under it. */
@media (max-width: 767.98px) {
    .banner--slim + .page-content article.py-5 {
        padding-top: 0.5rem !important;
    }

    .banner--slim + .page-content .entry-content .wysywig:first-child,
    .banner--slim + .page-content .entry-content > :first-child .wysywig {
        margin-top: 0;
    }

    /* Groups: the brochure stamp hangs below its column on an absolute
       offset and its arrow sat on the next section's heading. In the flow
       on a phone. */
    .sellpoint .download-brochure {
        position: relative;
        bottom: auto;
        left: auto;
        margin: 16px auto 0;
    }
}

/* ---------------------------------------------------------------------------
 * 26. Last review pass (24 Oct 2026): contrast, and the policy pages' column
 * ------------------------------------------------------------------------- */

/* Privacy, Cookies, Accessibility, Help Desk, Fast Facts, the B Corp story and
   Sustainability in Action sit in a centred col-xxl-10 offset-xxl-1 column.
   With the reading measure on the text (section 16), the 46rem lines hung off
   that column's left edge: they started 110px in from the page title and
   stopped two-thirds of the way across. The column starts at the title, as on
   every other prose page. */
.bh-prose .entry-content .row > [class*="offset-"] {
    margin-left: 0;
}

/* White on the designed pages' #23b4d4 blue is 2.46:1: Sauna and Swim at both
   venues, Adventure Pass, Gift Vouchers and Memberships. Navy is 6.1:1 on it
   and 5.0:1 on its #17a3c1 hover. The legacy rules use !important and load
   after this file, so these do too, with more weight. */
body [class*="bh-sauna"] .bh-btn-primary,
body .bh-toggle-btn.active,
body .bh-membership-maths-tab.active,
body .bh-membership-link,
body .bh-membership-link:hover,
body .bh-membership-link:focus,
body .bh-price-card-highlight .bh-price-link,
body .bh-ap-btn-primary,
body .bh-gv-btn-primary,
body .bh-membership-btn-primary,
body .bh-membership-btn-wake {
    color: #21272F !important;
}

/* Residential Summer Camp: white on a #1fb8d9 to #129dbb gradient, 2.4:1 at
   its light end. Navy holds 4.7:1 even at the darker end. */
body .bh-residential-btn,
body .bh-residential-booking__btn {
    color: #21272F;
}

/* Two more off-brand primaries, treated like the green ones in section 23:
   the Impact Report's green "continue" button (white on #46c48f, 2.2:1) and
   One Day Warriors' orange "Book" buttons (white on an inline #ff6a00
   gradient, 2.9:1, the only orange on the site). The brand's yellow primary. */
body .bh-impact-continue-btn,
body .bh-impact-continue-btn:hover {
    background: #E4FF1A;
    color: #21272F;               /* 13.34:1 */
}

body .entry-content a[style*="#ff6a00"] {
    background: #E4FF1A !important;
    color: #21272F !important;
    box-shadow: none !important;
}

/* Groups enquiry form: bootstrap-select draws its placeholder in #999 on
   #f8f9fa, 2.7:1. */
.bootstrap-select .btn.bs-placeholder,
.bootstrap-select .btn.bs-placeholder .filter-option-inner-inner {
    color: #57606A;               /* 6.1:1 */
}

/* Activity summary: an activity at both venues printed two "Location" rows.
   One "Locations" row now lists them, one per line, right-aligned like every
   other value in the summary. */
.summary__places {
    text-align: right;
}

.summary__places > span {
    display: block;
}

/* Cookie Policy: CookieYes injects a "Consent Preferences" link in #858a8f on
   #f8f9fa, 3.3:1. */
.entry-content .cky-banner-element {
    color: #57606A !important;    /* 6.1:1 */
}

/* Feedback: the Google Form is 3,214px tall beside a tips card that ends after
   about 200px, which left a long empty column. The card travels with the form
   while it is in view, from the 980px breakpoint where the two sit side by
   side. */
@media (min-width: 980px) {
    /* Sticky needs a scrolling ancestor that actually scrolls. main.min.css
       gives every .wysywig .col-12 overflow-x: auto, which makes a scroll
       container that never scrolls (the body's own overflow is section 28). */
    .wysywig .col-12:has(.bh-feedback-page) {
        overflow-x: visible;
    }

    /* At 492px the form's rating grid cut "Excellent" to "Excell". The form
       takes more of the row; the tips card needs little. */
    body .bh-feedback-grid {
        grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
    }

    body .bh-feedback-grid > .bh-feedback-card {
        position: sticky;
        top: 120px;
    }
}

/* ---------------------------------------------------------------------------
 * 27. Full-site screenshot review (24 Oct 2026, evening)
 * ------------------------------------------------------------------------- */

/* Activity cards: each image was drawn at its height attribute (306px for the
   legacy 1024x306 panoramas, 575px for the newer 1024x575 photos) inside a
   395px column, so every photo was squeezed sideways and two cards stood
   270px taller than the rest, which left a 340px blank band under the
   homepage carousel. One shape for every card; photos crop instead. */
.card.product .card-img-top {
    width: 100%;
    height: auto;
    aspect-ratio: 395 / 306;
    object-fit: cover;
}

/* Cards with no Adventure Pass price have one line of price text, not two,
   and sat 20px shorter than their neighbours. */
.card.product .product__text {
    min-height: 2lh;
}

/* Homepage reviews: the carousel is as tall as its longest quote. Long
   quotes (front-page.php adds the class) are set smaller so the slides
   are close in height and the short ones do not float in white space. */
.reviews .review-card .review-quote--long {
    font-size: 30px;
}

@media (max-width: 767.98px) {
    .reviews .review-card .review-quote--long {
        font-size: 20px;
        line-height: 1.25;
    }
}

/* Footer, desktop: "Ballyhass Coachford" and "Ballyhass Wake Park" wrap to
   two lines, so their links started 33px below their neighbours'. Every
   heading in that row takes two lines, set from the top. */
@media (min-width: 1200px) {
    .footer__display + .footer__col .footer__list button {
        display: flex;
        align-items: flex-start;
        min-height: 68px;              /* two 18px lines as drawn, plus padding */
    }
}

@media (min-width: 1300px) {
    .footer__display + .footer__col .footer__list button {
        min-height: 80px;              /* two 22px lines as drawn, plus padding */
    }
}

/* Footer, phone and tablet: the B Corp badge floated into the logo row and
   the social row's faint rule showed only as two stray dots either side of
   the icons. The badge sits centred under the first menu group, and the
   icons are centred without the rule. */
@media (max-width: 1199.98px) {
    .footer__col .footer__list img {
        float: none;
        display: block;
        width: auto;
        height: 72px;
        margin: 24px auto 0;
    }

    .footer__social:before {
        display: none;
    }

    .footer__social ul li {
        padding: 0;
    }

    /* The logo sat low and #thisisballyhass high: one centred row. */
    .footer__display {
        align-items: center;
    }

    /* The accordion's "+" was white on Ballyhass Blue, 2.4:1. Dark, 8.7:1. */
    .footer__list button:after {
        filter: brightness(0);
    }
}

/* An image with width and height attributes shrinks to its column through
   max-width but kept the attribute's height: Things To Do In Cork's photos
   were drawn at 370x360 from 640x360 sources on a phone. :where() keeps this
   at zero specificity, so any designed block that sets a height still wins. */
:where(.entry-content, .wysywig) :where(img[height]) {
    height: auto;
}

/* ---------------------------------------------------------------------------
 * 28. Full-site screenshot review: spacing, gutters and the activity sidebar
 *
 * Ten reviewers walked all 121 pages at 1440 and 390. Most of what they
 * found traces to a handful of stacked spacings and one overflow rule.
 * ------------------------------------------------------------------------- */

/* Above the footer: main.min.css gives every section margin-bottom 100px,
   so a designed section inside section.wysywig ended with 200px of margin,
   then the article's 48px padding and the footer's 50px margin: 250 to 570px
   of white on most designed pages. The last block ends the page. */
.entry-content :is(section, .wysywig):last-child {
    margin-bottom: 0;
}

.page-content article.py-5 {
    padding-bottom: 0 !important;
}

/* Under the banner: .wysywig's 40px top margin and the first heading's own
   margin stacked on the banner's 70px margin and the article's padding,
   130 to 210px on phones. One page body holds one .wysywig. */
.entry-content .wysywig {
    margin-top: 0;
}

.entry-content > :first-child,
.entry-content .wysywig > :first-child,
.entry-content > :first-child > .wysywig > :first-child {
    margin-top: 0;
}

@media (max-width: 767.98px) {
    body:not(.home) .banner:not(.banner--slim) {
        margin-bottom: 40px;
    }
}

/* Phone gutter: Bootstrap's 10px put body text almost on the screen edge.
   16px everywhere; the footer's legal row lines up with the menu labels. */
@media (max-width: 575.98px) {
    .container,
    .container-fluid {
        padding-left: 16px;
        padding-right: 16px;
    }
}

@media (max-width: 1199.98px) {
    .footer__legal {
        padding-left: 17px;
        padding-right: 17px;
    }
}

/* Activity cards: the Adventure Pass price ran straight on from the main
   price ("From €18.00pp€14.00pp with Adventure Pass"). Its own line. */
.card.product .product__text > span {
    display: block;
    margin: 2px 0 0;
    float: none;
}

/* Sticky panels need a scrolling ancestor that scrolls. overflow-x: hidden
   on the body made it a scroll container that never scrolls, so no sticky
   element on the site ever stuck. clip cuts off the same overflow without
   that side effect. */
body,
body.mm-wrapper {
    overflow-x: clip;
}

/* Activity pages: the Summary box scrolled away after 600px and left a
   400px empty column beside 5,000px of content. It now travels with the
   page. The designed sticky panels in page bodies were set 18 to 30px from
   the top, under the 100px fixed header; they clear it. Below 992px those
   panels stack in the flow, and an offset there only pushed them down. */
@media (min-width: 992px) {
    .single-activity .main__side:not(.main__side--left) {
        position: sticky;
        top: 120px;
    }

    .bh-chaos-birthday__result,
    .bh-bp-result,
    .bh-camp-survival__result,
    .bh-axe-v2-side-note,
    .bh-padel__faq-intro {
        top: 120px !important;
    }
}

/* Accordions on prose pages: the reading measure capped each header's
   heading at 46rem, so its +/- toggle sat mid-line while the rule under it
   ran the full width. */
.bh-prose .entry-content .accordion :is(h2, h3, h4) {
    max-width: none;
}

/* Prose pages: the 46rem reading column hung on the left with the right
   45% of the desktop page empty, which reviewers read as unfinished. The
   column is centred; tables keep the full width. */
@media (min-width: 992px) {
    .bh-prose .entry-content :is(p, ul, ol, h2, h3, h4, blockquote, dl, .accordion, figure) {
        margin-left: auto;
        margin-right: auto;
    }

    /* main.min.css pins ".wysywig h2" to margin-left: 0 !important, which left
       Privacy Policy's headings 290px left of their centred paragraphs. */
    .bh-prose .entry-content .wysywig h2 {
        margin-left: auto !important;
        margin-right: auto !important;
    }

    .bh-prose .entry-content .accordion {
        max-width: 46rem;
    }

    .bh-prose .entry-content ul,
    .bh-prose .entry-content ol {
        padding-left: 1.25rem;
    }
}

/* ---------------------------------------------------------------------------
 * 29. Page furniture that showed too early
 * ------------------------------------------------------------------------- */

/* The calculators' fixed phone CTA bars sat over the hero on first load,
   covering its headline or stacking on its own identical button. They wait
   until the visitor is past most of the first screen (scroll-state.js). */
html:not(.bh-scrolled) :is(.bh-chaos-birthday__sticky, .bh-bp-sticky, .bh-camp-survival__sticky) {
    transform: translateY(160%);
    pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
    :is(.bh-chaos-birthday__sticky, .bh-bp-sticky, .bh-camp-survival__sticky) {
        transition: transform 0.25s ease;
    }
}

/* "If the form does not load, you can still contact Ballyhass through the
   main website" sat under every working form. It shows only when no form
   has appeared after ten seconds (hubspot-forms.js). */
:is(.bh-chaos-birthday__fallback, .bh-bp-fallback) {
    display: none;
}

html.bh-hs-missing :is(.bh-chaos-birthday__fallback, .bh-bp-fallback) {
    display: block;
}

/* ---------------------------------------------------------------------------
 * 30. Hub listings and link rows (artifacts/migration/rebuild-hub-lists.php)
 *
 * The hub pages listed products as one run-on line each, mostly unlinked:
 * "Mallow Cadets Mallow, from €150". Each is now a row: the name linked to
 * its page, the venue as a tag, the price set right, any note underneath.
 * ------------------------------------------------------------------------- */

body .entry-content ul.bh-listing {
    max-width: 46rem;
    margin: 1.25rem auto 2rem;
    padding: 0;
    list-style: none;
    border-top: 1px solid rgba(33, 39, 47, 0.16);
}

body .entry-content .bh-listing li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 12px;
    margin: 0;
    padding: 14px 0;
    border-bottom: 1px solid rgba(33, 39, 47, 0.16);
}

.bh-listing__name {
    flex: 1 1 14rem;
    min-width: 0;
    color: #21272F;
    font-weight: 600;
    text-decoration: none;
}

.bh-listing__name:hover,
.bh-listing__name:focus-visible {
    color: #0B7A8E;
    text-decoration: underline;
}

.bh-listing .venue {
    padding: 2px 9px;
    border-radius: 999px;
    background: #E6F6F9;
    color: #0B5D6B;               /* 6.8:1 on the tint */
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.bh-listing__price {
    margin-left: auto;
    color: #21272F;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.bh-listing__note {
    flex-basis: 100%;
    color: #57606A;
    font-size: 0.9375rem;
}

/* "Find a camp · Camp FAQs" lines wrapped and left a dot at each line end.
   They are a row of the brand's buttons: all caps, bold, rounded square. */
.bh-link-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.bh-link-row a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 8px 18px;
    border: 2px solid #21272F;
    border-radius: 6px;
    color: #21272F;
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-decoration: none;
    text-transform: uppercase;
}

.bh-link-row a:first-child {
    border-color: #E4FF1A;
    background: #E4FF1A;
}

.bh-link-row a:hover,
.bh-link-row a:focus-visible {
    border-color: #21272F;
    background: #21272F;
    color: #FFFFFF;
}

/* Phones: the name takes its own line, and the venue tag and the price
   share the next, rather than the price wrapping alone under the tag. */
@media (max-width: 575.98px) {
    .bh-listing__name {
        flex-basis: 100%;
    }
}

/* Homepage video: the placeholder is a real button again (front-page.php),
   so it can be started from the keyboard. Buttons shrink to their content;
   it fills its frame as the div did. */
.video-container button.video-placeholder {
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * 31. "Two amazing locations" (homepage, activity pages, schools template)
 *
 * White "Ballyhass Mallow" and "Ballyhass Coachford" sat on a 42% navy fade
 * over bright photos, 1.1 to 1.7:1 at the lightest point. The fade is
 * darker and starts higher: 4.0:1 or better at 1440px (large text needs
 * 3:1) and 7.1:1 or better on a phone, where the caption covers most of the
 * photo. On a phone "Coachford" at 60px was wider than its card and lost
 * its last letter; the names scale with the screen there.
 * ------------------------------------------------------------------------- */

.locations__image::before {
    background: linear-gradient(180deg, rgba(9, 32, 60, 0) 15%, rgba(8, 33, 62, 0.72) 55%);
}

@media (max-width: 575.98px) {
    .locations__image::before {
        background: linear-gradient(180deg, rgba(9, 32, 60, 0.30) 0%, rgba(8, 33, 62, 0.80) 40%);
    }

    .locations__content h3 {
        font-size: min(60px, 12vw);
        line-height: 1;
    }
}

/* 32. Activity Summary: a venue with nothing to book.
   The Summary now takes its state from the booking system, so an activity
   that is out of season says so where the Book button would be, instead of
   printing a "From" price for something that cannot be bought. */
.single-activity .summary__state {
    margin: 0 0 12px;
    padding: 14px 18px;
    border: 2px solid var(--bh-navy);
    border-radius: 6px;
    color: var(--bh-navy);
    font-weight: 700;
    text-transform: uppercase;
}

.single-activity .summary__state span {
    display: block;
    margin-top: 4px;
    font-weight: 500;
    text-transform: none;
}

/* 33. Mobile menu: the Adventure Pass line at the top of the menu replaced
   an image that claimed "Up to 30% off" (Teamwork 11929468). Text, so it
   can be read and changed; navy on the menu's yellow. */
.mm-menu .mm-navbar .mmlogo.mmlogo--pass {
    filter: none;
    padding: 12px 64px 12px 20px;
    text-align: left;
}

.mm-menu .mm-navbar .mmlogo--pass a {
    color: var(--bh-navy);
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.35;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.mm-menu .mm-navbar .mmlogo--pass strong {
    font-weight: 700;
}

/* 34. Mega menu: a five-column panel (Experiences, after Eoghan's review
   11929469) does not fit the compiled 980px panel, whose columns are fixed at
   a quarter and whose links never wrap. Wide panels get more width, one row of
   equal columns, tighter gutters, and links that may wrap at narrower desktop
   widths. Panels open from the start of the nav, so the width leaves room for
   that offset at 1200px. */
@media (min-width: 1200px) {
    .c-navbar .dropdown-menu.dropdown-menu--wide {
        width: min(1180px, calc(100vw - 220px));
        max-width: none;
    }

    .c-navbar .dropdown-menu--wide .col-12 > .row {
        flex-wrap: nowrap;
    }

    .c-navbar .dropdown-menu--wide .col-12 > .row > .col {
        flex: 1 1 0;
        max-width: none;
        min-width: 0;
        padding-left: 8px;
        padding-right: 8px;
    }

    .c-navbar .dropdown-menu--wide .content {
        padding-left: 12px;
        padding-right: 12px;
    }

    .c-navbar .dropdown-menu--wide .dropdown-item {
        white-space: normal;
    }
}

/* 35. Plan Your Visit opens from the utility pill at the right of the header,
   so its panel is anchored to the right; anchored left like the main panels,
   it ran 420px off the screen. */
@media (min-width: 1200px) {
    .c-navbar .nav-ecomm .dropdown-menu {
        left: auto;
        right: 0;
    }
}

/* 36. Activity pages with the booking strip (single-activity.php, .main--strip).
   The Summary column is gone, so the body no longer keeps the 350px the
   compiled sheet reserves beside it. Designed bodies take the container;
   plain text bodies keep a reading measure, centred. */
.single-activity .main--strip {
    padding-top: var(--bh-space-12);
}

.single-activity .main--strip .main__body {
    margin: 0;
    padding: 0;
}

.single-activity .main--strip:not(.main--wide) .main__body {
    max-width: 52rem;
    margin-inline: auto;
}

@media (max-width: 991.98px) {
    .single-activity .main--strip {
        padding-top: var(--bh-space-8);
    }
}

/* The designed bodies line up with the strip's edges. Four carried a legacy
   wrapper that inset them 40 to 112px from it at 1440px: a 1240px centred
   shell with side padding (Open Water Swimming, Paddle Boarding, Zipline) or
   the old ten-of-twelve grid column (Team Challenge). */
.single-activity .main--strip .main__body :is(.bh-ows-shell, .bh-kayak-sup-page, .bh-zip-shell) {
    max-width: none;
    margin-right: 0;
    margin-left: 0;
    padding-right: 0;
    padding-left: 0;
}

.single-activity .main--strip .main__body .bh-ows-page {
    padding-right: 0;
    padding-left: 0;
}

.single-activity .main--strip .main__body .row > .col-xxl-10.offset-xxl-1 {
    flex: 0 0 100%;
    max-width: 100%;
    margin-left: 0;
}

/* 39. Downloads: the contact line shown when no download has a file behind it (inc/downloads.php).
   It used to sit flush under the hero, at the width of the card column it replaced. */
.bh-downloads-unavailable {
    max-width: 46rem;
    margin: 0;
    padding: var(--bh-space-8) 0 var(--bh-space-4);
    font-size: var(--bh-text-md);
    font-weight: var(--bh-weight-semibold);
    line-height: var(--bh-leading-body);
}

/* 37. Past-event notice (artifacts/migration/fix-stale-and-pass-claims-1029.php).
   Eoghan, 29 October 2026 (comment 11929468 section 6): the site must not keep
   advertising an expired season. A page for an event or a season that has
   passed says so in a navy block with yellow text and square corners (brand
   guide, highlighted text). Navy on yellow is 14:1. */
.bh-past-notice {
    max-width: 1100px;
    margin: var(--bh-space-6) auto;
    padding: var(--bh-space-4) var(--bh-space-6);
    border-radius: 0;
    background: var(--bh-navy);
    color: var(--bh-yellow);
}

.bh-past-notice p {
    margin: 0;
    color: inherit;
    font-weight: 500;
}

.bh-past-notice a {
    color: inherit;
    text-decoration: underline;
}

/* The same sentence inside a camp or course date panel, where a list of weeks was. */
.bh-troopers-main-hero__dates > p,
.bh-explorers-main-hero__dates > p,
.bh-cadets-v1__dates > p,
.bh-cutting-edge-v1__dates > p,
.bh-residential-booking__dates-list > p {
    grid-column: 1 / -1;
}

/* 38. A photograph in an activity page's body (the Archery page, artifacts/migration/apply-archery-photo.php).
   It keeps its own size rather than stretching across the page: the only archery
   photograph in the media library is 400px wide. */
.single-activity .main__body figure.bh-activity-photo {
    max-width: 400px;
    margin: 0 0 var(--bh-space-6);
}

.single-activity .main__body figure.bh-activity-photo img {
    display: block;
    max-width: 100%;
    height: auto;
}

/* 40. A library answer in a page's own FAQ design (inc/faq-library.php, apply-faq-pages-1030.php).
   Three pages now draw an existing library answer into a design written for one short
   paragraph. On /groups/ each paragraph carried the panel's own padding (16px above, 24px
   below), so the approved three-paragraph answers had 56px between paragraphs. On the
   Aquapark page the paragraphs ran together with no space. On First Time at Ballyhass the
   "What should I wear?" list printed in the body colour at 16px beside 15px grey answers. */
.faq-accordion .accordion-content p + p {
    padding-top: 0;
}

.faq-accordion .accordion-content p:not(:last-child) {
    padding-bottom: 0;
}

.bh-aqua-faq-block .bh-faq-item p + p {
    margin-top: 8px;
}

.bh-ft-faq-item ul {
    margin: 0;
    padding-left: 1.25em;
    color: #5f7488;
    font-size: 15px;
    line-height: 1.75;
}

/* 41. The ASD camp design at Coachford (/asd-active-adventurers2/, artifacts/migration/apply-route-map-1030.php).
   The design's hero photograph is set in its recovered stylesheet (assets/css/legacy/bf37ee5bc4.css)
   and shows the lake at Mallow. Rebuilt in that design on 30 October 2026, the Coachford page shows
   Coachford's lake instead. Same overlay as the design, desktop and phone. */
.bh-asd-camp-v1--coachford .bh-asd-camp-v1__hero:before {
    background:
        linear-gradient(90deg, rgba(13, 19, 26, .96) 0%, rgba(13, 19, 26, .78) 52%, rgba(13, 19, 26, .40) 100%),
        url("/wp-content/uploads/2026/10/Coachford_Aquapark_Cool_Vivid-1.jpg") center right / cover no-repeat;
}

@media (max-width: 640px) {
    .bh-asd-camp-v1--coachford .bh-asd-camp-v1__hero:before {
        background:
            linear-gradient(180deg, rgba(13, 19, 26, .86) 0%, rgba(13, 19, 26, .82) 62%, rgba(13, 19, 26, .94) 100%),
            url("/wp-content/uploads/2026/10/Coachford_Aquapark_Cool_Vivid-1.jpg") center / cover no-repeat;
    }
}

/* 42. A second paragraph in an Our Story timeline card (artifacts/migration/apply-route-map-1030.php).
   The scholarship's history is one sentence under the Outdoor Training Academy entry since
   30 October 2026 (Teamwork 11931146). The design's card paragraphs have no margin, as each card
   held one, so the two ran together with no space between them. */
.bh-history-card p + p {
    margin-top: 10px;
}

/* 43. The Cart link (ballyhass_cart_link; Eoghan, 3 October 2026, comment 11924622, and
   30 October, comment 11931168): the icon, the word, the item count and the total, filled in
   after load by assets/js/cart-summary.js. Below the desktop breakpoint (1199px) the utilities
   fold into the menu, so Cart also sits in the bar beside the menu button, the word hidden to
   save room (the link keeps it as its name). Colours follow section 8: white over the scrim,
   navy on the blue bar, navy on yellow on hover. */
.c-cart {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

.c-cart__icon {
    flex: none;
}

.c-cart__count {
    font-weight: 700;
}

.c-cart--bar {
    display: none;
}

@media (max-width: 1198.98px) {
    .c-navbar .c-cart--bar {
        display: inline-flex;
        min-height: 44px;
        margin-left: auto;
        margin-right: 8px;
        padding: 8px 12px;
        border-radius: 8px;
        color: #FFFFFF;
        font-size: 14px;
        font-weight: 600;
        text-decoration: none;
    }

    .c-navbar .c-cart--bar + .hamburger {
        margin-left: 0;
    }

    .c-navbar.active .c-cart--bar,
    .c-navbar.menu-open .c-cart--bar {
        color: #21272F;
    }

    .c-navbar .c-cart--bar:hover,
    .c-navbar .c-cart--bar:focus-visible {
        color: #21272F;
        background-color: #E4FF1A;
        text-decoration: none;
    }

    .c-navbar .c-cart--bar .c-cart__word {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }
}

/* 44. WebP copies of two decorative images that main.min.css draws on most pages: the torn edge
   under every inner page's banner (60 KB as PNG, 34 KB as WebP) and the highlight behind the
   "locations" heading. The copy sits next to the PNG (bin/make-theme-webp.py). The plain url()
   comes first, so a browser that cannot read image-set() with type() keeps the PNG.
   FSD REQ-NF001, 31 October 2026; inc/images.php does the same for <img> tags. */
body:not(.home) .banner figure:after {
    background-image: url(../images/ballyhass/white-rip-4.png);
    background-image: image-set(url(../images/ballyhass/white-rip-4.png.webp) type("image/webp"), url(../images/ballyhass/white-rip-4.png) type("image/png"));
}

.rip-title h2:before {
    background-image: url(../images/ballyhass/highlight-sm.png);
    background-image: image-set(url(../images/ballyhass/highlight-sm.png.webp) type("image/webp"), url(../images/ballyhass/highlight-sm.png) type("image/png"));
}

/* 45. axe-core 4.14 over every published page, WCAG 2.2 A and AA (31 October 2026).
   Sitewide corrections; page-level ones are at the end of review-fixes.css. */

/* The locations' "Find us" sat on 40% black, which is only as dark as the photo under it. axe
   measured it on the white behind the photo at 2.84:1, and over the photo's light patches it
   is not much more. Navy at 80% holds white text at 8:1 or better on any photo. The hover
   state (white, !important in main.min.css) is unchanged. */
.locations__content .button--bordered-white {
    background-color: rgba(33, 39, 47, 0.8);
}

/* News article meta ("By: Ballyhass Team | Posted on") was CSS gray, 3.94:1 at 12px. */
.dccom_gdNews .inner:not(.articlesList) .news-item .meta {
    color: var(--bh-muted);
}

/* A link in running text is underlined, so it is told apart by more than its colour (WCAG
   1.4.1, axe link-in-text-block). Bus and Train Info's "Camp Finder" links were teal in
   grey and plum text, 1.27:1 and 1.52:1 against it, with nothing else to mark them. Links
   with a class are buttons, cards or pills and keep their own look. */
.entry-content p a:not([class]),
.wysywig p a:not([class]) {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Wakeboarding's East and West Park switch is two hidden radio buttons and their labels
   (inc/content-a11y.php). The keyboard reaches the radio, so its label shows the focus. */
#bh-wake-park-east:focus-visible ~ .bh-wake-parks__switcher .bh-wake-parks__switch--east,
#bh-wake-park-west:focus-visible ~ .bh-wake-parks__switcher .bh-wake-parks__switch--west {
    outline: var(--bh-focus-width) solid var(--bh-focus-color);
    outline-offset: var(--bh-focus-offset);
    box-shadow: var(--bh-focus-shadow);
}

/* A sideways-scrolling strip the keyboard can now reach (inc/content-a11y.php) draws the ring
   inside its edge, where its own overflow cannot clip it: white 2px, navy 3px, white 2px, inwards. */
[data-bh-scroll-region]:focus-visible:not(#bh-focus-none) {
    outline-offset: calc(-1 * (var(--bh-focus-offset) + var(--bh-focus-width))) !important;
    box-shadow: inset 0 0 0 calc(var(--bh-focus-offset) + var(--bh-focus-width) + 2px) var(--bh-focus-halo) !important;
}

/* 46. The desktop header on one line, with the whole logo (3 November 2026).
   Measured on dev before this: from 1200px to about 1360px the logo was squeezed, to nothing
   at 1200 to 1280px, because the bar's items do not shrink and the logo does; and at 1280,
   1366 and 1440px "Sign a Waiver", "My Account" and "Book Now" each broke onto two lines. The
   utility routes had grown (Plan Your Visit, Sign a Waiver, the account link, the Cart with its
   count and total), and My Account (comment 11931699, point 8) is longer than Login was.
   Now the logo keeps its width, no label wraps, and the room comes from spacing, in steps:
   1199 to 1439px (the desktop bar starts at 1199px, .navbar-expand-mtd) the container's side padding (60px to 16px) and the links' padding; below
   1366px also the pill's padding; below 1280px also one pixel off the type; 1440 to 1799px only
   the links' spacing. Measured on dev at 1199, 1200, 1240, 1280, 1300, 1366, 1400, 1440, 1536, 1680,
   1800 and 2560px, on an ordinary page, the Camps hub and the compact header of Book Now and
   Waivers: the logo is its full 83px, nothing wraps and Book Now stays inside the window. */
.theme-25 .c-navbar .navbar-brand {
    flex-shrink: 0;
}

.theme-25 .c-navbar .navbar-nav.mr-auto > .nav-item > .nav-link,
.theme-25 .c-navbar .nav-ecomm .nav-link,
.theme-25 .c-navbar .btn-booking {
    white-space: nowrap;
}

@media (min-width: 1199px) and (max-width: 1439.98px) {
    .theme-25 .c-navbar > .container {
        padding-right: 16px;
        padding-left: 16px;
    }

    .theme-25 .c-navbar .navbar-brand {
        margin-right: 12px;
    }

    .theme-25 .c-navbar .navbar-nav.mr-auto > .nav-item {
        margin-right: 2px;
        margin-left: 2px;
    }

    .theme-25 .c-navbar .navbar-nav.mr-auto > .nav-item > .nav-link {
        padding-right: 4px;
        padding-left: 4px;
    }

    .theme-25 .c-navbar .nav-ecomm {
        margin-right: 10px;
    }

    .theme-25 .c-navbar .btn-booking {
        padding-right: 16px;
        padding-left: 16px;
    }
}

@media (min-width: 1199px) and (max-width: 1365.98px) {
    .theme-25 .c-navbar .nav-ecomm {
        padding-right: 6px;
        padding-left: 6px;
    }

    .theme-25 .c-navbar .nav-ecomm .nav-link {
        padding-right: 4px;
        padding-left: 4px;
    }

    .theme-25 .c-navbar .btn-booking {
        padding-right: 12px;
        padding-left: 12px;
    }
}

@media (min-width: 1199px) and (max-width: 1279.98px) {
    .theme-25 .c-navbar .navbar-brand {
        margin-right: 8px;
    }

    .theme-25 .c-navbar .navbar-nav.mr-auto > .nav-item > .nav-link {
        font-size: 14px;
    }

    .theme-25 .c-navbar .nav-ecomm .nav-link {
        font-size: 12px;
    }

    .theme-25 .c-navbar .btn-booking {
        font-size: 15px;
    }
}

@media (min-width: 1440px) and (max-width: 1799.98px) {
    .theme-25 .c-navbar .navbar-nav.mr-auto > .nav-item {
        margin-right: 2px;
        margin-left: 2px;
    }

    .theme-25 .c-navbar .navbar-nav.mr-auto > .nav-item > .nav-link {
        padding-right: 6px;
        padding-left: 6px;
    }

    .theme-25 .c-navbar .btn-booking {
        padding-right: 16px;
        padding-left: 16px;
    }
}

/* 47. The icons in the utility pill vanished once the header turned white on scroll (3 November
   2026). main.min.css paints the main bar's dropdown arrows navy for the white header
   (.theme-25 .c-navbar.active .nav-link svg path), and the same rule reached the icons inside the
   navy pill, so Plan Your Visit's arrow and the Cart's basket were navy on navy and only the
   cart's two wheels showed. Inside the pill they take the link's own colour, white. */
.theme-25 .c-navbar.active .nav-ecomm .nav-link svg path,
.theme-25 .c-navbar.menu-open .nav-ecomm .nav-link svg path {
    stroke: currentColor;
}

/* 48. Nothing shows through or over the fixed header, and nothing it covers holds focus
   (3 November 2026).

   Over it: Mmenu moves the header into its page wrapper (.mm-page, position: relative,
   z-index: 1) and leaves the footer outside, so the header's z-index of 1030 counts only inside
   that wrapper. The footer's call-to-action band (.bh-foot__cta-inner, z-index: 1) came later at
   the same level and painted over the header: "I know what I want: Quick Book" over the logo.
   The footer now makes its own stacking context below the wrapper. Its own layers are kept.

   Through it: the header turns solid (.c-navbar.active) only on a scroll event
   (app.min.js initHeader), so a page that opened already scrolled, at an anchor
   (/mallow/#plan-your-visit) or back in the history, kept the see-through top-of-page header
   over its text. assets/js/scroll-state.js now sets it on load as well.

   Under it: WCAG 2.2 2.4.11 (Focus Not Obscured). A link reached by the keyboard just under the
   header stayed 40px down, hidden behind it, because the browser saw it as on screen. Every
   control and every anchor target now keeps clear of the header (technique C43, as
   scroll-margin): the header's height plus a gap, and on an activity page wide enough for the
   booking strip to stick, the strip too. Bottom bars (the phone booking bar, the designed
   pages' sticky phone buttons) are kept clear the same way. :where() gives the rule no weight,
   so a component that sets its own scroll-margin-top keeps it. The values here are the
   header's (70px, 100px from 1199px); scroll-state.js replaces them with what it measures.

   Room for a bottom bar: the phone booking bar on activity pages (and the designed pages'
   sticky phone buttons) covered the foot of the page, the footer's legal links included, with
   nothing to scroll them clear. While a bar shows, scroll-state.js sets html.bh-bottom-bar and
   --bh-bottom-bar-height from the bar's own size (75px to 102px, by its label), and the footer
   ends with that much more of its own ground. */
.bh-foot {
    position: relative;
    z-index: 0;
}

html.bh-bottom-bar .bh-foot::after {
    display: block;
    height: var(--bh-bottom-bar-height, 0px);
    content: "";
}

:root {
    --bh-header-height: 70px;
    --bh-scroll-clear-top: calc(var(--bh-header-height) + var(--bh-space-4));
    --bh-scroll-clear-bottom: var(--bh-space-4);
}

@media (min-width: 1199px) {
    :root {
        --bh-header-height: 100px;
    }
}

:where(a[href], area[href], button, input, select, textarea, summary, iframe, [tabindex], [contenteditable], [id]) {
    scroll-margin-top: var(--bh-scroll-clear-top);
    scroll-margin-bottom: var(--bh-scroll-clear-bottom);
}

/* The current Padel page's recovered styles (assets/css/legacy/, rebuilt from the old site and
   never edited) set its sections 100px clear, the desktop header's height with no gap, and too
   much for a phone. The measured clearance above replaces it. The careers, training, Ballyhass
   Business and Bunkhouse sections set 80px, 20px short of the desktop header; those rules were
   removed from components.css and bunkhouse-hub.css on the same date. */
html .bh-padel-launch-v8 section[id] {
    scroll-margin-top: var(--bh-scroll-clear-top);
}

/* 49. Dropdown panels fit their labels (5 November 2026, Eoghan 11932725). The compiled single-column
   panel is a fixed 220px (250px with its padding), so "Adventure Retreats & Group Stays" ran 30px
   past the white container and over the photograph, and the links never wrap. A single-column panel
   now takes the width its longest label needs, between 250px and 380px (and never wider than the
   screen), with room on the right; labels may wrap cleanly beyond that. Every dropdown's links get a
   comfortable target and a visible hover (the focus ring is the theme's one central rule). The panels' structure and the navigation itself are unchanged. */
.theme-25 .c-navbar .dropdown-menu--single-col {
    box-sizing: border-box;
    width: max-content;
    min-width: 250px;
    max-width: min(380px, calc(100vw - 48px));
    padding-right: 32px;
    padding-bottom: 12px;
}

.theme-25 .c-navbar .dropdown-menu .dropdown-item,
.theme-25 .c-navbar .dropdown-menu a.nav-link {
    border-radius: 6px;
    overflow-wrap: anywhere;
    text-wrap: balance;
    white-space: normal;
}

.theme-25 .c-navbar .dropdown-menu--single-col .dropdown-item {
    margin-right: -12px;
    margin-left: -12px;
    padding: 7px 12px;
}

.theme-25 .c-navbar .dropdown-menu .dropdown-item:hover,
.theme-25 .c-navbar .dropdown-menu a.nav-link:hover {
    background-color: var(--bh-surface-2);
    color: var(--bh-navy);
    text-decoration: underline;
    text-underline-offset: 3px;
}
