/*
Theme Name: Strata Child
Template: strata
Author: CCW
Version: 1.7.3
Description: Child theme for ccw.uk.com. CSS/PHP overrides only; the Strata parent stays untouched. v1.0.0: contact-form focus colour, pinch-zoom, minor mobile spacing. v1.1.x-1.3.x: contact map explored as a static self-hosted image (tilted European reach map). v1.4.0: contact map is now a LIVE Leaflet map on free CARTO/OSM tiles (no API key), locked/non-interactive, that auto-fits all the congress cities to any banner shape (reflows, never crops or shows white). Leaflet self-hosted; loaded only on the Contact page. v1.4.1: contact map banner height reduced (40vh, max 460px) to sit with the other page banners; footer widget row centred to the 1100px content width with its three columns evenly distributed. v1.4.2: added a hero banner to the Trade Shows (Events) page (GSMA MWC / Fira Barcelona photo) so it matches the other pages. v1.4.3: swapped the Trade Shows banner photo to a free, commercially-licensed Unsplash expo-floor image (the earlier MWC photo was copyrighted). v1.4.4: site capped at 1920px centred on very wide screens (Qode's fluid-width/fixed-height banners cover-crop the slider images beyond ~1850px; 2560 fullscreen lost the river) + slide crops centred instead of top-anchored. v1.4.5: uniform banners — ALL pages 650px tall (Qode sliders via page meta; Contact map + Events banner 40vh/460 -> 650); banner images recropped 1920x650; About video rebuilt 1920x650. v1.5.0 (2026-07-10 refinements): banner spec lowered to 1920x550 (page meta 550 + recrops + video rebuilt, incl. the Services slides this time); contact map: Bonn -> Munich, pins get a soft pulsing glow; FIX 8 — Contact/Trade-Shows banners tuck under the transparent header like the slider pages (kill content_top_margin; top scrim on the light map for menu legibility); FIX 9 — hero sliders scroll IN-FLOW on every page (parent pins .carousel-inner position:fixed for a skrollr uncover effect — now all five banners scroll away with the page uniformly); slide VIDEO sized correctly via js/ccw-video-dims.js (parent hardcodes 1280x720 globals) + object-fit belt. v1.5.1: Trade Shows banner photo swapped to Manu Lozano's GSMA MWC / Fira Barcelona shot (licensed to Fred); FIX 10 — compact bottom-of-page: the "How can we be of Assistance?" call-to-action row, the footer widget band (incl. a smaller offices map), the copyright bar, and a tidy .ccw-offices phone list (tap-friendly tel: links; widget text corrected to proper international formats). v1.5.2: FIX 4b — mobile reach-map legibility (taller 420px map, pins/halos/pulse/labels scaled down, fit padding shrunk on mobile in ccw-reach-map.js — the 150px top padding is for the desktop header tuck only); FIX 11 — the Twitter bird is the X logo site-wide (FA4 has no X glyph; currentColor SVG mask); FIX 12 — contact form Website field replaced by Company (child AJAX endpoint ccw_contact_mail — the plugin's ajax_mail.php esc_url()s the field, which would mangle a company name; old website field kept as a hidden honeypot). v1.5.3 (Fred's mobile pass + Phase-3 SEO): FIX 4c — mobile map pins/labels reduced a LOT more (7px pins, 10px labels); FIX 13 — mobile hamburger was invisible (#777 on the #212121 header -> white); FIX 14 — footer offices map centred on mobile; .ccw-offices rows slightly tighter (9px -> 6px, still tap-safe); FIX 15 (functions.php) — SEO head: document title from qode_seo_title (the module never output it), OG/Twitter tags, Organization+WebSite JSON-LD on the front page, TEC Event JSON-LD repairs (double-escaped description, organizer Person->Organization, bogus performer). v1.5.4: FIX 13b — the header-top social icons + "Contact us" phone (inline-styled #777777 on the #212121 bar) go white at mobile widths, same fix as the hamburger. v1.5.5: FIX 12b — the contact endpoint no longer passes its own From header (built from qode email_from = website@ccw.uk.com, whose DMARC p=reject was silently killing every send); the mail plugin's/site's From applies unconditionally, visitor stays in Reply-To and the body. v1.5.6: FIX 13c — the header-top social icons were STILL grey on mobile: the parent's responsive.css re-greys them at <=1000px with a higher-specificity !important rule that beat 13b; repeated class lifts the child selector above both .light/.dark variants. v1.5.7: FIX 16 — the Home cover boxes (About Us / Our Services / Main Events) are a hover accordion the parent breaks on phones: at <=768px the text panel stays absolutely positioned beside a fixed-width thumb (clipped by the li's overflow:hidden) and at <=480px responsive.css hides .box_content entirely (display:none) — a decade of image-only mute links on mobile. Child restyles them as stacked cards at <=768px: natural-size centred thumb, text + button statically below, always visible. v1.5.8: FIX 17 + FIX 10 retune (Fred's spacing pass) — parallax slogan lines get 16px between them; the full-width testimonials band compacted (parent gave it 46/75px paddings + 50px margin + 25px slides margin, ~150px of air under the quote); CTA band now 18px top / 48px bottom (was 16/14 — hugged the footer), uniform across Home/About/Services via the :has() override of the inline row paddings; About gets a 40px breather between the counters parallax and the testimonials (parallax + .section:has(.testimonials_holder) adjacency, fires only there). v1.5.9: footer offices map back UP to 170px (110px read small beside the offices list / news widget); footer-map.png regenerated at 2x (502x290, gen_footer_map.py) so the bigger display is crisp — BOTH the png and its .webp sibling must deploy together (stale-sibling hazard). v1.6.0 (Phase-5 perf): FIX 18 — desktop CLS 1.0 root cause was the parent's "uncover" footer (position:fixed from first paint + setContentBottomMargin() JS margin; the footer's in-viewport rect then grows/moves as its widgets load — PSI attribution named footer.uncover at exactly 1.000). Footer now scrolls in flow (same family as FIX 9's in-flow sliders) and the JS margin is neutralised; plus size reserves for the two unsized-image culprits (footer map 502x290 -> fixed 170px box, Home circle images 1:1). FIX 19 (functions.php) — front-end weight shed: WooCommerce styles/scripts dequeued outside shop contexts (no products published), mediaelement only where a video slide exists (About), Google Fonts get display=swap + a fonts.gstatic.com preconnect. v1.6.1: FIX 19a2 — wc-blocks-style survived the priority-100 dequeue (WC re-enqueues it after wp_enqueue_scripts; verified in the rendered staging head); now dequeued AND deregistered at wp_print_styles (last hook before the head prints), plus the woocommerce-inline stub, same shop-context guard. v1.7.0 (Phase-6): FIX 20 — "Industry News" is now curated, human-approved items (CCW_News_Widget reading the ccw_news_items JSON option) with a CSS-only cross-fade rotation (zero JS, reserved height = zero CLS); replaces the ge-rss-reader jQuery ticker whose upstream Feed Informer digest was mangled and unmaintained. v1.7.1 (Fred's staging pass): FIX 21 — the Home client-logo carousel becomes a continuous slow conveyor (js/ccw-logo-conveyor.js re-inits the parent's FlexSlider: move 1, linear easing, animation==interval, hover pauses; the old init lurched a full viewport in 0.6s then froze 3s); FIX 20 refinements — news item titles in lighter grey (#b0b0b0), news list bottom-aligned with the offices phone list via a desktop-only flex footer row. v1.7.2 (Fred's second staging pass): FIX 21 reworked — the logo strip is now a Web-Animations BOUNCE marquee (glides to the far end and back, ~45px/s, hover pauses; the FlexSlider ticker re-init only made one pass and idled 4.5s before starting); the footer flex bottom-align REVERTED (the column floor is the tallest column's, text landed far too low) for a simple 6px nudge under the heading; hero-slide order pinned via menu_order 1-4 (script 07 — all four were 0, the DB tie-break reshuffled when Phase-6 added posts). v1.7.3: FIX 19b — mediaelementplayer no-op guard stub (functions.php): FIX 19's dequeue left the parent's UNGUARDED initVideoBackground call throwing on every non-About page, which killed the rest of the ready chain (initCoverBoxes = Fred's dead Home hover boxes, initSearchButton, content menu) since the Phase-5 deploy; the stub restores the chain while keeping the weight shed.
*/

/* =======================================================================
   FIX 1 — Contact-form focus colour  (Fred's "offensive light blue")
   Parent css/stylesheet.css:7372-7380 turns the TYPED TEXT bright cyan
   (#00aeef) on focus. Keep a subtle border cue; make the text dark/readable.
   Child loads after the parent, so these win (also !important as a belt).
   ======================================================================= */
#respond textarea:focus,
#respond input[type='text']:focus,
.contact_form input[type='text']:focus,
.contact_form textarea:focus,
.post-password-form input[type='password']:focus {
    color: #333 !important;              /* was #00aeef */
    border-color: #b8b8b8 !important;    /* soft grey, not bright cyan */
    background-color: #fff !important;
}

/* Typed text stays dark even while focused (parent resting colour is #777). */
.contact_form textarea,
.contact_form input[type='text'],
#respond textarea,
#respond input[type='text'] {
    color: #333;
}

/* =======================================================================
   FIX 3 — Minor mobile spacing (conservative first pass)
   Pinch-zoom is re-enabled in functions.php (viewport), not here.
   Hero-slider fine-tuning is deliberately deferred to a staging iteration
   (its height comes from slide settings/JS; guessing selectors here is risky).
   ======================================================================= */
@media only screen and (max-width: 768px) {
    /* trim the large vertical gaps between stacked full-width sections */
    .full_width .parallax_content {
        padding-top: 30px;
        padding-bottom: 30px;
    }
}

/* =======================================================================
   FIX 4 — Contact-page "European reach" map: a live Leaflet map on free
   CARTO/OSM tiles (no API key), locked so it's non-interactive, that auto-fits
   all the cities into whatever shape the banner is — so it reflows to any
   screen and never crops a city or shows a white edge. London is the red
   anchor; Lisbon and Cannes are enlarged. Loaded only on this page.
   ======================================================================= */
.google_map.ccw_reach_map {
    display: block;
    position: relative;
    width: 100%;
    height: 550px;                /* uniform banner height, same as the Qode sliders (v1.5.0) */
    padding: 0;
    background: #eef2f5;          /* == the tiles' sea colour, shown while they load */
}
#ccw-reach-map { width: 100%; height: 100%; background: #eef2f5; }

/* --- custom city pins (Leaflet divIcon) --- */
.leaflet-div-icon.ccw-pin-wrap { background: transparent; border: 0; }
.ccw-pin {
    position: absolute; left: 0; top: 0; transform: translate(-50%, -50%);
    width: 16px; height: 16px; border-radius: 50%;
    background: #0080c4; border: 3px solid #fff;
    box-shadow: 0 0 0 6px rgba(0, 128, 196, .26);
}
.ccw-pin--l  { width: 22px; height: 22px; }
.ccw-pin--xl { width: 28px; height: 28px; background: #d63030; box-shadow: 0 0 0 7px rgba(214, 48, 48, .26); }

/* --- v1.5.0: soft pulsing glow on the pins (Fred's request). A ::after ring
   expands + fades on loop; halo colour follows the pin colour. Disabled for
   users who prefer reduced motion. --- */
@media (prefers-reduced-motion: no-preference) {
    .ccw-pin::after {
        content: '';
        position: absolute; inset: -3px;
        border-radius: 50%;
        box-shadow: 0 0 0 0 rgba(0, 128, 196, .45);
        animation: ccw-pin-pulse 2.6s ease-out infinite;
    }
    .ccw-pin--xl::after {
        box-shadow: 0 0 0 0 rgba(214, 48, 48, .5);
        animation-name: ccw-pin-pulse-red;
    }
    @keyframes ccw-pin-pulse {
        0%   { box-shadow: 0 0 0 0    rgba(0, 128, 196, .45); }
        70%  { box-shadow: 0 0 0 16px rgba(0, 128, 196, 0); }
        100% { box-shadow: 0 0 0 0    rgba(0, 128, 196, 0); }
    }
    @keyframes ccw-pin-pulse-red {
        0%   { box-shadow: 0 0 0 0    rgba(214, 48, 48, .5); }
        70%  { box-shadow: 0 0 0 20px rgba(214, 48, 48, 0); }
        100% { box-shadow: 0 0 0 0    rgba(214, 48, 48, 0); }
    }
}
.ccw-pin-label {
    position: absolute; top: -9px; white-space: nowrap;
    font: 700 13px/1.2 Arial, "Helvetica Neue", sans-serif; color: #1e2630;
    text-shadow: 0 0 3px #fff, 0 0 3px #fff, 0 1px 3px #fff;
}
.ccw-pin-label--right { left: 14px; }
.ccw-pin-label--left  { right: 14px; text-align: right; }

/* --- keep the tile attribution small + subtle --- */
.ccw_reach_map .leaflet-control-attribution {
    font-size: 10px !important; line-height: 1.4;
    background: rgba(255, 255, 255, .6); color: #7c8894;
}
.ccw_reach_map .leaflet-control-attribution a { color: #6a7684; }

/* --- FIX 4b (v1.5.2) — mobile map legibility. The 300px mobile map read as a
   postage stamp: the pins/halos are fixed-px so they looked huge relative to
   the tiny map, and the 10 labels crowded until their white halos overlapped
   into unreadable smudges (the label text itself is dark navy, not white).
   Fix: taller map, pins/halos/pulse/labels scaled down. The companion change
   in ccw-reach-map.js shrinks the fitBounds padding below 1000px — the 150px
   top padding only exists for the DESKTOP header tuck (FIX 8, >=1000px), on
   mobile it just squeezed Europe into the bottom half of the map.
   (This block sits after the base pin/label rules so it wins the cascade.) --- */
@media only screen and (max-width: 768px) {
    /* FIX 4c (v1.5.3): pins reduced a LOT (Fred) — tiny dots, hairline halo,
       10px labels so all ten cities read on a phone */
    .google_map.ccw_reach_map { height: 420px; min-height: 420px; }
    .ccw-pin {
        width: 7px; height: 7px; border-width: 1px;
        box-shadow: 0 0 0 2px rgba(0, 128, 196, .20);
    }
    .ccw-pin--l  { width: 9px; height: 9px; }
    .ccw-pin--xl { width: 12px; height: 12px; box-shadow: 0 0 0 2px rgba(214, 48, 48, .20); }
    .ccw-pin-label {
        top: -6px;
        font-size: 10px;
        font-weight: 600;
        text-shadow: 0 0 2px #fff, 0 1px 2px #fff;
    }
    .ccw-pin-label--right { left: 7px; }
    .ccw-pin-label--left  { right: 7px; }
}
@media only screen and (max-width: 768px) and (prefers-reduced-motion: no-preference) {
    /* pulse rings scaled to the smaller pins */
    .ccw-pin::after     { inset: -1px; animation-name: ccw-pin-pulse-sm; }
    .ccw-pin--xl::after { inset: -1px; animation-name: ccw-pin-pulse-red-sm; }
    @keyframes ccw-pin-pulse-sm {
        0%   { box-shadow: 0 0 0 0   rgba(0, 128, 196, .40); }
        70%  { box-shadow: 0 0 0 4px rgba(0, 128, 196, 0); }
        100% { box-shadow: 0 0 0 0   rgba(0, 128, 196, 0); }
    }
    @keyframes ccw-pin-pulse-red-sm {
        0%   { box-shadow: 0 0 0 0   rgba(214, 48, 48, .45); }
        70%  { box-shadow: 0 0 0 5px rgba(214, 48, 48, 0); }
        100% { box-shadow: 0 0 0 0   rgba(214, 48, 48, 0); }
    }
}

/* =======================================================================
   FIX 11 (v1.5.2) — Twitter bird -> X logo, site-wide.
   The parent bundles FontAwesome 4, which predates the X rebrand and has no
   X glyph. Blank the bird glyph and paint the official X mark as a
   currentColor SVG mask, so it follows each icon's own colour (grey header
   icons, dark contact-page circles, footer). Browsers without mask support
   would show nothing rather than a wrong bird — acceptable, mask is
   universal in evergreen browsers.
   ======================================================================= */
i.fa-twitter::before {
    content: "";
    display: inline-block;
    width: .85em; height: .85em;
    vertical-align: -.08em;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24h-6.657l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24h-6.657l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* =======================================================================
   FIX 5 — Footer columns centred.
   The footer widget row is a full-width "four_columns" block, but only three
   widgets are used (phones, Industry News, offices map), so they packed to the
   left with an empty quarter on the right. Centre the block to the site's
   1100px content width and let the three widgets share it evenly.
   ======================================================================= */
.footer_top_holder .four_columns {
    max-width: 1100px;
    margin-left: auto;
    margin-right: auto;
    float: none;
}
.footer_top_holder .four_columns .column3 { display: none; }   /* the empty slot (widgets live in 1, 2, 4) */
@media only screen and (min-width: 769px) {
    .footer_top_holder .four_columns .column1,
    .footer_top_holder .four_columns .column2,
    .footer_top_holder .four_columns .column4 {
        width: 33.3333%;
        box-sizing: border-box;
    }
}

/* =======================================================================
   FIX 6 — Trade Shows (Events) page hero banner, so it matches the other
   pages. Injected above the events list by ccw-events-banner.js; full-bleed
   even though it lives inside the content container. Same height band as the
   contact-page map banner. Photo: tech/photography expo floor, Unsplash
   (Unsplash Licence — free for commercial use, no attribution required).
   ======================================================================= */
.ccw-events-banner {
    position: relative;
    width: 100vw;
    margin-left: calc(50% - 50vw);   /* break out of the content container -> full-bleed */
    margin-bottom: 44px;
    height: 550px;                   /* uniform banner height, same as the Qode sliders (v1.5.0) */
    background: #20262e url('images/trade-shows-banner.jpg') center center / cover no-repeat;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    overflow: hidden;
}
.ccw-events-banner::before {
    content: '';
    position: absolute; inset: 0;
    background: rgba(18, 26, 36, .42);   /* legibility scrim */
}
.ccw-events-banner__inner { position: relative; z-index: 1; padding: 0 24px; max-width: 900px; }
.ccw-events-banner__title {
    color: #fff; margin: 0 0 8px; font-size: 38px; font-weight: 600;
    letter-spacing: .005em; text-shadow: 0 1px 14px rgba(0, 0, 0, .45);
}
.ccw-events-banner__sub {
    color: #eef2f5; margin: 0; font-size: 17px; line-height: 1.5;
    text-shadow: 0 1px 10px rgba(0, 0, 0, .5);
}
@media only screen and (max-width: 768px) {
    .ccw-events-banner { height: 280px; min-height: 280px; margin-bottom: 28px; }
    .ccw-events-banner__title { font-size: 26px; }
    .ccw-events-banner__sub { font-size: 15px; }
}

/* =======================================================================
   FIX 7 — Cap the site at 1920px on very wide screens.
   The Qode hero sliders are fluid-width but near-fixed-height, so beyond
   ~1850px the banner is a wider shape than the 1920x674 slider images and
   `cover` crops them vertically (at 2560 fullscreen the Home slide lost the
   whole river). Capping the page at 1920px keeps the banner within ~3% of
   the images' aspect at any monitor width; below 1921px nothing changes
   (mobile untouched). Gutters get a quiet grey + shadow so the boxed look
   reads as intentional.
   ======================================================================= */
@media only screen and (min-width: 1921px) {
    body { background: #e9ecef; }
    .wrapper {
        max-width: 1920px;
        margin-left: auto;
        margin-right: auto;
        background: #fff;
        box-shadow: 0 0 34px rgba(15, 20, 26, .18);
    }
    /* position:fixed is viewport-relative — the header must be capped too
       (left/right 0 + auto margins centre a fixed element of max-width) */
    header.page_header {
        max-width: 1920px;
        left: 0;
        right: 0;
        margin-left: auto;
        margin-right: auto;
    }
    /* the events banner full-bleeds via 100vw; clamp it to the capped page */
    .ccw-events-banner {
        width: 1920px;
        margin-left: calc(50% - 960px);
    }
    /* (v1.5.0: the carousel-inner pin that lived here is gone — FIX 9 makes
       the slider position:relative at every width, so it can no longer
       escape the wrapper cap.) */
    /* the "uncover" footer is position:fixed too (revealed on scroll) —
       cap and centre it like the header */
    footer.uncover {
        max-width: 1920px;
        left: 0;
        right: 0;
        margin-left: auto;
        margin-right: auto;
    }
}

/* Centre the slide crop (parent anchors it to the TOP: '50% 0'), so whatever
   sliver cover still crops comes off sky AND foreground evenly, not all off
   the bottom. Applies at every width; horizontally it was already centred. */
.q_slider .image { background-position: center center !important; }

/* =======================================================================
   FIX 8 — Contact + Trade Shows banners tuck under the transparent header,
   like the Qode slider pages (v1.5.0, Fred's request).
   Pages WITHOUT a Qode slider get `content_top_margin` from the parent
   (stylesheet.css:1538 -> margin-top:120px !important), which paints a white
   bar between the fixed transparent header and our injected banners. Remove
   it on exactly those two page types so the banner starts at y=0 behind the
   header — the same geometry as Home/About/Services. Desktop only: below
   1000px the theme switches to the mobile header and the margin is load-
   bearing there.
   The Leaflet map is nearly white, so the white "light" menu text needs a
   scrim: a top gradient dark enough for legibility, above the map panes
   (z 400s) but below its controls/attribution (z 1000). The events banner
   already carries a full scrim.
   ======================================================================= */
@media only screen and (min-width: 1000px) {
    body.page-template-contact-page .content.content_top_margin,
    body.post-type-archive-tribe_events .content.content_top_margin,
    body.tax-tribe_events_cat .content.content_top_margin {
        margin-top: 0 !important;
    }
    .ccw_reach_map::after {
        content: '';
        position: absolute;
        top: 0; left: 0; right: 0;
        height: 150px;
        background: linear-gradient(to bottom, rgba(18, 26, 36, .55), rgba(18, 26, 36, 0));
        z-index: 800;
        pointer-events: none;
    }
    /* keep the banner text optically centred in the band below the header */
    .ccw-events-banner__inner { padding-top: 70px; }
}

/* =======================================================================
   FIX 9 — Hero banners scroll IN-FLOW on every page (v1.5.0, Fred's request).
   The parent pins `.carousel-inner` position:fixed on desktop
   (stylesheet.css:10601) and skrollr parallaxes it, so page content slid
   OVER a pinned banner (most visible on About/Services). Mobile (≤1024px)
   already reverts it to relative. Make it relative everywhere: all five
   banners now scroll away with the page, matching the Trade Shows banner
   and the Contact map. !important also beats skrollr's inline transforms.
   ======================================================================= */
.q_slider .carousel-inner {
    position: relative !important;
    transform: none !important;
    left: 0 !important;
}

/* Belt for the About video slide: if the element the theme sizes ends up a
   different shape than the film, crop like a background instead of
   letterboxing. (Primary fix: js/ccw-video-dims.js corrects the theme's
   hardcoded 1280x720 sizing globals to the real 1920x550 film.) */
.q_slider .item video {
    object-fit: cover;
    object-position: center center;
}

/* =======================================================================
   FIX 10 — Compact bottom-of-page (v1.5.1, Fred's request).
   (a) The "How can we be of Assistance?" call-to-action sits in a WPBakery
       row carrying padding 40/31, the CTA box adds 28px more and a large H2 —
       together a tall band for one line + a button. Tighten all three.
   (b) The footer widget band: 48px paddings, a 145px-tall offices map and
       roomy type made the footer ~350px — on Contact it cropped on the
       initial viewport. Tighten paddings/typography, shrink the map.
   (c) The copyright bar: 60px -> 38px.
   (d) .ccw-offices — the tidy phone list markup now in the footer text
       widget (the old version aligned columns with strings of &nbsp; and
       mis-grouped the numbers). City left, number right, every number a
       tel: link with a comfortable tap target (larger padding on touch
       widths so nobody fat-fingers the wrong office).
   ======================================================================= */
/* v1.5.8 retune (Fred): 14px bottom hugged the footer; give the band air
   below and keep it tight above. The :has() rule overrides each page's
   inline row paddings (122/142/98px), so all three CTA pages are uniform
   by construction. */
.section:has(> .section_inner .call_to_action) {
    padding-top: 18px !important;
    padding-bottom: 48px !important;
}
.call_to_action.normal { padding: 12px 21px !important; }
.call_to_action .call_to_action_text h2 {
    font-size: 22px;
    line-height: 32px;
}

.footer_top_holder .footer_top { padding: 26px 24px 20px !important; }
.footer_top_holder h4,
.footer_top_holder h5,
.footer_top_holder h6,
.footer_top_holder .widget_title {
    font-size: 14px;
    line-height: 1.4;
    margin: 0 0 10px;
}
.footer_top_holder .footer_map {
    /* v1.5.9 (Fred): 110px read as too small next to the offices list and
       the news widget — up to 170px. The PNG ships at 2x (502x290) since
       2026-07-13, so this displays crisp (and retina-sharp). */
    max-height: 170px;
    width: auto;
}
.footer_top_holder .widget { margin-bottom: 0; }

.footer_bottom_holder,
.footer_bottom_holder .footer_bottom {
    height: 38px !important;
    line-height: 38px !important;
}
.footer_bottom_holder span { font-size: 11px; }

.footer_top_holder .ccw-offices {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    max-width: 240px;
}
.footer_top_holder .ccw-offices li {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 2px 0;
    font-size: 13px;
    line-height: 1.55;
}
.footer_top_holder .ccw-offices li span { font-weight: 600; }
.footer_top_holder .ccw-offices li a {
    color: inherit;
    white-space: nowrap;
    display: inline-block;
    padding: 1px 0;
    text-decoration: none;
}
.footer_top_holder .ccw-offices li a:hover { text-decoration: underline; }
@media only screen and (max-width: 768px) {
    /* touch: taller rows so a tap can't land on the neighbouring number
       (v1.5.3: 9px -> 6px per Fred — a touch tighter, still tap-safe:
       ~32px row height clears the 24px minimum tap-target guidance) */
    .footer_top_holder .ccw-offices { max-width: 300px; margin-left: auto; margin-right: auto; }
    .footer_top_holder .ccw-offices li { padding: 6px 0; font-size: 15px; }

    /* FIX 14 (v1.5.3): the "Our Worldwide Offices" map sat off to the right
       on stacked mobile columns — centre it (and never overflow) */
    .footer_top_holder .footer_map {
        display: block;
        float: none;
        margin: 0 auto;
        max-width: 100%;
    }
}

/* =======================================================================
   FIX 13 (v1.5.3) — mobile hamburger was imperceptible: the parent paints
   the three-lines glyph #777 on the solid #212121 mobile header. White +
   a slightly larger glyph. (The button only displays at mobile widths, so
   no desktop effect; covers the .dark variant too.)
   ======================================================================= */
.mobile_menu_button span,
.dark .mobile_menu_button span {
    color: #fff !important;
    font-size: 17px;
}

/* FIX 13b (v1.5.4): same invisibility up in the header-top bar on mobile —
   the social icons carry an inline color:#777777 (shortcode attr) and the
   "Contact us" phone widget inherits a dark grey, both on the #212121 bar.
   !important beats the inline style. Mobile widths only (the parent swaps
   to the mobile header at 1000px); desktop stays as designed. */
@media only screen and (max-width: 1000px) {
    .header_top .q_social_icon_holder .simple_social,
    .header_top a,
    .header_top span {
        color: #fff !important;
    }
}

/* FIX 13c (v1.5.6): 13b did NOT win for the social icons — the parent's
   responsive.css re-greys them at <=1000px with its own !important rule at
   HIGHER specificity: `.light .header_top .q_social_icon_holder
   i.simple_social => #777 !important` (0,4,1) vs 13b's (0,3,0). The phone
   span looked fixed only because its competing parent rule lacks !important.
   Repeat the class to (0,5,1) so this beats both the .light and .dark
   variants regardless of stylesheet enqueue order. */
@media only screen and (max-width: 1000px) {
    .header_top .q_social_icon_holder i.simple_social.simple_social.simple_social {
        color: #fff !important;
    }
}

/* FIX 16 (v1.5.7): Home cover boxes usable on mobile. The parent's
   accordion is hover-driven (default.js mouseenter swaps li.act 265->530px)
   and its phone breakpoints break it: <=768px keeps .box_content absolutely
   positioned beside a fixed-width thumb inside an overflow:hidden li (text
   clipped off-screen), and <=480px sets .box_content { display:none } —
   image-only mute links. Restyle as stacked cards at <=768px: the natural
   270px thumb centred (natives are 270x152 — no upscale blur), text +
   button statically below. Widths use !important because the parent's own
   768 block already !importants li widths. */
@media only screen and (max-width: 768px) {
    .cover_boxes ul {
        width: 100% !important;
        margin: 0 !important;
    }
    .cover_boxes ul li,
    .cover_boxes ul li.act,
    .cover_boxes ul li .box {
        width: 100% !important;
        margin: 0 0 30px !important;
    }
    .cover_boxes ul li .box .thumb {
        float: none !important;
        display: block !important;
        width: 270px !important;
        max-width: 100%;
        margin: 0 auto !important;
    }
    .cover_boxes ul li .box .box_content {
        display: block !important;
        position: static !important;
        padding: 14px 0 0 !important;
        width: 100% !important;
        text-align: center;
    }
    .cover_boxes ul li .box .box_content p {
        max-height: none !important;
        overflow: visible !important;
    }
    .cover_boxes ul li .box .qbutton {
        margin: 12px 0 0 !important;
    }
}

/* FIX 17 (v1.5.8): spacing polish pass (Fred, 2026-07-13).
   (a) The Home parallax slogan renders as two adjacent .custom_font_holder
       spans (45px/55px) with zero gap — open them up.
   (b) The full-width testimonials band: parent gives .testimonial_text_inner
       46px/75px paddings + 50px margin, and .slides another 25px — ~150px of
       empty space under a one-line quote. Compact it (same-specificity
       selectors, child loads later; !important belts the paddings).
   (c) About: the counters parallax and the testimonials sat flush — add a
       40px breather. The adjacency + :has() scoping fires ONLY where a
       testimonials section directly follows a parallax (About today). */
.parallax_section_holder .custom_font_holder {
    display: block;
}
.parallax_section_holder .custom_font_holder + .custom_font_holder {
    margin-top: 16px;
}

.testimonials_holder.full_width .testimonials .testimonial_text_inner {
    padding: 30px 0 34px !important;
    margin: 0 0 18px !important;
    font-size: 17px;
}
.testimonials .slides {
    margin-bottom: 12px;
}
.testimonials .testimonial_container {
    margin: 0 0 10px;
}

section.parallax_section_holder + .section:has(.testimonials_holder) {
    margin-top: 40px;
}

/* =======================================================================
   FIX 18 (v1.6.0) — desktop CLS 1.0: the "uncover" footer.
   The parent fixes footer.uncover to the viewport bottom from first paint
   (stylesheet.css:8125) and setContentBottomMargin() (default.js:2590) then
   gives .content a footer-height margin-bottom so the page can scroll past
   it. The footer therefore sits INSIDE the viewport the whole load, and its
   rect moves/grows as the widgets (offices list, map, news) render — PSI's
   desktop layout-shift attribution named footer.uncover at exactly 1.000
   (mobile is 0 only because the effect doesn't bite there). Same family as
   FIX 9: put it in flow. In-flow, the footer sits below the fold at load,
   so its rendering can no longer shift anything visible. The JS inline
   margin-bottom loses to !important.
   ======================================================================= */
footer.uncover {
    position: relative !important;
    bottom: auto !important;
    left: auto !important;
}
.content {
    margin-bottom: 0 !important;
}

/* Size reserves for the two images PSI flags as unsized (secondary CLS
   culprits). The footer map is a fixed 502x290 asset shown 170px tall —
   give it a definite box so nothing moves when it loads. The five Home
   circle images are all 180x180 — reserve them square. */
img.footer_map {
    height: 170px;
    width: auto;
    aspect-ratio: 502 / 290;
}
.q_circle_outer img.q_image_in_circle {
    aspect-ratio: 1 / 1;
}

/* =======================================================================
   FIX 20 (v1.7.0) — Phase-6 "Industry News": CSS-only rotation.
   The widget (functions.php CCW_News_Widget) puts every approved item in
   the DOM; this rotates them with a keyframe cross-fade — no JS (the whole
   point of retiring the jQuery ticker), and the list's height is RESERVED
   (min-height fits the tallest item) so the footer contributes zero CLS
   (FIX 18's hard-won property). Each li carries an inline
   animation-delay of i*8s from PHP; the keyframe set below matches the
   item count via .ccw-news-count-N (3..5). 8s per item, ~1s fades.
   Hover pauses; prefers-reduced-motion shows item 1 statically.
   ======================================================================= */
.ccw-news {
    position: relative;
    margin: 0;
    padding: 0;
    list-style: none;
    min-height: 10em;   /* reserve: tallest item must fit — verify rendered */
}
.ccw-news-item {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    margin: 0;
    opacity: 0;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}
.ccw-news-count-3 .ccw-news-item { animation-name: ccw-news-fade-3; animation-duration: 24s; }
.ccw-news-count-4 .ccw-news-item { animation-name: ccw-news-fade-4; animation-duration: 32s; }
.ccw-news-count-5 .ccw-news-item { animation-name: ccw-news-fade-5; animation-duration: 40s; }
/* visible slice = 100/N %, ~1s fade at each edge of the slice */
@keyframes ccw-news-fade-3 { 0% {opacity:0} 4% {opacity:1} 29.3% {opacity:1} 33.3% {opacity:0} 100% {opacity:0} }
@keyframes ccw-news-fade-4 { 0% {opacity:0} 3% {opacity:1} 22%   {opacity:1} 25%   {opacity:0} 100% {opacity:0} }
@keyframes ccw-news-fade-5 { 0% {opacity:0} 2.5% {opacity:1} 17.5% {opacity:1} 20% {opacity:0} 100% {opacity:0} }
.ccw-news:hover .ccw-news-item {
    animation-play-state: paused;
}
.ccw-news-title {
    display: block;
    font-weight: 600;
    margin-bottom: 4px;
}
.ccw-news-body {
    display: block;
    line-height: 1.6;
}
@media (prefers-reduced-motion: reduce) {
    .ccw-news-item { animation: none; }
    .ccw-news-item:first-child { opacity: 1; }
    .ccw-news-item:not(:first-child) { display: none; }
}

/* =======================================================================
   FIX 21 (v1.7.1, reworked v1.7.2) — Home client-logo strip: slow BOUNCE
   marquee. js/ccw-logo-conveyor.js swaps the FlexSlider-initialised
   carousel for its pristine markup and animates the track with the Web
   Animations API (alternate direction, ~45px/s, hover pauses). The CSS
   below lays the bare markup out as a single flex row: the parent hides
   un-FlexSlidered items (`.qode_carousels .slides>li { display:none }`,
   stylesheet.css:11355) and normally sizes them with inline styles — the
   marquee needs them visible at the same 220px + 2px gap the old init
   used. Parent `.slides img { width:100% }` keeps the logo scale.
   ======================================================================= */
.qode_carousels {
    overflow: hidden;
}
.qode_carousels ul.slides {
    display: flex;
    align-items: center;
    margin: 0;
    padding: 0;
    list-style: none;
    will-change: transform;
}
.qode_carousels .slides > li {
    display: block;
    flex: 0 0 auto;
    width: 220px;
}

/* FIX 20 refinements (v1.7.1/2, Fred's staging eyeballs):
   1. Item titles in a lighter grey than the footer body text — they read
      as headings between the white h4 and the darker body.
   2. Items sit a touch lower under the heading — 6px extra, which puts a
      typical item's last line level with the Lisbon row of the offices
      list alongside. (v1.7.1 tried bottom-aligning via a flex footer row:
      the column floor is set by the TALLEST column, not the phone list,
      and the text landed far too low — reverted.) */
.ccw-news-title,
.ccw-news-item a .ccw-news-title {
    color: #b0b0b0;
}
ul.ccw-news {
    margin-top: 6px;
}
