/**
 * Theme Name:     Organify Child
 * Author:         Case-Themes / Xcado
 * Template:       organify
 * Text Domain:    organify-child
 * Description:    Premium speed-optimised child theme for xcado.africa — v3.0.9
 * Version:        3.0.9
 */

/* ═══════════════════════════════════════════════════════
   CHANGELOG

   3.0.9 — removes the 3.0.8 split-text safety net now that the real cause
   is fixed at the source. The actual bug was in the parent Organify theme's
   own JS (elements/assets/js/elementor.js, function organify_split_text()):
   its scroll-triggered letter reveal used
   `toggleActions: "restart pause resume reverse"` with no `once` guard,
   which could interrupt the reveal tween mid-stagger and leave it stuck.
   That's been patched directly in the parent theme file (swapped the
   toggleActions line for `once: true`, so the reveal plays exactly once
   and can never be reversed/interrupted) and confirmed working on staging
   (xcado.africa/stage) -- all three tested headings ("East Africa's Finest
   Produce Delivered Globally.", "Our Organic Products", "A Reputable
   Company Offering Organic Food Options.") now render their full text.

   Keeping the 3.0.8 CSS override in place alongside that JS fix would be
   actively counterproductive, not just redundant: forcing every split-text
   letter to `opacity: 1 !important` makes the text appear instantly, before
   the JS animation ever gets to run, which kills the fly-in effect the JS
   fix just restored. So this version removes that override entirely and
   relies on the JS fix as the real, permanent solution -- which also means
   this style.css no longer masks a regression here if the JS fix is ever
   accidentally reverted (a future parent-theme update, for instance): if
   that happens, headings going blank again would be visible immediately
   rather than silently caught by CSS, which is the right failure mode to
   notice and re-fix at the source rather than paper over a second time.

   IMPORTANT DEPLOYMENT ORDER: only install this style.css on production
   AFTER the patched elementor.js is live there. Installing this first,
   before the JS fix, would bring back the original bug (missing heading
   text) on production with nothing left to mask it.

   3.0.8 — fix: every homepage heading using the parent theme's letter-by-
   letter reveal animation (`.pxl-split-text`, used by the "split-in-right"
   effect) was stuck showing only a small fraction of its own letters --
   confirmed live on xcado.africa across ALL SEVEN instances of this effect
   on the homepage, not just the "About Us" one reported: "East Africa's
   Finest Produce Delivered Globally." (7 of 50 letters visible), "Our
   Organic Products" (4/22), "A Reputable Company Offering Organic Food
   Options." (8/52), "Our Awesome Team Member" (3/25), "What Our Clients
   Say About Us" (7/31), "Take a Look at Our Latest Blog & Articles."
   (10/44), and the newsletter heading (11/68). Root cause is NOT in this
   child theme, NOT in functions.php, and NOT the Speed Kit plugin (its
   Combine module is currently inactive on this page -- no xsk-scripts-*
   bundle is even being served -- and every script that builds this
   animation, organify/assets/js/libs/{gsap,scroll-trigger,split-text}.js
   and organify/assets/js/theme.js, loads individually and returns HTTP
   200 with no console errors). It's the parent Organify theme's own GSAP
   ScrollTrigger setup for this effect: each heading gets split into
   individual-letter <div>s that start at `opacity:0` (inline style,
   intentional -- that's the "before" state of the reveal), and a
   scroll-linked timeline is supposed to animate each one to `opacity:1`.
   Confirmed live that this timeline is not completing correctly for any
   of the 7 instances -- calling `ScrollTrigger.refresh()` did not fix it,
   ruling out a simple stale-layout-position cause, and this held across
   every instance, in and out of the viewport, so it isn't one broken
   widget instance. Because the letters' hidden state is a plain inline
   `opacity:0`, a broken or never-firing timeline leaves that heading's
   text permanently invisible rather than just un-animated -- on
   "East Africa's Finest Produce Delivered Globally.", the specific
   sentence reported missing, only stray fragments of a couple of early
   letters were ever visible.

   This is a JavaScript animation bug in the parent theme, so it can't be
   fixed from this CSS file -- fixing the actual GSAP/ScrollTrigger timeline
   requires organify/assets/js/theme.js (and/or split-text.js), which is
   parent-theme code this child theme doesn't include and this session
   doesn't have a copy of. What CAN be done from here, safely and
   reversibly, is a CSS safety net: force every split-text letter to its
   final, fully-visible state unconditionally, so the heading text is
   always readable regardless of whether the JS timeline ever runs. This
   trades away the fly-in-per-letter animation (headings now simply appear
   already-visible, the same effect the existing `prefers-reduced-motion`
   block below already gives motion-sensitive visitors) in exchange for
   guaranteeing no heading is ever silently blank. Verified live: patching
   this exact rule into the page's CSSOM took every one of the 7 instances
   from a handful of visible letters to 100% (50/50, 22/22, 52/52, 25/25,
   31/31, 44/44, 68/68), confirmed both by script and by screenshot of the
   About Us section showing the full "East Africa's Finest Produce
   Delivered Globally." line. See the rule at the end of this file.

   3.0.7 — fix: the blanket `p, li, span, td { font-family: var(--font-sans)
   !important; ... }` rule (added in an update this session didn't make --
   see note below) was silently breaking every icon rendered through a bare
   <span> tag: Font Awesome (used by the Sign Up / Login form's username,
   password, email and eye-toggle icons), Elementor's eicons, this theme's
   flaticon/caseicon sets, and Material Icons all work by pointing a plain
   <span> or <i> at their own icon font via ordinary, non-!important CSS
   (e.g. Font Awesome ships `.fa, .far, .fas { font-family: "Font Awesome 5
   Free"; }` with no !important at all, relying on class-selector
   specificity alone). A same-or-lower-specificity rule carrying !important
   always beats that regardless of how specific the other selector is, so
   forcing every <span> to Poppins didn't just make icons render in the
   wrong font -- Poppins has no glyph at the private-use codepoint Font
   Awesome's CSS requests (e.g. content:"\f234" for the username icon), so
   the browser fell back to a visible empty-box glyph. Confirmed live
   (xcado.africa/my-account/): the icon span's computed font-family was
   "Poppins" instead of "Font Awesome 5 Free", while the underlying
   content:"\f234" declaration itself was intact and unaffected -- this was
   a font-family collision, not a missing icon font file (Font Awesome's
   CSS and .woff2 files all loaded fine over the network). Fix: narrowed
   the selector to exclude any span whose class contains "icon" or "fa-",
   which covers every icon-font convention in use on this site without
   hardcoding brittle exact class names. No property values changed.

   NOTE ON SCOPE: this file was already at 3.0.6 on the live site when this
   fix was made -- a 3.0.6 changelog entry (below) documents a functions.php
   change (item 14, the asset-version stripper) that this session did not
   make. That functions.php change is NOT included here: this update was
   pulled directly from the live site's current style.css and should be
   installed as a style.css-only replacement, not as a full theme-folder
   overwrite, so it doesn't revert whatever functions.php currently has.

   3.0.6 — fix: functions.php's version-string stripper (item 14,
   "Remove version strings from asset URLs") was undermining XCADO
   Speed Kit's Cache module rather than helping it. That stripper
   predates Speed Kit's Cache module entirely -- it was written back
   when nothing on this site gave static assets a long-lived
   Cache-Control header, so removing ?ver= just meant one fewer query
   string to vary on. Once Speed Kit's Cache module started sending
   long max-age (and optionally immutable) headers for every CSS/JS
   asset site-wide, by file extension, this function kept stripping
   the ?ver= query arg that is the ONLY thing telling a browser (or an
   immutable cache) that a file changed -- exactly the failure mode
   Speed Kit's own README documents in its 2.3.0 changelog entry for a
   theme stylesheet enqueued with no version string, except this
   function was actively manufacturing that bug for every core script
   and every other plugin's asset on the site, not just one theme
   file. See functions.php's own updated comment on item 14 for the
   full reasoning; this changelog entry exists so the CSS file's own
   version history doesn't go silent on a change that only touches
   functions.php. Fix: xcado_strip_ver() now checks whether Speed
   Kit's Cache module is actually turned on (XSK_Settings::get(
   'cache_enabled' )) and stands down entirely when it is, leaving
   ?ver= alone for Speed Kit's own asset auto-versioning module to
   manage correctly (it rewrites this theme's ?ver= to the file's real
   on-disk modified time, rather than removing it).

   3.0.5 — fix: Elementor heading/typography overrides (H1-H6, and
   several component titles built from heading tags) were silently
   ignored across the whole site, most visibly on the homepage H2/H3s.
   Nine separate CSS rules pinned font-size/font-weight/color/etc.
   with `!important` on selectors that either were, or shared
   specificity with, live heading tags: the bare h1-h6 defaults, the
   combined heading-default rule, the hero-slider heading rule, the
   mobile-breakpoint h1-h3 duplicate, WooCommerce's own h2 product
   title, the team-member h3/h4 name rule, the testimonial-author h5
   rule, the blog post-title h3 rule, and the footer widget h3/h4
   rule. `!important` beats CSS specificity AND Elementor's inline
   `style="..."` output regardless of how specific Elementor's own
   generated selector is, so every one of these structurally could
   not be overridden from the Elementor editor no matter what was set
   there -- the value would save, and the live page would keep
   showing the old size/weight/color anyway. All nine had
   `!important` removed; none of the actual values changed, and every
   one still wins its normal cascade position (verified: each was
   already at least as specific as the bare heading defaults it needs
   to beat). See the comment left at each fixed rule for the specific
   reasoning.

   3.0.5 — fix: the site's ENTIRE heading typeface (Montserrat, vs.
   Poppins for body copy) depended on one inline <script> in
   functions.php creating a <link> to Google Fonts at runtime. That
   workaround existed to dodge a WP-Optimize bug that combined and
   corrupted Google Fonts URLs -- but this site runs XCADO Speed Kit
   now, not WP-Optimize, and Speed Kit's Combine/font-merge modules
   structurally cannot touch a cross-origin fonts.googleapis.com
   request either way (verified against Speed Kit's own source: both
   XSK_Combine and XSK_Fonts::merge_google_fonts() only ever act on
   same-origin files or stylesheets registered via wp_enqueue_style(),
   and this loader was neither). So the workaround was pure downside:
   every visitor's headings depended on that one script executing,
   with no <noscript> fallback, and the two fallback faces declared
   in xcado_critical_css() (`Poppins Fallback` / `Montserrat
   Fallback`) both point at the exact same local font
   (`src:local('Arial')`), so any failure of that script made every
   heading on the site visually indistinguishable from body text
   except for boldness -- exactly the symptom reported ("About Us" /
   "Our Products" section headings not reflecting the heading font).
   Replaced with a real, static <link>, loaded via the standard
   preload + media=print/onload "loadCSS" pattern so it still doesn't
   block render, plus a <noscript> fallback for when JavaScript never
   runs at all. See xcado_load_fonts() in functions.php.

   Also hardened (NOT a confirmed fix, defensive only): the scroll-
   reveal IntersectionObserver in functions.php set every
   `.elementor-widget` (headings included) to `opacity:0` until the
   observer marked it visible, with no timeout fallback -- unlike this
   theme's own preloader, which already force-closes after 4s. Added
   a matching 2s force-reveal fallback so a missed observer callback
   degrades to "no fade-in" instead of "permanently invisible
   content." This is plausible but unconfirmed as a contributor to
   the reported symptom; the `!important` overrides above are the
   confirmed, structural cause.
   ═══════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════
   1.  DESIGN TOKENS
   2.  TYPOGRAPHY
   3.  ANIMATIONS & TRANSITIONS
   4.  HEADER & NAVIGATION
   5.  HERO / SLIDER
   6.  BUTTONS
   7.  PRODUCT CARDS
   8.  SECTION TITLES & EYEBROWS
   9.  ABOUT SECTION
   10. WHY CHOOSE US
   11. TEAM
   12. TESTIMONIALS
   13. PARTNERS / LOGOS
   14. BLOG CARDS
   15. FOOTER
   16. WOOCOMMERCE
   17. FORMS & INPUTS
   18. UTILITY
   19. RESPONSIVE
   ═══════════════════════════════════════════════════════ */

/* ─── 1. DESIGN TOKENS ───────────────────────────────── */

:root {
    --c-green:       #2d6a4f;
    --c-green-mid:   #40916c;
    --c-green-light: #74c69d;
    --c-green-pale:  #d8f3dc;
    --c-gold:        #b5884c;
    --c-gold-light:  #e9c46a;
    --c-cream:       #faf8f4;
    --c-dark:        #0e1a0f;
    --c-text:        #2c2c2c;
    --c-muted:       #6b7280;
    --c-border:      rgba(0,0,0,0.07);
    --c-white:       #ffffff;

    --font-heading:  'Montserrat', 'Montserrat Fallback', 'Helvetica Neue', Arial, sans-serif;
    --font-sans:     'Poppins', 'Poppins Fallback', system-ui, -apple-system, sans-serif;

    --ease-expo:     cubic-bezier(0.16, 1, 0.3, 1);
    --ease-smooth:   cubic-bezier(0.4, 0, 0.2, 1);

    --radius-sm:     4px;
    --radius-md:     10px;
    --radius-lg:     18px;
    --radius-pill:   999px;

    --shadow-xs:     0 1px 3px rgba(0,0,0,0.06);
    --shadow-sm:     0 2px 8px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.04);
    --shadow-md:     0 8px 24px rgba(0,0,0,0.10), 0 2px 8px rgba(0,0,0,0.06);
    --shadow-lg:     0 20px 56px rgba(0,0,0,0.12), 0 6px 20px rgba(0,0,0,0.07);
    --shadow-green:  0 8px 30px rgba(45,106,79,0.28);
}

/* ─── 2. TYPOGRAPHY ──────────────────────────────────── */

body {
    font-family: var(--font-sans);
    font-size: 1rem;
    line-height: 1.72;
    color: var(--c-text);
    background: var(--c-white);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* Brand default for every heading, including Elementor's own heading
   widget -- no !important (removed in 3.0.5, same reasoning as the h1-h6
   size rules below): a page-specific Elementor typography/color choice on
   an individual widget is already more specific than this selector list
   and will correctly win where one is actually set, while every heading
   left on "default" in Elementor still inherits this exactly as before. */
h1, h2, h3, h4, h5, h6,
.elementor-heading-title,
.woocommerce-loop-product__title,
.entry-title,
.pxl-section-title {
    font-family: var(--font-heading);
    line-height: 1.18;
    letter-spacing: -0.015em;
    color: var(--c-dark);
}

/* Fixed px, matching the Theme Options -> Typography admin panel exactly.
   Redux's Typography module doesn't support fluid clamp() sizing, so these
   are pinned to the same desktop values entered there (H1 64/75, H2 48/57)
   as the site-wide DEFAULT for any heading Elementor hasn't been told to
   size individually.
   No !important here on purpose (removed in 3.0.5): these are bare h1-h6
   tag selectors, the lowest specificity a rule can have, so anything more
   specific -- including every per-widget typography choice Elementor
   applies, which always lands on a page/element-scoped class, e.g.
   `.elementor-1234 .elementor-element-eae5678 .elementor-heading-title`
   -- already wins the cascade without needing !important's help. Carrying
   !important here didn't just future-proof consistency the way it looks
   like it should; it made every such Elementor override structurally
   impossible to win, `!important` beats a plain selector regardless of
   specificity, and beats Elementor's own inline `style="font-size:...px"`
   output too. That's the exact bug behind "I changed the heading size in
   Elementor and nothing happened" on the homepage -- the value visibly
   saved in the editor, and then this rule silently overrode it on the
   live page every time, for every H2/H3 on the site, not just one. */
h1 { font-size: 64px; font-weight: 600; }
h2 { font-size: 48px; font-weight: 500; }
h3 { font-size: 32px; font-weight: 600; }
h4 { font-size: 24px; font-weight: 600; }
h5 { font-size: 18px; font-weight: 600; line-height: 1.3; }
h6 { font-size: 15px; font-weight: 600; line-height: 1.3; text-transform: uppercase; }

/* 3.0.7 fix: excludes icon-font spans (Font Awesome, Elementor eicons,
   flaticon, caseicon, Material Icons, and this site's login/signup-form
   icon spans) from the blanket font-family override below. Those icon
   libraries render their glyphs by pointing a bare <span> or <i> at their
   own icon font via ordinary, non-!important CSS (Font Awesome's own CSS
   ships `.fa, .far, .fas { font-family: "Font Awesome 5 Free"; }` with NO
   !important, relying on class-selector specificity alone, which a
   same-or-lower-specificity !important rule always beats regardless of
   selector complexity). Forcing every <span> on the site to Poppins meant
   the icon's underlying content, e.g. Font Awesome's `content:"\f234"` for
   the username icon, was still being requested correctly -- confirmed
   intact and unaffected -- but the browser rendered that private-use
   codepoint in Poppins instead of the icon font, which has no glyph
   there, so it fell back to a visible missing-character box. Confirmed
   live on xcado.africa/my-account/: the icon span's computed font-family
   was "Poppins", not "Font Awesome 5 Free". The exclusion below covers
   every icon-font convention actually in use on this site (fa/fas/far/fab
   + fa-* glyph classes, eicon, flaticon, caseicon, material-icons, and the
   login form's xoo-aff-input-icon) without hardcoding brittle exact class
   names -- anything with "icon" or "fa-" anywhere in its class list falls
   through to its own icon font's rule instead of being forced to Poppins.
   No property values changed. */
p, li, td,
span:not([class*="icon"]):not([class*="fa-"]) {
    font-family: var(--font-sans) !important;
    font-size: 1rem;
    line-height: 1.75;
    color: #484848;
}

/* This Elementor site has years of mixed demo-import content where nearly
   every widget carries its own hardcoded font-family (Inter, Rowan Variable,
   Roboto, Poppins, ...) via highly-specific per-page inline CSS. Those beat
   the plain "p, li, span, td" rule above on specificity even without
   !important, which is why prices/labels/list text drifted off the site's
   two intended fonts (Montserrat for headings, Poppins for
   everything else). Force the known offenders back in line explicitly. */
div.pxl-content,
.woocommerce-product--price,
.woocommerce-product-header a,
.woocommerce-product-category,
.price,
.pxl-top-bar,
[class*="announcement"] {
    font-family: var(--font-sans) !important;
}

a {
    color: var(--c-green);
    text-decoration: none;
    transition: color 0.18s var(--ease-smooth);
}
a:hover { color: var(--c-green-mid); }

::selection {
    background: var(--c-green-pale);
    color: var(--c-green);
}

/* ─── 3. ANIMATIONS & TRANSITIONS ───────────────────── */

/* Scroll reveal */
.xcado-reveal {
    opacity: 0;
    transform: translateY(12px);
    transition:
        opacity  0.32s var(--ease-expo),
        transform 0.32s var(--ease-expo);
}
.xcado-reveal.xcado-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Lazy image fade-in — prevents jarring pop-in */
img {
    transition: opacity 0.35s ease;
}
img[loading="lazy"] {
    opacity: 0;
}
img[loading="lazy"].xcado-img-loaded,
img:not([loading]) {
    opacity: 1;
}

/* Header hide/show on scroll */
.pxl-header-main,
.site-header,
header {
    transition:
        transform    0.38s var(--ease-expo),
        box-shadow   0.38s var(--ease-expo),
        background   0.38s var(--ease-expo);
}
.xcado-hidden {
    transform: translateY(-100%) !important;
}
.xcado-shown {
    transform: translateY(0) !important;
}

/* Custom scrollbar */
::-webkit-scrollbar         { width: 6px; }
::-webkit-scrollbar-track   { background: #f0efeb; border-radius: 10px; }
::-webkit-scrollbar-thumb   { background: #b5c9bb; border-radius: 50px; }
::-webkit-scrollbar-thumb:hover { background: var(--c-green); }

/* ─── 4. HEADER & NAVIGATION ─────────────────────────── */

/* Frosted glass on scroll — premium effect */
.xcado-scrolled .pxl-header-main,
.pxl-header-main.xcado-scrolled,
.site-header.xcado-scrolled,
header.xcado-scrolled {
    background: rgba(255,255,255,0.95) !important;
    backdrop-filter: blur(14px) !important;
    -webkit-backdrop-filter: blur(14px) !important;
    box-shadow: 0 2px 28px rgba(0,0,0,0.07) !important;
}

/* Nav links — animated underline */
.pxl-header-main .menu-item a,
.pxl-main-nav .menu-item > a,
.main-navigation a,
.nav-menu > li > a {
    font-family: var(--font-sans) !important;
    font-size: 0.82rem !important;
    font-weight: 500 !important;
    letter-spacing: 0.05em !important;
    text-transform: uppercase !important;
    color: var(--c-dark) !important;
    position: relative;
    padding-bottom: 3px;
    transition: color 0.18s ease !important;
}

.pxl-header-main .menu-item a::after,
.pxl-main-nav .menu-item > a::after,
.main-navigation a::after {
    content: '';
    position: absolute;
    bottom: -2px;
    left: 0;
    width: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--c-green), var(--c-gold));
    border-radius: var(--radius-pill);
    transition: width 0.32s var(--ease-expo);
}

.pxl-header-main .menu-item a:hover::after,
.pxl-main-nav .menu-item > a:hover::after,
.pxl-header-main .current-menu-item > a::after {
    width: 100%;
}

/* ─── 5. HERO / SLIDER ───────────────────────────────── */

.pxl-slider-wrap,
.elementor-widget-pxl_slider,
[class*="hero-section"] {
    position: relative;
    overflow: hidden;
}

/* Hero headlines. No !important (removed in 3.0.5) -- same bug as the
   h1-h6 rules above, just easier to miss here: this selector is MORE
   specific than a bare "h2", so on the homepage hero specifically, this
   was the rule actually winning (and blocking Elementor) even after the
   general h1-h6 !important was removed. A per-slide Elementor typography
   override on a hero heading still needs a more specific selector than
   this to win, which every per-widget Elementor style already is. */
[class*="slide"] h1,
[class*="slide"] h2,
.pxl-slide-title {
    font-family: var(--font-heading);
    font-size: clamp(2.4rem, 6vw, 5.5rem);
    font-weight: 700;
    line-height: 1.08;
    letter-spacing: -0.02em;
    text-shadow: 0 2px 24px rgba(0,0,0,0.18);
}

/* ─── 6. BUTTONS ─────────────────────────────────────── */

.btn,
.pxl-button .btn,
.button:not(.menu-toggle),
button:not([class*="slick"]),
input[type="submit"],
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button {
    font-family: var(--font-sans) !important;
    font-size: 0.8rem !important;
    font-weight: 600 !important;
    letter-spacing: 0.07em !important;
    text-transform: uppercase !important;
    border-radius: var(--radius-pill) !important;
    padding: 0.85rem 2rem !important;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    position: relative;
    overflow: hidden;
    cursor: pointer;
    transition:
        background-color 0.18s var(--ease-smooth),
        color            0.18s var(--ease-smooth),
        border-color     0.18s var(--ease-smooth),
        transform        0.22s var(--ease-expo),
        box-shadow       0.22s var(--ease-expo) !important;
}

/* Icon-only product action buttons (Compare / Wishlist / Quick View) rely on
   font-size:0 (from the parent theme) to hide their text label and show only
   the icon painted via a background/mask. The global button rule above sets
   font-size:0.8rem !important, which was un-hiding that label text and making
   it overlap the icon circles. Restore font-size:0 for these specifically. */
.woocommerce--toolbar button,
.woosc-btn,
.woosw-btn,
.woosq-btn {
    font-size: 0 !important;
}


/* Lift on hover */
.btn:hover,
.pxl-button .btn:hover,
.woocommerce a.button:hover,
.woocommerce button.button:hover {
    transform: translateY(-3px) !important;
}

.btn:active,
.button:active,
input[type="submit"]:active {
    transform: translateY(-1px) !important;
    transition-duration: 0.08s !important;
}

/* Primary green button */
.btn-primary,
.pxl-button .btn-primary,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
input[type="submit"] {
    background: var(--c-green) !important;
    color: #fff !important;
    border: 2px solid var(--c-green) !important;
}
.btn-primary:hover,
.pxl-button .btn-primary:hover {
    background: var(--c-green-mid) !important;
    border-color: var(--c-green-mid) !important;
    box-shadow: var(--shadow-green) !important;
}

/* Outline button */
.btn-outline,
.pxl-button .btn-outline {
    background: transparent !important;
    color: var(--c-green) !important;
    border: 2px solid var(--c-green) !important;
}
.btn-outline:hover,
.pxl-button .btn-outline:hover {
    background: var(--c-green) !important;
    color: #fff !important;
    box-shadow: var(--shadow-green) !important;
}

/* Shimmer effect on hover */
.btn::before,
.pxl-button .btn::before {
    content: '';
    position: absolute;
    top: 0; left: -100%;
    width: 60%;
    height: 100%;
    background: linear-gradient(
        120deg,
        transparent 0%,
        rgba(255,255,255,0.22) 50%,
        transparent 100%
    );
    transition: left 0.55s var(--ease-expo);
    pointer-events: none;
}
.btn:hover::before,
.pxl-button .btn:hover::before {
    left: 140%;
}

/* ─── 7. PRODUCT CARDS ───────────────────────────────── */

.product,
li.product,
.pxl-product-item {
    border-radius: var(--radius-lg) !important;
    overflow: hidden !important;
    background: var(--c-white) !important;
    box-shadow: var(--shadow-xs) !important;
    border: 1px solid var(--c-border) !important;
    transition:
        transform  0.42s var(--ease-expo),
        box-shadow 0.42s var(--ease-expo) !important;
}

.product:hover,
li.product:hover {
    transform: translateY(-8px) !important;
    box-shadow: var(--shadow-lg) !important;
}

/* Product image zoom */
.product .woocommerce-loop-product__link img,
.product img.wp-post-image,
li.product img {
    transition: transform 0.75s var(--ease-expo);
    will-change: transform;
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
}

.product:hover .woocommerce-loop-product__link img,
li.product:hover img {
    transform: scale(1.07);
}

/* Product title. WooCommerce's own content-product.php template prints this
   as an <h2>, so this is the same bug as the bare h1-h6 rule above, on the
   one homepage element most likely to be built with Elementor's Products /
   Archive widgets: a page/element-scoped Elementor override on this h2 has
   higher specificity than this class selector already, so !important was
   the only thing standing in its way. No !important here on purpose
   (removed in 3.0.5). */
.woocommerce-loop-product__title {
    font-family: var(--font-heading);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--c-dark);
    line-height: 1.3;
    margin-top: 0.6rem;
}

/* Price */
.woocommerce .price,
.product .price {
    font-family: var(--font-sans) !important;
    font-weight: 600 !important;
    font-size: 1.05rem !important;
    color: var(--c-green) !important;
}
del .woocommerce-Price-amount {
    color: var(--c-muted) !important;
    font-weight: 400 !important;
}

/* Sale badge */
.woocommerce span.onsale,
.pxl-product-label {
    background: var(--c-gold) !important;
    color: #fff !important;
    font-family: var(--font-sans) !important;
    font-size: 0.68rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.08em !important;
    text-transform: uppercase !important;
    border-radius: var(--radius-pill) !important;
    padding: 4px 12px !important;
    min-height: unset !important;
    line-height: 1 !important;
    min-width: unset !important;
}

/* Add to cart */
.woocommerce .add_to_cart_button,
.woocommerce button.button:not(.alt),
.woocommerce a.button:not(.alt) {
    background: var(--c-green) !important;
    color: #fff !important;
    border-radius: var(--radius-pill) !important;
    font-family: var(--font-sans) !important;
    font-size: 0.75rem !important;
    font-weight: 600 !important;
    letter-spacing: 0.06em !important;
    text-transform: uppercase !important;
    border: none !important;
    padding: 0.6rem 1.4rem !important;
}
.woocommerce .add_to_cart_button:hover {
    background: var(--c-green-mid) !important;
    transform: translateY(-2px) !important;
    box-shadow: var(--shadow-green) !important;
}

/* Star ratings */
.woocommerce .star-rating span::before,
.woocommerce .star-rating::before {
    color: var(--c-gold) !important;
}

/* ─── 8. SECTION TITLES & EYEBROWS ───────────────────── */

/* Eyebrow / sub-label above headings */
.pxl-sub-title,
.sub-title,
[class*="eyebrow"] {
    font-family: var(--font-sans) !important;
    font-size: 0.72rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.14em !important;
    text-transform: uppercase !important;
    color: var(--c-green) !important;
}

/* Decorative gradient underline on main section h2s */
.elementor-section .elementor-heading-title[tag="h2"],
.elementor-widget-heading h2.elementor-heading-title {
    position: relative;
    display: inline-block;
}
.elementor-section .elementor-heading-title[tag="h2"]::after,
.elementor-widget-heading h2.elementor-heading-title::after {
    content: '';
    display: block;
    width: 52px;
    height: 3px;
    background: linear-gradient(90deg, var(--c-green), var(--c-gold));
    border-radius: var(--radius-pill);
    margin-top: 0.5rem;
}

/* Divider lines */
.elementor-divider-separator {
    border-color: var(--c-green-pale) !important;
}

/* ─── 9. ABOUT SECTION ────────────────────────────────── */

.pxl-about-img img,
.about-image img,
[class*="about"] .elementor-image img {
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    transition: transform 0.7s var(--ease-expo);
}
.pxl-about-img img:hover,
.about-image img:hover {
    transform: scale(1.02);
}

/* Feature icon boxes */
.pxl-icon-box,
.elementor-icon-box-wrapper,
[class*="feature-item"] {
    background: var(--c-white);
    border-radius: var(--radius-md);
    padding: 1.5rem;
    box-shadow: var(--shadow-xs);
    border: 1px solid rgba(45,106,79,0.08);
    transition:
        box-shadow 0.38s var(--ease-expo),
        transform  0.38s var(--ease-expo),
        border-color 0.38s ease;
}
.pxl-icon-box:hover,
.elementor-icon-box-wrapper:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-5px);
    border-color: var(--c-green-pale);
}

/* ─── 10. WHY CHOOSE US ───────────────────────────────── */

.pxl-list-item,
[class*="why-choose"] li,
.elementor-icon-list-item {
    position: relative;
    padding-left: 1.4rem;
}
.pxl-list-item::before,
.elementor-icon-list-item .elementor-icon-list-icon {
    color: var(--c-green) !important;
}

/* ─── 11. TEAM ─────────────────────────────────────────── */

.pxl-team-item,
[class*="team-member"] {
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    background: var(--c-white);
    transition:
        transform  0.42s var(--ease-expo),
        box-shadow 0.42s var(--ease-expo);
}
.pxl-team-item:hover { transform: translateY(-9px); box-shadow: var(--shadow-lg); }
.pxl-team-item img { transition: transform 0.75s var(--ease-expo); }
.pxl-team-item:hover img { transform: scale(1.06); }

/* Team member name. Targets h3/h4 tags directly, same bug as the bare h1-h6
   rule above: if a Team widget's name field is styled per-instance in
   Elementor, that override is more specific than this class+tag selector
   already and only loses because of !important. No !important here on
   purpose (removed in 3.0.5). */
.pxl-team-item h3,
.pxl-team-item h4,
[class*="team-member"] h3 {
    font-family: var(--font-heading);
    font-size: 1.3rem;
    font-weight: 600;
}

/* Team member role */
.pxl-team-item .team-position,
.pxl-team-item .position,
[class*="team-member"] .role {
    font-size: 0.8rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--c-green) !important;
}

/* ─── 12. TESTIMONIALS ─────────────────────────────────── */

.pxl-testimonial-item,
[class*="testimonial-item"],
.owl-item .elementor-testimonial-wrapper {
    background: var(--c-white);
    border-radius: var(--radius-lg);
    padding: 2rem 2rem 1.6rem;
    box-shadow: var(--shadow-md);
    border: 1px solid var(--c-border);
    position: relative;
    overflow: hidden;
}

/* Decorative quote mark */
.pxl-testimonial-item::before {
    content: '\201C';
    font-family: var(--font-heading);
    font-size: 7rem;
    line-height: 1;
    font-weight: 700;
    color: var(--c-green-pale);
    position: absolute;
    top: 0.5rem;
    left: 1.2rem;
    pointer-events: none;
    user-select: none;
}

/* Green left border accent */
.pxl-testimonial-item::after {
    content: '';
    position: absolute;
    top: 0; left: 0;
    width: 4px;
    height: 100%;
    background: linear-gradient(180deg, var(--c-green), var(--c-gold));
    border-radius: 0 0 0 var(--radius-lg);
}

/* Testimonial author name. Same bug as above on the h5 branch of this
   selector -- removed in 3.0.5. */
.pxl-testimonial-item .author-name,
.pxl-testimonial-item h5 {
    font-family: var(--font-heading);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--c-dark);
}

.pxl-testimonial-item .author-role,
.pxl-testimonial-item .position {
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    color: var(--c-muted);
}

/* ─── 13. PARTNERS / LOGO STRIP ────────────────────────── */

[class*="partner"],
.pxl-brand-item,
[class*="client-logo"] {
    filter: grayscale(100%) opacity(0.55);
    transition: filter 0.35s ease, transform 0.35s ease;
}
[class*="partner"]:hover,
.pxl-brand-item:hover {
    filter: grayscale(0%) opacity(1);
    transform: scale(1.06);
}

/* ─── 14. BLOG CARDS ──────────────────────────────────── */

.pxl-post-item,
article.post,
.blog-card {
    border-radius: var(--radius-lg) !important;
    overflow: hidden !important;
    box-shadow: var(--shadow-sm) !important;
    background: var(--c-white) !important;
    border: 1px solid var(--c-border) !important;
    transition:
        transform  0.42s var(--ease-expo),
        box-shadow 0.42s var(--ease-expo) !important;
}
.pxl-post-item:hover,
article.post:hover {
    transform: translateY(-7px) !important;
    box-shadow: var(--shadow-lg) !important;
}

/* Post thumbnail zoom */
.pxl-post-thumbnail,
.pxl-post-item .thumbnail-wrap {
    overflow: hidden;
}
.pxl-post-thumbnail img,
.pxl-post-item img {
    transition: transform 0.75s var(--ease-expo);
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
.pxl-post-item:hover .pxl-post-thumbnail img,
.pxl-post-item:hover img {
    transform: scale(1.07);
}

/* Post title. The h3-anchor and .entry-title branches are the exact same
   bug as the bare h1-h6 rule above -- an Elementor Posts widget or a
   per-post title override on the homepage blog section is more specific
   than this selector already and only loses because of !important.
   No !important here on purpose (removed in 3.0.5). */
.pxl-post-item .pxl-post-title a,
.pxl-post-item h3 a,
.entry-title a {
    font-family: var(--font-heading);
    font-size: 1.3rem;
    font-weight: 600;
    color: var(--c-dark);
    line-height: 1.3;
    transition: color 0.18s ease;
}
.pxl-post-item .pxl-post-title a:hover,
.entry-title a:hover {
    color: var(--c-green) !important;
}

/* Date badge */
.pxl-post-date,
.pxl-post-item .date-box {
    background: var(--c-green) !important;
    color: #fff !important;
    font-family: var(--font-sans) !important;
    font-weight: 700 !important;
    border-radius: var(--radius-sm) !important;
    line-height: 1.2 !important;
}

/* Category badge */
.pxl-post-item .pxl-post-cats a,
.pxl-post-item .cat-links a {
    font-family: var(--font-sans) !important;
    font-size: 0.7rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.08em !important;
    text-transform: uppercase !important;
    color: var(--c-green) !important;
    background: var(--c-green-pale) !important;
    padding: 3px 10px !important;
    border-radius: var(--radius-pill) !important;
}

/* ─── 15. FOOTER ──────────────────────────────────────── */

.site-footer,
#footer,
.pxl-footer-wrap {
    background: var(--c-dark) !important;
    color: rgba(255,255,255,0.7) !important;
}

.site-footer p,
.site-footer li,
.site-footer span,
#footer p {
    color: rgba(255,255,255,0.62) !important;
    font-size: 0.9rem !important;
}

.site-footer a,
#footer a {
    color: rgba(255,255,255,0.62) !important;
    transition: color 0.18s ease !important;
}
.site-footer a:hover,
#footer a:hover {
    color: var(--c-gold-light) !important;
}

/* Footer widget titles. Same bug as the bare h1-h6 rule above -- but note
   why it's still safe to drop !important here: `.site-footer h3` (a class
   plus a tag) is already more specific than the bare `h3` rule earlier in
   this file, so it keeps winning against that rule on ordinary cascade
   order/specificity with no !important needed, the same way it would have
   kept winning against Elementor's own more-specific override if this rule
   hadn't had !important forcing white text here regardless of what
   Elementor was told. Removed in 3.0.5. */
.site-footer h3,
.site-footer h4,
.site-footer .widget-title,
#footer .widget-title {
    font-family: var(--font-heading);
    font-size: 1.15rem;
    font-weight: 600;
    color: #fff;
    letter-spacing: 0;
    margin-bottom: 1rem;
}

/* Footer divider */
.footer-bottom,
.site-footer .pxl-footer-bottom {
    border-top: 1px solid rgba(255,255,255,0.08) !important;
    padding-top: 1rem !important;
}

/* Footer newsletter field */
.site-footer input[type="email"],
.site-footer input[type="text"],
.footer-newsletter input {
    background: rgba(255,255,255,0.07) !important;
    border: 1.5px solid rgba(255,255,255,0.14) !important;
    border-radius: var(--radius-pill) !important;
    color: #fff !important;
    padding: 0.75rem 1.25rem !important;
    font-family: var(--font-sans) !important;
    font-size: 0.9rem !important;
    width: 100%;
    transition: border-color 0.18s ease, background 0.18s ease !important;
}
.site-footer input[type="email"]:focus,
.site-footer input[type="text"]:focus {
    outline: none !important;
    border-color: var(--c-gold) !important;
    background: rgba(255,255,255,0.11) !important;
}

/* Instagram grid in footer */
.pxl-instagram-item img,
[class*="instagram-grid"] img {
    border-radius: var(--radius-md);
    transition: opacity 0.28s ease, transform 0.38s var(--ease-expo);
}
[class*="instagram-item"]:hover img {
    opacity: 0.85;
    transform: scale(1.04);
}

/* ─── 16. WOOCOMMERCE ─────────────────────────────────── */

/* Quantity input */
.woocommerce .quantity .qty {
    border-radius: var(--radius-sm) !important;
    border: 1.5px solid #ddd !important;
    font-family: var(--font-sans) !important;
    font-weight: 500 !important;
    padding: 0.4rem 0.6rem !important;
    transition: border-color 0.18s ease !important;
}
.woocommerce .quantity .qty:focus {
    outline: none !important;
    border-color: var(--c-green) !important;
}

/* Mini-cart */
.woocommerce-mini-cart {
    border-radius: var(--radius-lg) !important;
    box-shadow: var(--shadow-lg) !important;
    border: 1px solid var(--c-border) !important;
}

/* Cart total badge */
.pxl-header-cart .count,
.cart-count {
    background: var(--c-green) !important;
    color: #fff !important;
    font-family: var(--font-sans) !important;
    font-weight: 700 !important;
    border-radius: var(--radius-pill) !important;
    font-size: 0.68rem !important;
}

/* Checkout button */
.woocommerce #place_order,
.woocommerce .checkout-button {
    background: var(--c-green) !important;
    border-radius: var(--radius-pill) !important;
    font-family: var(--font-sans) !important;
    font-weight: 600 !important;
    letter-spacing: 0.07em !important;
    font-size: 0.85rem !important;
    text-transform: uppercase !important;
    transition: background 0.18s ease, transform 0.22s var(--ease-expo), box-shadow 0.22s ease !important;
}
.woocommerce #place_order:hover,
.woocommerce .checkout-button:hover {
    background: var(--c-green-mid) !important;
    transform: translateY(-2px) !important;
    box-shadow: var(--shadow-green) !important;
}

/* Breadcrumb */
.woocommerce .woocommerce-breadcrumb {
    font-family: var(--font-sans);
    font-size: 0.8rem;
    color: var(--c-muted);
}

/* ─── 17. FORMS & INPUTS ───────────────────────────────── */

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="search"],
textarea,
select {
    font-family: var(--font-sans) !important;
    font-size: 0.95rem !important;
    border-radius: var(--radius-md) !important;
    border: 1.5px solid #e0e0e0 !important;
    padding: 0.75rem 1rem !important;
    transition: border-color 0.18s ease, box-shadow 0.18s ease !important;
    background: #fff !important;
    color: var(--c-text) !important;
}
input[type="text"]:focus,
input[type="email"]:focus,
textarea:focus,
select:focus {
    outline: none !important;
    border-color: var(--c-green) !important;
    box-shadow: 0 0 0 3px rgba(45,106,79,0.1) !important;
}

/* Focus rings — accessibility */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible {
    outline: 2px solid var(--c-green) !important;
    outline-offset: 3px !important;
    border-radius: var(--radius-sm) !important;
}

/* ─── 18. UTILITY ──────────────────────────────────────── */

/* Announcement bar */
.pxl-top-bar,
[class*="announcement"],
[class*="top-bar"] {
    font-family: var(--font-sans) !important;
    font-size: 0.78rem !important;
    font-weight: 500 !important;
    letter-spacing: 0.04em !important;
}

/* Image containers prevent overflow bleed */
[class*="thumbnail"],
.pxl-post-thumbnail,
.woocommerce-product-gallery,
.product-thumbnail {
    overflow: hidden;
}

/* Prevent CLS on images with explicit dimensions */
img[width][height] {
    height: auto;
}

/* Section max-width consistency */
.elementor-section.elementor-section-boxed > .elementor-container {
    max-width: 1220px;
}

/* Stats / counter section */
.pxl-counter-item .pxl-count,
.elementor-counter-number-wrapper {
    font-family: var(--font-heading) !important;
    font-size: clamp(2.5rem, 5vw, 4rem) !important;
    font-weight: 700 !important;
    color: var(--c-green) !important;
    line-height: 1 !important;
}

/* ─── 19. RESPONSIVE ──────────────────────────────────── */

@media (max-width: 1024px) {
    .elementor-section.elementor-section-boxed > .elementor-container {
        padding: 0 1.5rem;
    }
}

@media (max-width: 768px) {
    /* No !important here either, for the same reason as the desktop rules
       above -- a mobile-specific Elementor typography setting needs to be
       able to win here too. */
    h1 { font-size: 1.9rem; }
    h2 { font-size: 1.6rem; }
    h3 { font-size: 1.3rem; }

    .pxl-testimonial-item {
        padding: 1.4rem 1.4rem 1.2rem;
    }
    .pxl-testimonial-item::before {
        font-size: 5rem;
    }

    .btn,
    .pxl-button .btn {
        padding: 0.75rem 1.6rem !important;
        font-size: 0.78rem !important;
    }

    /* Tighter product grid on tablet */
    .woocommerce ul.products {
        grid-template-columns: repeat(2, 1fr) !important;
        gap: 1rem !important;
    }

    /* Reduce animation distance on mobile */
    .xcado-reveal {
        transform: translateY(16px);
    }
}

@media (max-width: 480px) {
    .woocommerce ul.products {
        grid-template-columns: 1fr !important;
    }

    .btn,
    .pxl-button .btn {
        width: 100%;
        justify-content: center;
    }
}

/* Reduced motion — respect OS accessibility preference */
@media (prefers-reduced-motion: reduce) {
    .xcado-reveal,
    .xcado-reveal.xcado-visible {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
    img { transition: none !important; }
    * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
