/*
Theme Name: Hello Elementor Child
Theme URI: https://www.twistfizz.co.uk/
Description: Child theme for Hello Elementor. Holds all TwistFizz custom code and styles so parent theme updates cannot wipe them (as happened on 14 July 2026).
Author: Lewis Edward
Template: hello-elementor
Version: 1.50.1
Text Domain: hello-elementor-child
*/

/* Child styles are appended below. Keep parent theme untouched. */

/*
 * TwistFizz child theme styles
 *
 * Migrated from WPCode snippets on 1 September 2026. Each block keeps its original
 * WPCode snippet ID so it can be traced back to wpcode-snippets-export-2026-09-01.json.
 */

/* ==========================================================================
   [8140] Logo carousel — remove white logo backgrounds (blend into section)
   ========================================================================== */
/* Partner logo carousel: blend white logo backgrounds into the section colour.
   Widget: Elementor media carousel 66716cd on the homepage. */
.elementor-element-66716cd .elementor-carousel-image {
    background-color: #f1f3f1; /* match section background */
    background-blend-mode: multiply;
    mix-blend-mode: multiply;
}

/* ==========================================================================
   [8141] Section headings — 36px site-wide
   ========================================================================== */
/* Section headings: 36px site-wide for consistency (was 48-50px).
   Dual-colour heading widgets set size on inner spans (h2 only —
   page-title h1s keep their size). Plain Elementor heading widgets are
   handled by the companion JS snippet "Section headings — 36px (plain
   heading widgets)", because their 48px comes from per-widget rules that
   CSS alone can't safely override without also shrinking small labels.
   The three homepage IDs below are kept as an instant no-flicker fallback. */
.elementor-widget-ucaddon_dual_color_heading h2,
.elementor-widget-ucaddon_dual_color_heading h2 span {
    font-size: 36px !important;
    line-height: 1.25 !important;
}
.elementor-element-642bbd2 h2, .elementor-element-080db4c h2, .elementor-element-d158cf3 h2 {
    font-size: 36px !important;
    line-height: 1.25 !important;
}

/* ==========================================================================
   [8142] Footer — evenly space the three columns
   ========================================================================== */
/* Footer: spread the three columns (brand / Quick Links / Contact)
   evenly across the row instead of bunching left.
   Grid container: c427364 in the footer template. Desktop/tablet only. */
@media (min-width: 768px) {
    .elementor-element-c427364.e-grid {
        grid-template-columns: repeat(3, 1fr) !important;
        justify-content: stretch !important;
    }
}

/* ==========================================================================
   [8143] Header — opaque white on scroll (no glass blur)
   ========================================================================== */
/* Sticky header: solid white background when scrolled,
   replacing the translucent glass/blur effect, with a subtle
   bottom shadow for separation from the page. */
.elementor-location-header.scrolled {
    background-color: #ffffff !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08) !important;
}

/* ==========================================================================
   [8145] CTA banner — "book online" link style (white underline + hover)
   ========================================================================== */
/* "Ready to get playing?" CTA banners: style the "book online" text
   link as white + underlined with a navy hover.
   Banners are per-page copies with different widget IDs, so the companion
   JS snippet "CTA banner - tag booking links on green banners" adds the
   .tf-banner-link class to booking links sitting on the green banner.
   Known widget IDs kept as an instant no-flicker fallback. */
.elementor-element-785e262 a,
.elementor-element-7d0fe17 a,
a.tf-banner-link {
    color: #ffffff !important;
    text-decoration: underline !important;
    text-underline-offset: 5px;
    transition: color .2s ease, text-decoration-color .2s ease;
}
.elementor-element-785e262 a:hover,
.elementor-element-7d0fe17 a:hover,
a.tf-banner-link:hover {
    color: #1f242e !important;
    text-decoration-color: #1f242e;
}

/* ==========================================================================
   [8151] News cards — remove backdrop blur (fixes scroll flicker)
   ========================================================================== */
/* News/loop cards apply backdrop-filter: blur(3px) with a transparent
   background. The blur has no visible effect (nothing scrolls behind the
   cards) but forces Chrome to recompute the backdrop every scroll frame,
   which causes visible flashing/flicker while scrolling the news page.
   Removing it fixes the flicker with zero visual change. */
.e-loop-item .card-body,
.elementor-element-f1ba8d8 {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* ==========================================================================
   [8160] Bexley Tennis Pass section — fix background tiling
   ========================================================================== */
/* Bexley Tennis Pass section on /tennis-in-bexley/.
   The section carries the shared .testimonials-section class, which sets
   background-size: 40px 40px for a dotted pattern on dark backgrounds.
   Now that this section uses a light mint gradient, that 40px tile makes
   the gradient repeat as vertical stripes. Override the sizing for this
   section only, leaving the shared class intact for other sections. */
.elementor-element-5c13bff {
    background-size: cover !important;
    background-repeat: no-repeat !important;
    background-attachment: scroll !important;
}

/* ==========================================================================
   [8189] Venue pages — address strip vertical centring
   ========================================================================== */
/* Bexley venue pages: the address strip pairs a location icon with a
   text widget. The theme gives paragraphs a bottom margin, which pushes
   the address text visually above centre inside the grey box.
   Applies to every venue page via the shared .tf-address class. */
.tf-address p:last-child {
    margin-bottom: 0;
}
.tf-address {
    align-items: center;
}

/* ==========================================================================
   [8234] Bexley venue cards — image cover + footer icon hover
   ========================================================================== */
/* Bexley venue cards: uniform image crop.
   Each card image is wrapped in a link, and Elementor renders that wrapper
   as inline-block, which shrink-wraps it. Force the wrapper full width and
   the image to a fixed height with object-fit so all cards line up. */
.elementor-element-84488e0 .elementor-widget-container,
.elementor-element-84488e0 a {
    display: block !important;
    width: 100% !important;
}
.elementor-element-84488e0 img {
    width: 100% !important;
    height: 240px !important;
    object-fit: cover !important;
    object-position: center center;
    display: block;
}
@media (max-width: 767px) {
    .elementor-element-84488e0 img { height: 200px !important; }
}
.elementor-element-39cb608 .elementor-widget-container,
.elementor-element-39cb608 a {
    display: block !important;
    width: 100% !important;
}
.elementor-element-39cb608 img {
    width: 100% !important;
    height: 240px !important;
    object-fit: cover !important;
    object-position: center center;
    display: block;
}
@media (max-width: 767px) {
    .elementor-element-39cb608 img { height: 200px !important; }
}
.elementor-element-7c49d38 .elementor-widget-container,
.elementor-element-7c49d38 a {
    display: block !important;
    width: 100% !important;
}
.elementor-element-7c49d38 img {
    width: 100% !important;
    height: 240px !important;
    object-fit: cover !important;
    object-position: center center;
    display: block;
}
@media (max-width: 767px) {
    .elementor-element-7c49d38 img { height: 200px !important; }
}
.elementor-element-a6b0dd4 .elementor-widget-container,
.elementor-element-a6b0dd4 a {
    display: block !important;
    width: 100% !important;
}
.elementor-element-a6b0dd4 img {
    width: 100% !important;
    height: 240px !important;
    object-fit: cover !important;
    object-position: center center;
    display: block;
}
@media (max-width: 767px) {
    .elementor-element-a6b0dd4 img { height: 200px !important; }
}
.elementor-element-48a7426 .elementor-widget-container,
.elementor-element-48a7426 a {
    display: block !important;
    width: 100% !important;
}
.elementor-element-48a7426 img {
    width: 100% !important;
    height: 240px !important;
    object-fit: cover !important;
    object-position: center center;
    display: block;
}
@media (max-width: 767px) {
    .elementor-element-48a7426 img { height: 200px !important; }
}
.elementor-element-94a0b5b .elementor-widget-container,
.elementor-element-94a0b5b a {
    display: block !important;
    width: 100% !important;
}
.elementor-element-94a0b5b img {
    width: 100% !important;
    height: 240px !important;
    object-fit: cover !important;
    object-position: center center;
    display: block;
}
@media (max-width: 767px) {
    .elementor-element-94a0b5b img { height: 200px !important; }
}
.elementor-element-0433f81 .elementor-widget-container,
.elementor-element-0433f81 a {
    display: block !important;
    width: 100% !important;
}
.elementor-element-0433f81 img {
    width: 100% !important;
    height: 240px !important;
    object-fit: cover !important;
    object-position: center center;
    display: block;
}
@media (max-width: 767px) {
    .elementor-element-0433f81 img { height: 200px !important; }
}

/* Footer contact icons and links: add a hover state. */
.elementor-location-footer .elementor-widget-icon svg,
.elementor-location-footer .elementor-widget-icon i,
.elementor-location-footer .elementor-icon-list-icon svg,
.elementor-location-footer .elementor-icon-list-icon i,
.elementor-location-footer a {
    transition: opacity .2s ease, transform .2s ease;
}
.elementor-location-footer .elementor-icon-list-item:hover .elementor-icon-list-icon svg,
.elementor-location-footer .elementor-icon-list-item:hover .elementor-icon-list-icon i,
.elementor-location-footer .elementor-widget-icon:hover svg,
.elementor-location-footer .elementor-widget-icon:hover i {
    /* transform: translateY(-1px) removed - it made the contact icons visibly
       jump on hover. Opacity alone is enough of a hover cue for a non-clickable
       icon, and nothing shifts position. */
    opacity: .7;
}

/* All footer icons on one spec. The three contact icons previously came from
   two different icon libraries (Phosphor Light for the pin and phone,
   wppagebuilder for the envelope), which gave the envelope a heavier stroke.
   The envelope is now phl phlight-envelope; this pins size and colour so a
   future icon from another set cannot drift again. */
.elementor-location-footer .elementor-widget-icon i,
.elementor-location-footer .elementor-widget-icon svg {
    font-size: 21px !important;
    width: 21px !important;
    height: 21px !important;
    color: #4CAE4F !important;
    fill: #4CAE4F !important;
    vertical-align: middle !important;
}
.elementor-location-footer a:hover { opacity: .75; }

/* MindBody / Healcode class-list buttons ("View Schedule" etc.) are injected
   by a shortcode and styled by an existing inline block using
   "div.healcode ... !important", so these selectors must match that
   specificity to win. Brings them onto the primary button tier. */
div.healcode .class_list span.class_offered_link,
div.healcode span.class_offered_link,
div.healcode a.hc-button,
div.healcode input.hc-button {
    background-color: #4CAE4F !important;
    border-color: #4CAE4F !important;
    border-radius: 8px !important;
    transition: background-color .3s ease !important;
}
div.healcode .class_list span.class_offered_link a,
div.healcode span.class_offered_link a,
div.healcode a.hc-button,
div.healcode input.hc-button {
    color: #FFFFFF !important;
    /* font-weight deliberately removed: it was 700 here, and this selector
       outranks the button standard further down the file, so VIEW SCHEDULE
       rendered a weight heavier than every other button. Typography for all
       button systems now lives in one place - see the button standard block. */
    text-decoration: none !important;
}
div.healcode .class_list span.class_offered_link:hover,
div.healcode span.class_offered_link:hover,
div.healcode a.hc-button:hover,
div.healcode input.hc-button:hover {
    background-color: #3E9141 !important;
    border-color: #3E9141 !important;
}
div.healcode .class_list span.class_offered_link:hover a,
div.healcode span.class_offered_link:hover a {
    color: #FFFFFF !important;
}

/* ==========================================================================
   [new] Booking pages — MindBody class list layout
   Added 1 Sep 2026, rolled out to all booking pages the same day.

   The :has(> * + *) guard is load-bearing: it only rebalances a container
   that genuinely has a second column. The single-column adults pages
   (shooters-hill-adults, adults-beginners, adults-intermediates) would
   otherwise gain an empty 340px gutter and lose 360px of content width.

   It matches any second child, not :has(> .e-con + .e-con), because on
   /booking-eltham-park-adults-improvers/ the sidebar is a bare Elementor
   widget rather than a container.

   Do NOT rewrite this as :has(> .e-con:not(:has(.book-list))) — :has()
   cannot be nested inside :has(), so that selector is invalid and silently
   applies nowhere.

   Problem it solves: the MindBody widget renders every course in one narrow
   633px column, ~5,260px tall, beside a 487px sidebar holding a 169px box —
   leaving roughly 4,800px of dead space.
   ========================================================================== */

/* Hello Elementor sets `body { overflow: hidden auto }`, which makes <body> a
   scroll container and silently disables position:sticky for every descendant.
   The sticky sidebar below computed as `position: sticky` but never actually
   stuck. `overflow-x: clip` clips horizontally without creating a scroll
   container, so sticky works again. Browsers without `clip` support simply
   ignore this and fall back to the old behaviour. */
body {
    overflow-x: clip !important;
    overflow-y: visible !important;
}

@media (min-width: 1025px) {
    /* Rebalance 633/487 to a usable split so two cards fit per row */
    .e-con.e-grid:has(> .e-con .book-list):has(> * + *) {
        grid-template-columns: minmax(0, 1fr) 340px !important;
        align-items: start !important;
    }

    /* Sidebar follows the list instead of stranding a long empty column */
    .e-con.e-grid:has(> .e-con .book-list):has(> * + *) > *:not(:has(.book-list)) {
        position: sticky !important;
        top: 110px !important;
    }
}

/* Course cards flow into a responsive grid; collapses to one column
   under ~620px, so no separate mobile rule is needed.

   The child selector is "*", not "div", on purpose: MindBody renders this
   wrapper as a <div> of <div>s on some pages and an <ol> of <li>s on others
   (e.g. /book-juniors-10-under/). The list resets below cover the <ol> case. */
div.healcode .class_list > *:not(.hc_footer) {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)) !important;
    gap: 20px !important;
    align-items: stretch !important;
    list-style: none !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* Equal-height cards with the button pinned to the bottom. Card content
   varies from 196px to 745px, so without this the buttons sit ragged. */
div.healcode .class_show {
    margin: 0 !important;
    display: flex !important;
    flex-direction: column !important;
    height: 100% !important;
    /* Lift the cards off the white page background. #f1f3f1 is the existing
       site neutral (used by the FAQ and logo-carousel sections), so this stays
       on-palette and keeps the green headings and buttons readable. */
    background-color: #f1f3f1 !important;
    border-color: #e3e7e3 !important;
}

div.healcode .class_show .class_info {
    flex: 1 1 auto !important;
}

div.healcode .class_show .class_offered_link {
    margin-top: auto !important;
    align-self: flex-start !important;
}

/* ==========================================================================
   [util] .tf-sticky-col — sticky sidebar column
   Add this class to any Elementor container (Advanced > CSS Classes) that
   should stick while its sibling column scrolls. Used on the holiday camps
   page, where the MindBody box is a static block rather than the MindBody
   widget, so the .book-list rules above do not apply.
   Depends on the body overflow fix earlier in this file.
   ========================================================================== */
@media (min-width: 1025px) {
    .tf-sticky-col,
    /* Holiday camps (page 4252) right-hand column. The element-ID class is used
       because Elementor does not output _css_classes on containers in this
       install - the class saves into _elementor_data but never reaches the HTML,
       so .tf-sticky-col alone matches nothing on a container. Verified: the
       served HTML contains elementor-element-7bb9648 but not tf-sticky-col. */
    .elementor-element-7bb9648 {
        position: sticky !important;
        top: 110px !important;
        align-self: start !important;
    }
}

/* ==========================================================================
   [new] MindBody login/register link — match the primary button tier
   Added 1 Sep 2026. This is a Healcode <a>, not an Elementor button, so the
   sitewide button standardisation never reached it. Two faults it fixes:
     - hover background was rgba(76,174,79,.8): the same green at 80% opacity,
       so it lightened on hover instead of darkening
     - nothing set a hover text colour, so reset.css `a:hover {color:#333366}`
       won and the label turned navy
   Also aligns radius and padding with the Elementor primary button.
   ========================================================================== */
a.healcode-link.healcode-login-register-text-link {
    background-color: #4CAE4F !important;
    color: #FFFFFF !important;
    border-radius: 10px !important;
    padding: 12px 24px !important;
    display: inline-block !important;
    transition: background-color .3s ease !important;
}

a.healcode-link.healcode-login-register-text-link:hover,
a.healcode-link.healcode-login-register-text-link:focus,
a.healcode-link.healcode-login-register-text-link:active {
    background-color: #3E9141 !important;
    color: #FFFFFF !important;
}

/* ==========================================================================
   [new] Button typography and sizing — one standard, all three systems
   Added 1 Sep 2026.

   The site had 7 distinct Elementor button variants across 20 buttons on
   5 pages, plus two Healcode systems, drawing on three font families
   (Montserrat, Poppins, Lato — Lato is not a site font at all).

   Standard: Poppins 15px/600, uppercase, 0.5px tracking, 14x28 padding,
   10px radius. Poppins is the body/UI font.

   Colours are deliberately NOT set here — they are handled per tier
   (primary / inverse / text) in Elementor and in the Healcode rules above,
   so this block only governs type and metrics.
   ========================================================================== */
.elementor-button,
a.elementor-button,
a.healcode-link.healcode-login-register-text-link,
div.healcode .class_list span.class_offered_link a,
div.healcode span.class_offered_link a,
div.healcode a.hc-button,
div.healcode input.hc-button,
.gform_wrapper input.gform_button,
.gform_wrapper button.gform_button {
    font-family: "Poppins", sans-serif !important;
    font-size: 15px !important;
    font-weight: 600 !important;
    line-height: 1.4 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.5px !important;
    padding: 14px 28px !important;
    border-radius: 10px !important;
    text-align: center !important;
    /* Button labels must never wrap. The 28px horizontal padding above left
       only 74px of content width in the narrow card slots on the Bexley venue
       cards, which broke "Learn More" onto two lines and made that button
       74px tall against its 53px neighbour. */
    white-space: nowrap !important;
}

/* Elementor's inner span carries its own line-height in some widgets. */
.elementor-button .elementor-button-text {
    line-height: 1.4 !important;
}

/* Keep the icon optically aligned with the uppercase label.
   The margin is needed because js/twistfizz.js adds an arrow at runtime to
   buttons that had no icon, and Elementor only emits its own icon spacing for
   buttons that were authored with one. */
.elementor-button .elementor-button-icon {
    display: inline-flex !important;
    align-items: center !important;
    margin-left: 8px !important;
    margin-right: 0 !important;
}

.elementor-button .elementor-button-content-wrapper {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* Small-size Elementor buttons stay proportionally smaller rather than
   inheriting the full 14x28 box. */
.elementor-button.elementor-size-xs {
    font-size: 13px !important;
    padding: 10px 20px !important;
}

/* Gravity Forms submit is a fourth button system. It was already Poppins 15px
   and green, but weight 500 and 8px 25px padding made it read a size smaller
   than everything else. Colours follow the primary tier. */
.gform_wrapper input.gform_button,
.gform_wrapper button.gform_button {
    background-color: #4CAE4F !important;
    color: #FFFFFF !important;
    border: 1px solid #4CAE4F !important;
    transition: background-color .3s ease !important;
    cursor: pointer !important;
}

.gform_wrapper input.gform_button:hover,
.gform_wrapper button.gform_button:hover,
.gform_wrapper input.gform_button:focus,
.gform_wrapper button.gform_button:focus {
    background-color: #3E9141 !important;
    border-color: #3E9141 !important;
    color: #FFFFFF !important;
}

/* The Elementor search field's submit is deliberately excluded from the
   button standard: it is welded to the input, so it keeps its square left
   edge (radius 0 10px 10px 0) and icon-sized padding. */

/* ==========================================================================
   [new] Page hero — heading measure and height
   Added 1 Sep 2026.

   NOT changed: the overlay. Every hero already has one (Elementor renders
   container overlays as ::before, not a .elementor-background-overlay div,
   which is easy to miss when inspecting). Booking heroes use #000 at 0.4,
   the Bexley venue pages use #2E6B31 at 0.78 - both intentional, so this
   block deliberately leaves overlay colour alone.

   What was actually wrong: the h1 ran the full 1140px container with
   line-height 1.0 at a fixed 56px, so long SEO titles like "Book Juniors
   (18 & Under) Tennis Lessons - Eltham Park, Greenwich, London" wrapped to
   three tightly-stacked lines of capitals.
   ========================================================================== */
h1.elementor-heading-title {
    /* 1000px + 48px measured out at 33 characters per line, which puts a
       65-character title on 2 lines instead of 3 and sits in the 30-40
       character range that reads best for headings. Tested against the
       longest title on the site; 900px/56px still gave 3 lines at only 22
       characters per line, which is too narrow a measure for display type. */
    max-width: 1000px !important;
    margin-left: auto !important;
    margin-right: auto !important;
    /* Pure-vw scaling shrank too hard at mid widths: 3.6vw gave only 35px at
       a 1000px viewport, which is weak for a hero. The rem+vw form holds the
       size up across desktop (44px at 1000px, 48px at 1440px+) while still
       scaling. Measured at 768/1000/1280/1440/1920. */
    font-size: clamp(32px, 2.25rem + 0.8vw, 48px) !important;
    line-height: 1.18 !important;
    /* Evens out the last line where supported; ignored elsewhere. */
    text-wrap: balance;
}

/* The hero is the only top-level container holding an h1, so this matches it
   without needing a class - which matters because Elementor does not render
   _css_classes on containers in this install. */
.elementor > .e-con:has(h1.elementor-heading-title) {
    min-height: 55vh !important;
}

@media (max-width: 767px) {
    .elementor > .e-con:has(h1.elementor-heading-title) {
        min-height: 42vh !important;
    }
}

/* Below 900px the rem+vw curve is still too large (42px at 768px pushed the
   longest title to 3 lines), so tablet and mobile get their own curve. */
@media (max-width: 900px) {
    h1.elementor-heading-title {
        font-size: clamp(28px, 5vw, 38px) !important;
    }
}

/* ==========================================================================
   [new] Unlinked menu parents — submenu visibility
   Companion to the handler in js/twistfizz.js. !important is required here:
   SmartMenus sets display:none as an inline style, and an inline style is only
   beaten by an !important declaration.
   ========================================================================== */
.elementor-nav-menu li.tf-submenu-open > ul.elementor-nav-menu--dropdown,
.elementor-nav-menu li.tf-submenu-open > ul {
    display: block !important;
    visibility: visible !important;
    opacity: 1 !important;
    max-height: none !important;
}

/* ==========================================================================
   [new] MindBody detail ("View schedule") view
   Added 1 Sep 2026 — fixing damage caused by the card-grid rules above.

   MindBody reuses .class_list for two different states. In LIST view the
   children are a wrapper (<div> or <ol>) holding the cards. In DETAIL view the
   wrapper is gone and a single .class_show.hide-in-detail-view sits directly
   under .class_list. The grid rule above therefore matched the card itself and
   turned it into two columns — which is why the course heading rendered in a
   379px column beside the schedule table instead of above it.

   .class_show is the discriminator: it never wraps the list, only ever a card.
   ========================================================================== */
div.healcode .class_list > .class_show {
    display: block !important;
}

div.healcode .class_show.hide-in-detail-view {
    display: block !important;
    width: 100% !important;
    height: auto !important;
    padding: 28px !important;
    box-sizing: border-box !important;
}

div.healcode .class_show.hide-in-detail-view .hc_header {
    width: 100% !important;
}

/* The schedule panel shipped with no padding and a table that inherited the
   squeezed column width. */
div.healcode.schedule,
div.healcode .schedule {
    padding: 28px !important;
    box-sizing: border-box !important;
}

div.healcode table.schedule {
    width: 100% !important;
}

div.healcode table.schedule td {
    padding: 14px 12px !important;
    vertical-align: middle !important;
}

/* SIGN UP is a fifth button variant (a.hc-button.signup_now) and shipped
   MindBody blue #1B75BB with lime #BCEC0D text. */
div.healcode a.hc-button.signup_now,
div.healcode a.hc-button,
div.healcode input.hc-button {
    background-color: #4CAE4F !important;
    color: #FFFFFF !important;
    border: 2px solid #4CAE4F !important;
}

div.healcode a.hc-button.signup_now:hover,
div.healcode a.hc-button:hover,
div.healcode input.hc-button:hover {
    background-color: #3E9141 !important;
    border-color: #3E9141 !important;
    color: #FFFFFF !important;
}

/* ==========================================================================
   [new] Homepage hero — C.I.C. as an eyebrow
   The Unlimited Elements dual-colour heading renders both parts as inline
   spans, so shrinking "C.I.C." to eyebrow size put it on the same line as
   "TWISTFIZZ" rather than above it. Only the homepage wordmark is targeted —
   other dual-colour headings on the site rely on the inline behaviour.
   ========================================================================== */
.elementor-element-ff13aac .ue-dual-color-heading .ue-title-one {
    display: block !important;
    /* The wordmark's line-height (72px) is smaller than its 96px font size, so
       its glyph box overflows upward and the eyebrow actually OVERLAPPED it by
       14px. Measured optical gaps were -14 / 28 / 22; these values give an even
       24 / 24 / 24 between eyebrow, wordmark, subtitle and buttons. */
    line-height: 1.2 !important;
    margin-bottom: 34px !important;
}

.elementor-element-ff13aac .ue-dual-color-heading .ue-title-two {
    line-height: 1 !important;
}

.elementor-element-36012d9,
.elementor-element-36012d9 > .e-con-inner {
    gap: 16px !important;
}

.elementor-element-524543c {
    margin-top: 6px !important;
}

/* ==========================================================================
   [new] Header utility strip (Option B)
   Element 14814f3 in header template 5364. Backup of the pre-redesign header
   is elementor_library 8257 (draft).
   ========================================================================== */

/* The root header container is boxed, so the strip inherited a 154px inset
   either side instead of running edge to edge. Break it out to full-bleed,
   then re-apply padding that keeps its content aligned with the nav above. */
.elementor-location-header .elementor-element-14814f3 {
    width: 100vw !important;
    max-width: 100vw !important;
    margin-left: calc(50% - 50vw) !important;
    margin-right: calc(50% - 50vw) !important;
    /* Pull the content back to exactly the main row's box. The row lives in
       an .e-con-inner with max-width 1420px and a 134px side margin, so its
       edges sit at max(134px, (width - 1420px) / 2). Matching that expression
       keeps the phone/email/social group flush with the nav and CTA above it -
       the previous 570px assumed a 1140px content width, which is the theme
       default but not what this header actually uses, leaving the strip
       indented by 140px on each side.

       Note this must use vw, not %. Percentage padding resolves against the
       containing block - here the 1420px .e-con-inner - not against the
       strip's own full-bleed 100vw width, so (100% - 1420px) evaluated to 0
       and the max() fell through to the 134px floor. */
    padding-left: max(134px, calc(50vw - 710px)) !important;
    padding-right: max(134px, calc(50vw - 710px)) !important;
}

/* Social icons were still coloured for a white background (#303030) and were
   effectively invisible on the navy strip. */
.elementor-location-header .elementor-element-14814f3 .elementor-social-icon,
.elementor-location-header .elementor-element-14814f3 .elementor-social-icon i,
.elementor-location-header .elementor-element-14814f3 .elementor-social-icon svg {
    color: #FFFFFF !important;
    fill: #FFFFFF !important;
    background-color: transparent !important;
    opacity: .75;
    transition: opacity .3s ease;
}

.elementor-location-header .elementor-element-14814f3 .elementor-social-icon:hover {
    opacity: 1;
}

/* The header is position:fixed, so without this the strip would occupy 34px
   permanently. It shows at the top of the page and folds away on scroll,
   reusing the .scrolled class already set by the header-on-scroll script. */
.elementor-location-header .elementor-element-14814f3 {
    overflow: hidden;
    transition: max-height .3s ease, padding .3s ease;
    max-height: 60px;
}

/* Scrolled, the bar is just the logo row, so with the document padding removed
   the row's own 53px became the whole header and the CTA button touched both
   edges. Padding is added back only in the scrolled state - unscrolled, the
   navy strip still needs to sit flush against the top of the viewport. It is
   transitioned on the same curve as the strip collapse so the two move
   together rather than the bar snapping taller as the strip closes. */
.elementor-location-header.elementor-5364 {
    transition: padding 0.3s;
}

.elementor-location-header.scrolled.elementor-5364 {
    padding-top: 10px !important;
    padding-bottom: 10px !important;
}

/* Unscrolled, the same 20px row-gap was the only thing above the logo row while
   the header's own padding-bottom gave 10px below it, so the white band read as
   20px above / 10px below - visibly bottom-light against the scrolled header,
   which is a clean 10/10. Matching the gap to the padding centres the row.

   Measured on /about/: strip ends at 68, row runs 88-141, header ends at 151.
   With row-gap: 10px the row runs 78-131 inside a header ending at 141: 10 above,
   10 below. */
.elementor-location-header .elementor-element-9f8f640 > .e-con-inner {
    row-gap: 10px !important;
}

/* The strip and the main row are the two children of a flex column with
   row-gap. Collapsing the strip to max-height 0 leaves that gap behind, so the
   scrolled header had space above the logo row and 1px below it. The gap has to
   collapse with the strip. */
.elementor-location-header.scrolled .elementor-element-9f8f640 > .e-con-inner {
    row-gap: 0 !important;
}

.elementor-location-header.scrolled .elementor-element-14814f3 {
    max-height: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

@media (max-width: 767px) {
    .elementor-location-header .elementor-element-14814f3 {
        display: none !important;
    }
}

/* ==========================================================================
   [new] Ghost button — the outline CTA
   Added 1 Sep 2026 for the homepage hero. Extended 11 Sep 2026 to every button
   sitting on a green CTA block.

   Rest   transparent background, white border, white text
   Hover  white background, green border, green text

   A solid white slab with a navy outline reads as heavy on a green block, and
   competes with the white headline above it. Outline-at-rest, fill-on-hover is
   the conventional treatment and keeps the block's colour dominant.

   Audited every button on the site that sits on a solid green background:
   13 in total across 12 pages. Nine were white/navy-outline as reported.
   The other four - "Buy a Bexley Tennis Pass" and the three "Send us a message"
   buttons - were green-on-green (#4CAE4F on #4CAE4F) with only their white
   label visible, so they barely read as buttons at all. Same fix covers both.

   The ID list below pins the 13 known buttons plus the homepage hero, so they
   style instantly with no flash. `.tf-green-cta` is added at runtime by
   js/twistfizz.js to any container with the green background that holds a
   button, so a CTA block built later inherits this automatically without
   another CSS change. `.tf-ghost-btn` is there to apply by hand if needed.
   ========================================================================== */
.tf-ghost-btn .elementor-button,
.tf-green-cta .elementor-button,
.elementor-element-52bff88 .elementor-button,
.elementor-element-3a9cb1d .elementor-button,
.elementor-element-fef7eab .elementor-button,
.elementor-element-a30043a .elementor-button,
.elementor-element-bc442ce .elementor-button,
.elementor-element-8ca9c0b .elementor-button,
.elementor-element-a15d2d7 .elementor-button,
.elementor-element-d095267 .elementor-button,
.elementor-element-280fe43 .elementor-button,
.elementor-element-654de60 .elementor-button,
.elementor-element-901b1d4 .elementor-button,
.elementor-element-fcb1353 .elementor-button,
.elementor-element-7d5abca .elementor-button,
.elementor-element-418fe69 .elementor-button {
    background-color: transparent !important;
    color: #FFFFFF !important;
    border: 2px solid #FFFFFF !important;
    transition: background-color .3s ease, color .3s ease, border-color .3s ease !important;
}

.tf-ghost-btn .elementor-button:hover,
.tf-green-cta .elementor-button:hover,
.elementor-element-52bff88 .elementor-button:hover,
.elementor-element-3a9cb1d .elementor-button:hover,
.elementor-element-fef7eab .elementor-button:hover,
.elementor-element-a30043a .elementor-button:hover,
.elementor-element-bc442ce .elementor-button:hover,
.elementor-element-8ca9c0b .elementor-button:hover,
.elementor-element-a15d2d7 .elementor-button:hover,
.elementor-element-d095267 .elementor-button:hover,
.elementor-element-280fe43 .elementor-button:hover,
.elementor-element-654de60 .elementor-button:hover,
.elementor-element-901b1d4 .elementor-button:hover,
.elementor-element-fcb1353 .elementor-button:hover,
.elementor-element-7d5abca .elementor-button:hover,
.elementor-element-418fe69 .elementor-button:hover,
.tf-ghost-btn .elementor-button:focus,
.tf-green-cta .elementor-button:focus,
.elementor-element-52bff88 .elementor-button:focus,
.elementor-element-3a9cb1d .elementor-button:focus,
.elementor-element-fef7eab .elementor-button:focus,
.elementor-element-a30043a .elementor-button:focus,
.elementor-element-bc442ce .elementor-button:focus,
.elementor-element-8ca9c0b .elementor-button:focus,
.elementor-element-a15d2d7 .elementor-button:focus,
.elementor-element-d095267 .elementor-button:focus,
.elementor-element-280fe43 .elementor-button:focus,
.elementor-element-654de60 .elementor-button:focus,
.elementor-element-901b1d4 .elementor-button:focus,
.elementor-element-fcb1353 .elementor-button:focus,
.elementor-element-7d5abca .elementor-button:focus,
.elementor-element-418fe69 .elementor-button:focus {
    background-color: #FFFFFF !important;
    color: #4CAE4F !important;
    border-color: #4CAE4F !important;
}

/* ==========================================================================
   [new] Header — remove document padding, centre the utility strip items
   Added 1 Sep 2026.

   Elementor's generated post-5364.css sets `.elementor-5364{padding:20px}` from
   the header template's document settings. That made sense when the header was
   a plain white bar; with the full-bleed navy strip it renders as a 20px white
   band above the strip. It should have been changed in Elementor, but that
   template's editor now throws "Cannot read properties of undefined (reading
   'toJSON')" on save, so every save silently failed. Overriding here instead —
   worth fixing at source if the template's editor is ever repaired.
   ========================================================================== */
.elementor-location-header.elementor-5364 {
    padding-top: 0 !important;
    /* Only the TOP needed zeroing - the navy strip has to sit flush against the
       top of the viewport. The bottom still needs its margin, or the logo row
       runs straight into the page content below it. */
    padding-bottom: 10px !important;
}

/* The header is position:fixed at top:0, and the WP admin bar is fixed above it
   at a higher z-index, so while logged in the bar covers the top 32px of the
   header and hides most of the utility strip. Logged-out visitors are
   unaffected, but this makes the admin view match the real one.
   Scoped to 783px and up, where the admin bar is actually position: fixed. */
@media screen and (min-width: 783px) {
    .admin-bar .elementor-location-header.elementor-5364 {
        top: 32px !important;
    }
}

/* No mobile equivalent on purpose. At 782px and below WordPress switches
   #wpadminbar to position: absolute so it scrolls away with the page. A fixed
   header offset by 46px would then hang 46px below the top of the viewport for
   the whole scroll, leaving a permanent gap - which reads as the page scrolling
   wrongly. The offset is only correct while the bar is actually fixed. */

/* Contact items sat on the strip's centre line, the social icons 3px above it.
   Cause: the social wrapper is an inline-grid 26px tall with the 20px icons
   pinned to its top, so centring the wrapper does not centre the icons.
   Collapsing it to a flex row makes wrapper height equal icon height. */
.elementor-location-header .elementor-element-14814f3 .elementor-social-icons-wrapper {
    display: flex !important;
    align-items: center !important;
    line-height: 1 !important;
}

/* Reduced 20% from Elementor's 20px. Elementor drives both the box and the
   glyph from --icon-size, so setting font-size alone shrank the glyph and left
   a 20px box around it; the variable is what actually needs overriding. The
   flex centring below keeps them on the strip's centre line at any size. */
.elementor-location-header .elementor-element-14814f3 .elementor-social-icon {
    --icon-size: 16px;
    font-size: 16px !important;
    width: 16px !important;
    height: 16px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* Each icon is wrapped in a block-level span. A block box containing an
   inline-flex child still builds a text line box, and the font's descender
   space adds 2.5px under the 20px icon, so the icon sits high inside its own
   wrapper. Making the wrapper a flex box removes the line box entirely. */
.elementor-location-header .elementor-element-14814f3 .elementor-grid-item {
    display: flex !important;
    align-items: center !important;
    line-height: 1 !important;
}

/* ==========================================================================
   [new] Overlays — one green, everywhere
   Added 11 Sep 2026.

   Audited every ::before overlay across all 57 pages: 39 already used the
   green #2E6B31, 21 did not. Those 21 were a mix of #000000 and #303030 (the
   Elementor global "Secondary" colour), which read as a grey wash over the
   court photos. Bringing them onto the same green.

   The green replaces the colour but keeps each overlay's existing opacity, so
   nothing gets darker than it already was — at the same alpha the green is
   lighter than black, which is the point.
   ========================================================================== */

/* 18 location/booking cards across /booking/, /booking-eltham-park-south/,
   -courts/, -adults/, -juniors/ and /booking-shooters-hill-sixth-form-courts/.
   Scoped to the .booking-card class rather than the 18 element IDs, so any
   card added later inherits this without another CSS change. */
.booking-card::before,
.booking-card:not(.elementor-motion-effects-element-type-background)::before {
    background-color: #2E6B31 !important;
}

/* The three page heroes that were still dark. Raised to 0.65 to match the
   hero overlay used on the rest of the site — these are headline-over-photo
   sections, not cards, so they follow the hero convention.
   /home/ is a separate page from the live home at /; it is in the sitemap and
   still dark, so it is covered here, but it looks like a leftover duplicate
   and is worth checking. */
.elementor-element-7963b532::before,
.elementor-element-7963b532:not(.elementor-motion-effects-element-type-background)::before,
.elementor-element-a94bbcc::before,
.elementor-element-a94bbcc:not(.elementor-motion-effects-element-type-background)::before,
.elementor-element-5427d4b::before,
.elementor-element-5427d4b:not(.elementor-motion-effects-element-type-background)::before {
    background-color: #2E6B31 !important;
    opacity: 0.72 !important;
}

/* ==========================================================================
   [new] MindBody registration form — bring it onto the site's form styling
   Added 11 Sep 2026. Scoped to .healcode.registration, so it applies wherever
   the widget is used, not just in popup 7299.

   The form is a Healcode widget rendered inline (same-origin, unlike the
   HubSpot chat), so it is styleable - but it arrives with MindBody's own
   design system and ignores the site's. Audited against the Gravity Forms
   styling on /contact/, which is the site's own form standard:

     Site form field   Poppins 15/300, #E5E7EB border, 10px radius
     MindBody field    Lato 16/400, #D5D9DE border, 4px radius

   Buttons were further out. Three tiers appeared, none matching the site:
     Register                  #87C65B - a lighter, yellower green than the
                               brand #4CAE4F, against a #4CAE4F border
     Resend Email              #CC3366, a pink, from MindBody's palette
     Register another client   Lato 700, #DDDFE5 border, 8px radius

   Checkboxes were 41px dark-grey blocks with accent-color #25A9E0 - the old
   primary blue that was replaced elsewhere on the site.
   ========================================================================== */

/* Fields — match the Gravity Forms spec on /contact/ */
.healcode.registration input[type="text"],
.healcode.registration input[type="email"],
.healcode.registration input[type="tel"],
.healcode.registration input[type="password"],
.healcode.registration input[type="number"],
.healcode.registration input[type="date"],
.healcode.registration textarea,
.healcode.registration select {
    font-family: "Poppins", sans-serif !important;
    font-size: 15px !important;
    font-weight: 300 !important;
    color: #6A7181 !important;
    border: 1px solid #E5E7EB !important;
    border-radius: 10px !important;
    padding: 10px !important;
}

.healcode.registration input:focus,
.healcode.registration textarea:focus,
.healcode.registration select:focus {
    border-color: #4CAE4F !important;
    outline: none !important;
}

/* Labels, headings and body copy */
.healcode.registration,
.healcode.registration label,
.healcode.registration h1,
.healcode.registration h2,
.healcode.registration h3,
.healcode.registration h4,
.healcode.registration p,
.healcode.registration span,
.healcode.registration div {
    font-family: "Poppins", sans-serif !important;
}

/* Checkboxes — native control, brand green, sensible size.
   MindBody sets appearance:none and draws its own 41px dark block; restoring
   the native appearance gives a normal tick and lets accent-color do the work. */
.healcode.registration input[type="checkbox"],
.healcode.registration input[type="radio"] {
    appearance: auto !important;
    -webkit-appearance: auto !important;
    accent-color: #4CAE4F !important;
    width: 18px !important;
    height: 18px !important;
    min-width: 18px !important;
    min-height: 18px !important;
    padding: 0 !important;
    background-color: transparent !important;
    border-radius: 0 !important;
}

/* MindBody draws its own tick as a ::before on the input - a 4x12px #2D2D2D
   bar rotated 45 degrees. With the native control restored above, that bar is
   painted on top of the real tick, which is the odd dark slash across the
   checked boxes. Hidden so only the native tick shows. */
.healcode.registration input[type="checkbox"]::before,
.healcode.registration input[type="checkbox"]::after,
.healcode.registration input[type="radio"]::before,
.healcode.registration input[type="radio"]::after {
    display: none !important;
    content: none !important;
}

/* Buttons — the site's three tiers. Shared metrics first. */
.healcode.registration .hc-button,
.healcode.registration .c-button,
.healcode.registration input[type="submit"] {
    font-family: "Poppins", sans-serif !important;
    font-size: 15px !important;
    font-weight: 600 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.5px !important;
    line-height: 1.4 !important;
    padding: 14px 28px !important;
    border-radius: 10px !important;
    border-width: 2px !important;
    border-style: solid !important;
    transition: background-color .3s ease, color .3s ease, border-color .3s ease !important;
}

/* Primary — Register */
.healcode.registration .hc-button.signup_now,
.healcode.registration input[type="submit"] {
    background-color: #4CAE4F !important;
    border-color: #4CAE4F !important;
    color: #FFFFFF !important;
}

.healcode.registration .hc-button.signup_now:hover,
.healcode.registration input[type="submit"]:hover {
    background-color: #3E9141 !important;
    border-color: #3E9141 !important;
    color: #FFFFFF !important;
}

/* MindBody's own stylesheet pins this one button by ID:
   `div.healcode #hc-register { background-color: #87C65B !important }`.
   An ID beats a class even when both are !important, which is why the class
   rule above silently lost - it was present and correct in the cascade and
   still not applied. Restating it at ID specificity is the only way to win
   without touching MindBody. Same for the metrics, which come from one of the
   widget's cross-origin stylesheets and so cannot be read, only overridden. */
div.healcode.registration input#hc-register,
div.healcode.registration input#hc-register.hc-button {
    background-color: #4CAE4F !important;
    border: 2px solid #4CAE4F !important;
    color: #FFFFFF !important;
    padding: 14px 28px !important;
    font-size: 15px !important;
    font-weight: 600 !important;
    border-radius: 10px !important;
}

div.healcode.registration input#hc-register:hover,
div.healcode.registration input#hc-register.hc-button:hover {
    background-color: #3E9141 !important;
    border-color: #3E9141 !important;
    color: #FFFFFF !important;
}

/* Inverse — Register another client */
.healcode.registration .c-button--outline {
    background-color: #FFFFFF !important;
    border-color: #1F242E !important;
    color: #1F242E !important;
}

.healcode.registration .c-button--outline:hover {
    background-color: #1F242E !important;
    border-color: #1F242E !important;
    color: #FFFFFF !important;
}

/* Text — Resend Email (was MindBody pink) */
.healcode.registration .hc-resend-email {
    background-color: transparent !important;
    border-color: transparent !important;
    color: #4CAE4F !important;
}

.healcode.registration .hc-resend-email:hover {
    background-color: transparent !important;
    border-color: transparent !important;
    color: #3E9141 !important;
}

/* ==========================================================================
   [new] Booking sidebar boxes — match the MindBody box to the courses box
   Added 11 Sep 2026.

   The two sidebar boxes were built separately and never matched: the MindBody
   box used 20px padding with a 25px heading, the blue courses box 35px padding
   with a 36px/45px heading. Padding now follows the courses box (35px) and the
   courses heading follows MindBody (25px), which is what was asked for in each
   case.

   Audited across all 57 pages: the MindBody box appears on 15, and its padding
   had already drifted three ways - 20px on 12 pages, 32px on 2, and 32px 40px
   on 1. All 15 are brought to 35px here, so this also closes that drift.

   Selected structurally rather than by element ID, because the box has no
   shared class and a different ID on almost every page. The hook is the
   Healcode account-link widget, which is the one thing every copy of this box
   contains; it sits exactly three levels down inside the box on all 15 pages.
   Note the hook is the <healcode-widget> element itself, not the
   a.healcode-login-register-text-link inside it - that anchor is injected by
   MindBody's script at runtime and so is not reliably present.

   Only one :has(), not nested - see the gotcha in Twistfizz.md.
   ========================================================================== */
.e-con:has(> * > * > healcode-widget[data-type="account-link"]) {
    padding: 35px !important;
}

/* The blue "Junior Courses" box. Only on /book-juniors-18-under/ and
   /booking-eltham-park-juniors-yellow/, and it carries the same element ID on
   both, so the ID is a safe handle here. Scoped to the first heading widget so
   the "January to March 2026" subheading below it keeps its own 18px size. */
.elementor-element-47bfcf8 > .elementor-widget:first-child .elementor-heading-title {
    font-size: 25px !important;
    line-height: 25px !important;
}

/* ==========================================================================
   [new] About pages — uniform person rows
   Added 11 Sep 2026. /about/meet-the-team/ (843) and
   /about/management-board/ (1366).

   Four things were wrong with the same layout, and they share one cause:
   the row was not an equal-height grid.

   1. Images were 400x355, not square.
   2. The text card and the image never matched heights.
   3. Opening a coach's "Show More" grew the text card to ~930px while the
      image stayed 355px pinned to the top, leaving a large empty area beside
      the text. The text column also had justify-content: center, so its
      content floated in the middle of the tall card with ~170px of blank
      space above and below it. That is the "breaks the section" report.
   4. The management board alternated TEXT|IMG and IMG|TEXT down the page.

   align-items: stretch makes both columns take the row height, so they can no
   longer disagree. The image fills its column with object-fit: cover, and a
   400px min-height on the image column means the row is at least as tall as a
   square image - so images render square wherever the bio allows it.

   The image is positioned absolutely inside its column rather than left in
   flow. In flow, a portrait photo sizes the row by its own intrinsic height:
   Russell Durrant's is 1200x1452, which at a 400px column is 484px tall, and
   that alone pushed his row to 484 no matter how short the bio was. Out of
   flow it can only ever fill the space the row gives it.

   Note it is "square wherever the bio allows". A bio taller than 400px makes
   the row taller, and the image grows with it to stay equal. The alternative
   would be clipping the bio, which is worse. Trimming the longest bios by a
   line or two would make every image exactly square.

   The two :has() are siblings, not nested - see the gotcha in Twistfizz.md.
   The `.card` class on the text column is the real discriminator: every person
   row has it, and the "Twistfizz Volunteers" row on page 843 - a two-column
   text section with no card background - does not. Without that guard this
   rule reshaped the volunteers section too, forcing its even 550/550 columns
   into 720/400. :has(> :nth-child(2):last-child) means "exactly two children",
   which additionally keeps this off the three-column stakeholder row on 1366.
   ========================================================================== */
.page-id-843 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child),
.page-id-1366 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child) {
    grid-template-columns: 720px 400px !important;
    align-items: stretch !important;
}

/* Image column: always on the right, square floor, fills its column. */
.page-id-843 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child) > *:has(img),
.page-id-1366 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child) > *:has(img) {
    order: 2;
    min-height: 400px;
    position: relative;
    overflow: hidden;
    border-radius: 10px;
}

.page-id-843 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child) > *:has(img) img,
.page-id-1366 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child) > *:has(img) img {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
}

/* Text card: always on the left, content anchored to the top.
   Vertical padding comes down from 45px to 25px. The bios' own natural height
   is ~345px; at 45px top and bottom the card measured 435px, which pushed the
   row past the 400px square and stopped the images being square. 20px brings
   every row in under 400, so the square floor wins and all images render
   square. Horizontal padding is unchanged. */
.page-id-843 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child) > *:not(:has(img)),
.page-id-1366 .e-con.e-grid:has(> .card):has(> * img):has(> :nth-child(2):last-child) > *:not(:has(img)) {
    order: 1;
    justify-content: flex-start !important;
    padding-top: 20px !important;
    padding-bottom: 20px !important;
}

/* ==========================================================================
   [new] Arrow link — align with the body copy beside it
   Added 11 Sep 2026.

   "See our safeguarding policy" is a Text-tier button, so it inherited the
   14px 28px button padding. The box lined up with the paragraph above it, but
   the visible text started 28px further right, which reads as an indent.
   A text link should align on its text, not its box.
   ========================================================================== */
.arrow-link .elementor-button {
    padding-left: 0 !important;
}

/* The safeguarding "Contact" button carried a phone icon, which was hidden
   here on 11 Sep 2026. Superseded the same day by the arrow rollout in
   js/twistfizz.js, which replaces that icon with the standard arrow - so this
   rule was left hiding the arrow instead, and the button was the only one on
   the site with no visible icon. Rule removed; the button now matches. */

/* ==========================================================================
   [new] Header dropdowns — one highlight shape
   Added 11 Sep 2026.

   The green highlight was rounded on all four corners in the hover state,
   while the panel's first and last items also carry corner radius to match the
   panel itself. With two items highlighted at once - one hovered, one the
   current page - the two greens met with rounded inner corners and left a
   notch between them, and a highlighted middle item appeared rounded on top
   and square at the bottom.

   The shape should depend on where an item sits in the panel, never on its
   state. Zeroed for every state first, then reapplied to the first and last
   items only, so hover, focus and current all produce the same silhouette.

   Deliberately not `overflow: hidden` on the panel, which would have been the
   shorter fix: these menus have third-level flyouts that open outside the
   parent panel, and hiding overflow would clip them.
   ========================================================================== */
.elementor-location-header .elementor-nav-menu--dropdown li > a,
.elementor-location-header .elementor-nav-menu--dropdown li > a:hover,
.elementor-location-header .elementor-nav-menu--dropdown li > a:focus,
.elementor-location-header .elementor-nav-menu--dropdown li > a.highlighted,
.elementor-location-header .elementor-nav-menu--dropdown li.current-menu-item > a,
.elementor-location-header .elementor-nav-menu--dropdown li.current-menu-ancestor > a,
.elementor-location-header .elementor-nav-menu--dropdown li.current-menu-parent > a {
    border-radius: 0 !important;
}

.elementor-location-header ul.elementor-nav-menu--dropdown > li:first-child > a {
    border-radius: 12px 12px 0 0 !important;
}

.elementor-location-header ul.elementor-nav-menu--dropdown > li:last-child > a {
    border-radius: 0 0 12px 12px !important;
}

/* Elementor renders an "icon before label" button by keeping the DOM as
   (text, icon) and setting flex-direction: row-reverse on the content wrapper.
   js/twistfizz.js moves the arrow to the end of the DOM, but row-reverse then
   flipped it back to the left on screen - which is why arrows appeared on both
   sides. Undoing the reversal only for buttons the script normalised, so the
   Google Play and App Store buttons keep their platform icon before the label
   where it belongs. */
.tf-arrow-btn .elementor-button-content-wrapper {
    flex-direction: row !important;
}

/* ==========================================================================
   [new] Header menu — submenus match their parents
   Added 11 Sep 2026.

   Top level was Poppins 15px/400, sentence case, #303030. Submenu items were
   Poppins 14px/500 and UPPERCASE in #1F242E, so the dropdown read as a
   different typeface from the menu that opened it. Matched to the parent.
   ========================================================================== */
.elementor-location-header .elementor-nav-menu--dropdown a.elementor-sub-item,
.elementor-location-header .elementor-nav-menu ul.sub-menu a {
    font-size: 15px !important;
    font-weight: 400 !important;
    text-transform: none !important;
    letter-spacing: normal !important;
    color: #303030 !important;
}

/* An ancestor of the current page ("Eltham Park South") gets no fill - it sits
   on the plain white panel - so its label must be green to stand out.

   There is deliberately NO rule here for current-menu-item. Updated 29 Sep 2026:
   there used to be one setting it white, on the assumption that Elementor always
   fills the current page green. It does not. Elementor paints the fill from
   `.elementor-item-active`, which it adds only to real page links. WordPress also
   marks *anchor* links to the current page (Coaches and Volunteers under Team,
   which point at #coaches and #volunteers on the Meet the Team page) as
   current-menu-item - those get no fill, so the white rule made them vanish
   against the white panel.

   The white text is now keyed only to the four states that actually paint the
   fill: :hover, :focus, .highlighted and .elementor-item-active - see below. A
   genuine current page still reads white on green through .elementor-item-active;
   an anchor link to the current page keeps the default #303030 and stays legible.

   Getting this wrong makes an item vanish. v1.24.2 set both states to white,
   which hid the ancestor; a later attempt set both green, which hid the current
   item. */
.elementor-location-header .elementor-nav-menu--dropdown li.current-menu-ancestor > a,
.elementor-location-header .elementor-nav-menu--dropdown li.current-menu-parent > a,
.elementor-location-header .elementor-nav-menu ul.sub-menu li.current-menu-ancestor > a,
.elementor-location-header .elementor-nav-menu ul.sub-menu li.current-menu-parent > a {
    color: #4CAE4F !important;
}

/* Hover and focus DO paint the green fill, so the label goes white there, as
   everywhere else on the site. Listed after the current-item rule on purpose:
   the two have equal specificity, so source order decides, and hovering the
   current item should still read white on green rather than green on green.

   Updated 14 Sep 2026: hover and focus are not the only states that paint the
   fill. Elementor's own rule is

     .elementor-nav-menu--dropdown a:hover,
     .elementor-nav-menu--dropdown a:focus,
     .elementor-nav-menu--dropdown a.elementor-item-active,
     .elementor-nav-menu--dropdown a.highlighted { background-color: <green> }

   and it adds `.highlighted` to a parent item for as long as its flyout is open.
   So once the pointer moved off "Bexley" and into its own flyout, the anchor was
   no longer hovered, `.highlighted` kept the green fill, and the label snapped
   back to #303030 - dark text on green for as long as the flyout was showing.
   Matching Elementor's own state list fixes it at source.

   Scoped to submenus on purpose. The top-level items live in ul.elementor-nav-menu
   on the white header bar and get no fill, so whitening those would make them
   disappear.

   The `li >` in these selectors is load-bearing. The current-menu-ancestor rule
   above is `... ul.sub-menu li.current-menu-ancestor > a` - four classes and
   three element names. Written as `ul.sub-menu a.highlighted` this rule has four
   classes and only two element names, so it loses on specificity and the
   ancestor's green wins even though both are !important and this one is later in
   the file. Adding `li >` levels the element count, and source order then does
   what it is supposed to. */
.elementor-location-header .elementor-nav-menu--dropdown li > a:hover,
.elementor-location-header .elementor-nav-menu--dropdown li > a:focus,
.elementor-location-header .elementor-nav-menu ul.sub-menu li > a:hover,
.elementor-location-header .elementor-nav-menu ul.sub-menu li > a:focus,
.elementor-location-header .elementor-nav-menu--dropdown li > a.highlighted,
.elementor-location-header .elementor-nav-menu--dropdown li > a.elementor-item-active,
.elementor-location-header .elementor-nav-menu ul.sub-menu li > a.highlighted,
.elementor-location-header .elementor-nav-menu ul.sub-menu li > a.elementor-item-active {
    color: #FFFFFF !important;
}

/* ==========================================================================
   [new] Contact page — columns were sized against the wrong box
   Added 11 Sep 2026. Page 274 only; audited all 57 pages and this is the
   single instance.

   The two columns carry Elementor's `--width: 65%` and `--width: 32%`, which
   is how a *flex* container's children are sized. This container is a grid
   with two fixed 545px tracks, so those percentages resolved against 545px
   rather than the 1140px row: the form came out 354px wide and "Get in Touch"
   just 174px, squeezing every card and wrapping the headings.

   The 65/32 split is the author's stated intent, so the tracks are set to 2fr
   and 1fr and the children told to fill them. The proper fix is in Elementor -
   either set both columns to 100% now the parent is a grid, or switch the
   parent back to flex - and this should be removed when that is done.
   ========================================================================== */
.page-id-274 .elementor-element-1ad727dd > .e-con-inner {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) !important;
}

.page-id-274 .elementor-element-1ad727dd > .e-con-inner > .e-con {
    width: 100% !important;
}

/* ==========================================================================
   [new] Breadcrumb (see js/twistfizz.js)
   Added 11 Sep 2026. Booking pages only.

   Deliberately quiet: this is a way back, not a call to action, so it should
   not compete with the hero above it or the first heading below it.
   ========================================================================== */
.tf-breadcrumb {
    max-width: 1140px;
    margin: 0 auto;
    /* Symmetric on purpose: the bar sits in its own strip between the hero and
       the first section, so uneven padding reads as the trail hugging the hero.
       Was 18px top / 0 bottom. */
    padding: 16px 20px;
    font-family: "Poppins", sans-serif;
    font-size: 14px;
    line-height: 1.5;
}

.tf-breadcrumb ol {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
}

.tf-breadcrumb li {
    display: flex;
    align-items: center;
    color: #6A7181;
}

/* Separator drawn in CSS rather than added to the markup, so screen readers
   read the list without a chevron between every item. */
.tf-breadcrumb li + li::before {
    content: "";
    display: inline-block;
    width: 5px;
    height: 5px;
    margin-right: 8px;
    border-top: 1.5px solid #B9BEC7;
    border-right: 1.5px solid #B9BEC7;
    transform: rotate(45deg);
}

.tf-breadcrumb a {
    color: #6A7181;
    text-decoration: none;
    transition: color .2s ease;
}

.tf-breadcrumb a:hover,
.tf-breadcrumb a:focus {
    color: #4CAE4F;
    text-decoration: underline;
}

.tf-breadcrumb li[aria-current="page"] {
    color: #1F242E;
    font-weight: 500;
}

@media (max-width: 767px) {
    .tf-breadcrumb {
        font-size: 13px;
        padding-top: 14px;
    }
}

/* ==========================================================================
   [new] Footer — four columns
   Added 11 Sep 2026.

   A Locations column was added to the footer (template 5384, row c427364),
   which had been built as a four-column grid with only three children - hence
   the empty space to the right of Contact. The new column dropped onto a
   second row instead of filling that gap.

   Elementor's own generated CSS sets --e-con-grid-template-columns to
   repeat(4, 1fr) and the computed variable on the element really is that, yet
   the used grid-template-columns stayed at three columns, and no rule in any
   readable stylesheet sets that property on this element. Rather than keep
   chasing it, the value is set directly here.

   Scoped to desktop so Elementor's own tablet (2 columns) and mobile
   (1 column) rules are left alone.
   ========================================================================== */
@media (min-width: 1025px) {
    .elementor-location-footer .elementor-element-c427364 {
        grid-template-columns: repeat(4, 1fr) !important;
    }
}

/* ==========================================================================
   [new] Green CTA blocks — texture and depth
   Added 14 Sep 2026.

   The solid green CTA blocks read as flat slabs.

   First attempt reused the site's existing dot pattern verbatim - the
   radial-gradient on /tennis-in-bexley/'s .testimonials-section: 1px dots at
   10% white, 40px apart. It rendered correctly and was still invisible at
   normal viewing distance, which is presumably why those blocks looked flat in
   the first place. Matching an ineffective pattern is not the same as fixing
   the problem, so this deviates from it deliberately:

     dots     1.5px at 16% white, 28px apart  (was 1px / 10% / 40px)
     depth    a soft diagonal wash, light top-left to dark bottom-right

   The wash is what stops it reading as a printed texture on a flat colour: it
   gives the block a light source. Both are kept low - the block still has to
   sit behind white type and a white outline button without competing.

   Painted as ::after rather than the element's own background-image. Setting
   background-image on .tf-green-cta did not work and was worth understanding:
   the rule was served with !important, the class was on the element, there was
   no inline style - yet background-image computed to `none` while
   background-size from the *same* rule applied as 40px 40px. A pseudo-element
   sidesteps whatever owns the element's background.

   pointer-events: none so it never intercepts a click on the CTA button.
   ========================================================================== */
.tf-green-cta {
    position: relative;
}

.tf-green-cta::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.16) 1.5px, transparent 0),
        linear-gradient(135deg, rgba(255, 255, 255, 0.10) 0%, rgba(255, 255, 255, 0) 45%, rgba(0, 0, 0, 0.12) 100%);
    background-size: 28px 28px, 100% 100%;
    pointer-events: none;
    z-index: 0;
}

/* Keep the block's own content above the texture. */
.tf-green-cta > * {
    position: relative;
    z-index: 1;
}

/* ==========================================================================
   [new] App download cards: centre the contents, even out the gaps
   Added 14 Sep 2026.

   The "Download on Google Play" / "Download on App store" cards on the booking
   pages looked top-heavy: the content was mathematically centred, but two
   widgets carried invisible slack that pushed the visible shapes upward.

   The icon widget rendered its box as inline-block, which adds ~3px of baseline
   descender space under it. It has to become inline-FLEX, not flex: a block-level
   flex container stretches the green tile across the whole card. The link widget is a .elementor-button carrying
   14px of vertical padding, so the visible "GET IT NOW" text sat 14px inside a
   53px-tall box - the gap above the link read as 34px against 23px above the
   heading, and the card finished with an 18px tail.

   Flattening both makes the flex gap the only spacing, so the three visible
   shapes are evenly spaced and the group is centred in the card.

   The padding override needs !important because the site's own button rule
   (`.elementor-button, a.elementor-button, ...`) sets the padding shorthand with
   !important - a plain longhand loses to that however specific it is.

   Selected by store link rather than by a class: these cards are duplicated
   across the venue booking pages with different element IDs, and container
   `_css_classes` set over REST does not reach the markup (see Twistfizz.md).
   ========================================================================== */
.e-con.card:has(> .elementor-widget-button a[href*="play.google.com"]),
.e-con.card:has(> .elementor-widget-button a[href*="apps.apple.com"]) {
    justify-content: center;
    gap: 24px;
}

.e-con.card:has(> .elementor-widget-button a[href*="play.google.com"]) .elementor-icon,
.e-con.card:has(> .elementor-widget-button a[href*="apps.apple.com"]) .elementor-icon {
    display: inline-flex;
}

.e-con.card:has(> .elementor-widget-button a[href*="play.google.com"]) .elementor-button,
.e-con.card:has(> .elementor-widget-button a[href*="apps.apple.com"]) .elementor-button {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* ==========================================================================
   [new] Badge pills: breathing room above the heading
   Added 12 Oct 2026.

   The pills ("Community Interest Company", "Welcome to TwistFizz",
   "Non-executive Director") sat flush against the heading below them - the
   measured gap between the pill's bottom edge and the heading's box was 0px,
   with only the heading's own 8px top margin and its line-height leading
   keeping them apart. At the pill's small type that reads as crowding.

   Applied to the class rather than per page: .tf-pill is tagged at runtime in
   js/twistfizz.js by matching the computed style (40px radius + #E3F2E4), so
   every pill on the site is covered, including any added later.

   margin-bottom rather than a gap on the parent: the pills sit in containers
   whose gap is 0 and which hold other widgets too, so a gap there would push
   everything apart, not just the pill.
   ========================================================================== */
.tf-pill {
    margin-bottom: 16px !important;
}

/* ==========================================================================
   Policy pages (Policies & Safeguarding)
   Plain-content pages, so everything is scoped to .tf-policy on the wrapper.
   ========================================================================== */

.tf-policy {
    max-width: 820px;
}

.tf-policy > *:first-child {
    margin-top: 0;
}

.tf-policy h2 {
    font-family: "Poppins", sans-serif;
    font-size: 30px;
    font-weight: 600;
    color: #1F1F1F;
    margin: 48px 0 16px;
}

.tf-policy h3 {
    font-family: "Poppins", sans-serif;
    font-size: 21px;
    font-weight: 600;
    color: #2E6B31;
    margin: 32px 0 10px;
}

.tf-policy p,
.tf-policy li {
    font-family: "Montserrat", sans-serif;
    font-size: 17px;
    line-height: 1.65;
    color: #4A4A4A;
}

.tf-policy ul {
    padding-left: 22px;
    margin: 0 0 20px;
}

.tf-policy li {
    margin-bottom: 8px;
}

.tf-policy a {
    color: #2E6B31;
    text-decoration: underline;
}

.tf-policy a:hover {
    color: #4CAE4F;
}

/* Lead paragraph under the page title */
.tf-policy .tf-lead {
    font-size: 19px;
    line-height: 1.6;
    color: #1F1F1F;
}

/* Grey strapline, e.g. "Fair access. Dignity. Belonging." */
.tf-policy .tf-strap {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: #4CAE4F;
    margin-bottom: 8px;
}

/* Green-tinted callout for the "report it now" and legal notes */
.tf-policy .tf-callout {
    background: #E3F2E4;
    border-left: 4px solid #4CAE4F;
    border-radius: 8px;
    padding: 22px 26px;
    margin: 28px 0;
}

.tf-policy .tf-callout > *:first-child {
    margin-top: 0;
}

.tf-policy .tf-callout > *:last-child {
    margin-bottom: 0;
}

.tf-policy .tf-callout h3 {
    margin-top: 0;
}

/* Urgent variant for the 999 / immediate danger notes */
.tf-policy .tf-callout--urgent {
    background: #FDF3F2;
    border-left-color: #C0392B;
}

/* Contact card: welfare officer, data protection lead, LTA */
.tf-policy .tf-contact {
    background: #F4F6F4;
    border-radius: 12px;
    padding: 22px 26px;
    margin: 20px 0;
}

.tf-policy .tf-contact p {
    margin: 0 0 4px;
}

.tf-policy .tf-contact strong {
    color: #1F1F1F;
}

/* Document control and protected-characteristic tables */
.tf-policy table {
    width: 100%;
    border-collapse: collapse;
    margin: 20px 0 28px;
    font-family: "Montserrat", sans-serif;
    font-size: 16px;
}

.tf-policy table th,
.tf-policy table td {
    text-align: left;
    vertical-align: top;
    padding: 12px 14px;
    border-bottom: 1px solid #E2E6E2;
    line-height: 1.55;
    color: #4A4A4A;
}

.tf-policy table th {
    background: #F4F6F4;
    font-weight: 600;
    color: #1F1F1F;
}

.tf-policy table td:first-child {
    font-weight: 600;
    color: #1F1F1F;
    width: 34%;
}

/* PDF download link */
.tf-policy .tf-download {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: #4CAE4F;
    color: #FFFFFF !important;
    font-family: "Montserrat", sans-serif;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    text-decoration: none !important;
    border-radius: 40px;
    padding: 14px 28px;
    margin: 8px 0 32px;
    transition: background 0.2s ease;
}

.tf-policy .tf-download:hover {
    background: #2E6B31;
    color: #FFFFFF !important;
}

/* Hub page: one card per policy */
.tf-policy-index {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
    margin: 32px 0 8px;
    max-width: 980px;
}

.tf-policy-card {
    display: block;
    background: #FFFFFF;
    border: 1px solid #E2E6E2;
    border-radius: 12px;
    padding: 26px 28px;
    text-decoration: none !important;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.tf-policy-card:hover {
    border-color: #4CAE4F;
    box-shadow: 0 10px 24px rgba(31, 31, 31, 0.08);
    transform: translateY(-2px);
}

.tf-policy-card h3 {
    font-family: "Poppins", sans-serif;
    font-size: 20px;
    font-weight: 600;
    color: #1F1F1F;
    margin: 0 0 8px;
}

.tf-policy-card p {
    font-family: "Montserrat", sans-serif;
    font-size: 15.5px;
    line-height: 1.55;
    color: #6A6A6A;
    margin: 0;
}

@media (max-width: 767px) {
    .tf-policy h2 { font-size: 25px; margin-top: 36px; }
    .tf-policy h3 { font-size: 19px; }
    .tf-policy p,
    .tf-policy li { font-size: 16px; }
    .tf-policy .tf-lead { font-size: 17.5px; }
    .tf-policy table,
    .tf-policy table th,
    .tf-policy table td { font-size: 15px; }
    .tf-policy table td:first-child { width: auto; }
    .tf-policy .tf-callout,
    .tf-policy .tf-contact { padding: 18px 20px; }
}

/* Coach cards: the photo is a grid sibling of the text column, so opening the
   "Show More" accordion used to stretch it to the card's new height. Pin it to
   the top of the cell and keep it square however tall the text grows. */
.elementor-element-c34eb6c > .e-con > .elementor-widget-image {
    align-self: start;
}

.elementor-element-c34eb6c > .e-con > .elementor-widget-image img {
    aspect-ratio: 1 / 1;
    height: auto !important;
    object-fit: cover;
}

/* Links inside the coach profiles were picking up a stray pink from the kit. */
.elementor-element-c34eb6c a:not(.elementor-button) {
    color: #2E6B31;
    text-decoration: underline;
}

.elementor-element-c34eb6c a:not(.elementor-button):hover {
    color: #4CAE4F;
}

/* ==========================================================================
   Meet the Team: Safety section
   Was a 705/415 grid, which left a big empty gap on the left and squeezed
   Anita's card into a tall narrow column. Even columns, top aligned, and the
   card's copy reads left to right like the rest of the site.
   ========================================================================== */

@media (min-width: 1025px) {
    .elementor-element-11a2abb8 > .e-con-inner {
        grid-template-columns: 1fr 1fr !important;
        align-items: start !important;
        gap: 48px !important;
    }

    .elementor-element-0d50325 {
        padding-top: 8px !important;
    }
}

/* Anita's card */
.elementor-element-fd72d69 {
    align-items: flex-start !important;
    text-align: left;
}

.elementor-element-fd72d69 .elementor-heading-title,
.elementor-element-fd72d69 .elementor-widget-container {
    text-align: left;
}

/* The role pill and name were centred over left-aligned body copy. */
.elementor-element-06f4f11 {
    justify-content: flex-start !important;
}

.elementor-element-fd72d69 .elementor-widget-button .elementor-button {
    width: auto;
}

/* Urgent callouts keep their red heading rather than the green default. */
.tf-policy .tf-callout--urgent h3 {
    color: #C0392B;
}

/* Anita's role pill was still centring itself inside the left-aligned card. */
.elementor-element-fd72d69 > .elementor-element-06f4f11 {
    align-self: flex-start !important;
}
