/*
Theme Name: PlayForge
Theme URI: https://childrenplayground.cn/playforge
Author: PlayForge
Author URI: https://childrenplayground.cn
Description: Commercial WordPress theme for indoor playground, trampoline park and family entertainment center manufacturers. Built on Bootstrap 5, fully compatible with Elementor and WooCommerce, with a serial-key activated theme options panel, four menu locations and eight selectable page layouts including edge-to-edge three-column ones. Ported from the Hugo theme of the same name.
Version: 1.3.0
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: playforge
Tags: business, e-commerce, portfolio, custom-logo, custom-menu, featured-images, footer-widgets, left-sidebar, right-sidebar, full-width-template, translation-ready, block-styles, wide-blocks, threaded-comments

PlayForge is distributed under the terms of the GNU GPL v2 or later.
Bundled Bootstrap 5.3.3 and Bootstrap Icons 1.11.3 are MIT licensed.
*/

/* ==========================================================================
   1. Design tokens

   Every colour, font, weight, radius, shadow and band background in this file
   is read from a custom property declared below. Nothing outside section 1
   contains a literal colour, so a whole new look can be produced by
   redefining tokens alone — in a child theme's style.css, in Appearance →
   Customise → Additional CSS, or per page from Elementor's custom CSS. See
   playforge-child-blue/style.css for a worked example.

   Tokens come in two kinds:

     Scale tokens  (--brand, --radius, --fw-bold, --shadow-card …) are the raw
                   values: the palette, the type weights, the radius steps.
     Role tokens   (--radius-btn, --fw-nav, --card-hover-border …) point at a
                   scale token and name the job it does. Redefine a scale token
                   to move everything that uses it; redefine a role token to
                   move one component. Roles are listed with the scale they
                   default to, so either level works.
   ========================================================================== */

:root {

  /* --- Palette ---------------------------------------------------------- */

  --ink: #17202a;
  --muted: #667085;
  --line: #e6e9ef;
  --brand: #0f766e;
  --brand-dark: #115e59;
  --accent: #f59e0b;
  --soft: #f7fafc;

  /* Spare palette slot. No rule in the theme reads it — it is here so page
     content, Elementor widgets and child-theme rules have a documented tint
     to reach for that moves with the rest of the palette. */
  --sky: #e0f2fe;

  /* Comma-separated channels for the same three colours. CSS cannot take a
     hex apart, so any rgba() built from the palette needs these alongside it.
     Redefine them together with the hex above or translucent overlays will
     keep the old hue. */
  --brand-rgb: 15, 118, 110;
  --brand-dark-rgb: 17, 94, 89;
  --accent-rgb: 245, 158, 11;

  /* Surfaces and rules. */
  --surface: #fff;            /* cards, navbar, dropdowns, widgets, inputs */
  --surface-alt: #f8fafc;     /* quiet fill: price block, table label column */
  --body-bg: var(--surface);
  --line-soft: #f1f4f7;       /* faintest divider, between list items */
  --line-alt: #e8edf2;        /* one step stronger */

  /* Text on a filled background. The accent is too light for white, so it
     carries its own ink. */
  --on-brand: #fff;
  --on-accent: #3a2a00;

  /* Brand washes, for outlined controls and their hover state. */
  --brand-tint: #d9f5f1;
  --brand-edge: #90d7d0;
  --brand-ring: #7bcac3;
  --hover-wash: rgba(15, 23, 42, .06);   /* neutral hover on a bare button */

  /* Long-form copy sits a shade softer than --ink so headings stay dominant. */
  --ink-prose: #2b3542;
  --ink-quote: #334155;

  --icon-ink: var(--brand);   /* icons in capability lists and cards */

  /* Status colours. Used by assets/css/woocommerce.css for stock, price and
     message states, where hue carries meaning and must not follow the brand.
     The tints are the notice backgrounds those colours sit on. */
  --ok: #15803d;
  --info: #0284c7;
  --danger: #b91c1c;
  --neutral: #64748b;
  --ok-tint: #f0fdf4;
  --info-tint: #f0f9ff;
  --danger-tint: #fef2f2;

  /* Dark bands. --panel-texture and --footer-texture are extra background
     layers painted over the flat colour — `none` by default, a repeating
     gradient or an image in a child theme. */
  --panel: #10202f;           /* top strip, quote band */
  --panel-deep: #08131f;      /* footer */
  --panel-ink: #dce6ef;
  --panel-icon-ink: inherit;
  --panel-border: 0;
  --panel-texture: none;
  --footer-ink: #b8c4cf;
  --footer-link-ink: #c8d3dc;
  --footer-heading-ink: var(--surface);
  --footer-icon-ink: inherit;
  --footer-border-top: 0;
  --footer-texture: none;

  /* Licence notice. Deliberately off-palette: it is enforcement copy and has
     to stay conspicuous. */
  --notice-bg: #3f1d1d;
  --notice-border: #5b2a2a;
  --notice-ink: #ffd9d9;

  /* WhatsApp keeps its own brand green — recolouring it costs recognition. */
  --whatsapp: #25d366;
  --whatsapp-hover: #1eb857;

  --selection-bg: var(--brand);
  --selection-ink: var(--on-brand);

  /* --- Typography ------------------------------------------------------- */

  --font-body: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-heading: var(--font-body);

  /* Weight scale, then the roles drawn from it. Dropping --fw-black to 700
     quietens the whole theme in one line; the roles below let single
     components move on their own. */
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;
  --fw-black: 900;

  --fw-heading: var(--fw-medium);        /* bare h1–h6; Bootstrap's own weight */
  --fw-display: var(--fw-black);         /* hero, section and page titles */
  --fw-brand: var(--fw-black);           /* the wordmark */
  --fw-btn: var(--fw-bold);
  --fw-nav: var(--fw-bold);
  --fw-menu: var(--fw-semibold);
  --fw-menu-active: var(--fw-extrabold);
  --fw-kicker: var(--fw-black);          /* section kicker */
  --fw-label: var(--fw-extrabold);       /* eyebrow, tag, chip, badge */
  --fw-card-title: var(--fw-extrabold);  /* product title in a listing */
  --fw-price: var(--fw-extrabold);
  --fw-prose-heading: var(--fw-extrabold);
  --fw-widget-title: var(--fw-extrabold);
  --fw-table-label: var(--fw-bold);
  --fw-pagination: var(--fw-bold);
  --fw-form-label: inherit;

  --tracking-heading: normal;
  --tracking-display: normal;
  --tracking-label: .08em;               /* uppercase eyebrow and kicker */
  --tracking-btn: normal;

  /* Tabular figures, for anywhere numbers should line up in a column. Set to
     `tabular-nums` in a child theme selling on specifications. */
  --numeric-figures: normal;

  --prose-width: 100%;
  --prose-size: 1.06rem;
  --prose-line-height: 1.75;
  --prose-link-ink: inherit;

  /* --- Geometry --------------------------------------------------------- */

  --radius-sm: 4px;
  --radius: 6px;
  --radius-lg: 8px;

  --radius-btn: var(--radius);
  --radius-control: var(--radius);       /* inputs and selects */
  --radius-card: var(--radius-lg);       /* cards, panels, widgets, media */
  --radius-chip: var(--radius-sm);       /* tag, badge, sale flash */
  --radius-media: var(--radius);         /* gallery thumbnails */
  --radius-pill: 999px;
  --radius-badge: var(--radius-pill);    /* header cart count */
  --radius-float: 50%;                   /* floating CTA buttons */

  /* --- Elevation -------------------------------------------------------- */

  --shadow-navbar: 0 8px 28px rgba(15, 23, 42, .08);
  --shadow-dropdown: 0 12px 32px rgba(15, 23, 42, .10);
  --shadow-card: none;
  --shadow-card-hover: 0 16px 40px rgba(15, 23, 42, .10);
  --shadow-blog-hover: 0 14px 34px rgba(15, 23, 42, .08);
  --shadow-float: 0 8px 24px rgba(var(--brand-rgb), .35);
  --shadow-form: none;
  --ring: 0 0 0 .25rem rgba(var(--brand-rgb), .15);   /* focus ring on inputs */

  /* The skip link's own focus outline. Deliberately neutral rather than brand
     tinted, and deliberately heavy: it has to be obvious against whatever the
     page happens to put behind it. Lighten it and it stops doing its job. */
  --shadow-skiplink: 0 0 2px 2px rgba(0, 0, 0, .6);

  /* Card hover. A lift plus a shadow by default; set --card-hover-lift to
     `none` and give --card-hover-border a colour for a flatter, more technical
     treatment that does not shift the layout. */
  --card-hover-lift: translateY(-4px);
  --card-hover-border: var(--line);
  --blog-hover-lift: translateY(-3px);

  /* --- Page metrics ----------------------------------------------------- */

  /*   --box-width     Widest the boxed .container ever gets. 1320px is
                       Bootstrap's own xxl container, so the default changes
                       nothing. Narrowing takes effect at every breakpoint;
                       widening past 1320px takes effect from 1400px up, where
                       there is room for it. See section 14.
       --page-padding  Padding on the content area (.pf-content), as a padding
                       shorthand — "4rem 0", "3rem 1.5rem", "0", anything.
       --page-margin   Margin on the same element, same shorthand freedom.

     The Elementor Full Canvas layout ignores all three by design. */
  --box-width: 1320px;
  --page-padding: 2rem 0;
  --page-padding-sm: 2.5rem 0;
  --page-margin: 0;

  /* Width of the sidebar column in the two-column layouts, from 992px up; the
     main column takes the rest. Bootstrap's grid steps in twelfths, so the
     markup keeps col-lg-4/col-lg-8 as the no-CSS fallback and section 14
     overrides the pair from this one token. */
  --sidebar-width: 25%;

  /* The right sidebar tracks the left unless given its own value, so the
     three-column layout is symmetric by default and either side can be tuned
     alone. The main column always takes what is left of the two. */
  --sidebar-width-right: var(--sidebar-width);

  /* Side breathing room for the edge-to-edge three-column layouts, which have no
     .container gutters of their own. Floored at 1.5rem in section 14: the row's
     g-5 gutter pulls its columns 1.5rem outwards, so anything less would put the
     content past the viewport edge and produce a horizontal scrollbar. */
  --fullscreen-sidebar-gutter: 2rem;

  /* Homepage sections track --page-padding unless given their own value. */
  --section-padding: var(--page-padding);
  --section-padding-sm: 3.5rem 0;

  --alignwide-width: 1140px;

  /* --- Bands ------------------------------------------------------------ */

  /* Hero. The background stacks four layers, top to bottom: texture, overlay
     gradient, the image from --hero-image, then a flat colour so the band is
     never bare while the image loads or when none is set. */
  --hero-min-height: calc(100vh - 112px);
  --hero-texture: none;
  --hero-overlay: linear-gradient(90deg, rgba(10, 23, 38, .82) 0%, rgba(10, 23, 38, .58) 45%, rgba(10, 23, 38, .16) 100%);
  --hero-bg: #234155;
  --hero-ink: #fff;
  --hero-lead-ink: #e7edf3;
  --hero-fade: linear-gradient(180deg, rgba(255, 255, 255, 0), var(--surface) 90%);
  --hero-title-size: clamp(2.35rem, 5vw, 5.2rem);
  --hero-title-size-sm: 2.55rem;
  --hero-title-line-height: 1.02;
  /* The hero title can be set tighter than the other display type. */
  --tracking-hero: var(--tracking-display);

  --eyebrow-ink: #fef3c7;
  --eyebrow-icon-ink: inherit;
  --eyebrow-size: .82rem;
  --kicker-size: .78rem;

  --metric-grid: rgba(255, 255, 255, .2);   /* shows through the 1px gaps */
  --metric-bg: rgba(8, 18, 31, .48);
  --metric-ink: #d7e4ee;
  --metric-value-ink: inherit;
  /* `bolder` is what <strong> resolves to on its own, so this changes nothing
     until a child theme pins it to a number. */
  --fw-metric-value: bolder;
  --metric-label-size: .88rem;
  --metric-label-transform: none;
  --metric-label-tracking: normal;

  /* Page header banner. Same layer order as the hero. --page-header-bg is
     transparent by default so the gradient alone paints the band. */
  --page-header-texture: none;
  --page-header-overlay: linear-gradient(90deg, rgba(var(--brand-rgb), .96), rgba(var(--brand-dark-rgb), .88));
  --page-header-bg: transparent;
  --page-header-ink: #fff;
  --page-header-lead-ink: #e5f3f1;
  --page-header-padding: 4rem 0 3rem;
  --page-header-padding-sm: var(--page-header-padding);
  --page-header-border-bottom: 0;
  /* Single posts only, applied by .single-post .page-header. Pages, archives and
     other single post types are left sizing to their content. */
  --page-header-single-min-height: 400px;
  --page-title-size: clamp(2rem, 4vw, 3.4rem);

  /* Used in place of the band when "Show page-header with big title" is off.
     --breadcrumb-title-* style the <h1> the breadcrumb's last item then carries;
     it is deliberately sized to the trail around it, so the heading is semantic
     rather than another banner. --entry-title-size is the visible <h1> a single
     post prints above its date line — a step below the banner title, because
     without the band's colour behind it the banner size reads as shouting.
     --page-lead-* style the band's old sub-heading where one survives: the search
     result count, the 404 notice, an archive description. */
  --breadcrumb-title-size: inherit;
  --breadcrumb-title-weight: inherit;
  --breadcrumb-title-ink: inherit;
  --entry-title-size: clamp(1.6rem, 2.6vw, 2.4rem);
  --page-lead-padding: 1.6rem 0 0;
  --page-lead-ink: var(--muted);
  /* Space between an archive description and the card grid under it. The gap above
     it comes from .pf-content's own padding, so only this side needs a token. */
  --archive-intro-gap: 1.75rem;

  --breadcrumb-bg: #f2f5f7;
  --breadcrumb-divider-ink: inherit;

  --factory-min-height: 520px;
  --factory-min-height-md: 360px;
  --factory-overlay: linear-gradient(180deg, rgba(var(--brand-rgb), .08), rgba(var(--accent-rgb), .08));
  --factory-bg: #d9e6e8;

  /* Homepage builder. The About Us media and the play button over a video cover;
     see section 18. */
  --home-media-radius: var(--radius-card);
  --home-media-shadow: var(--shadow-card-hover);
  --home-play-size: 76px;
  --home-play-size-sm: 56px;
  --home-play-bg: var(--brand);
  --home-play-ink: #fff;
  --home-play-hover-bg: var(--brand-dark);
  --home-play-shadow: 0 10px 30px rgba(var(--brand-rgb), .45);
  --home-video-scrim: linear-gradient(180deg, rgba(10, 23, 38, .10), rgba(10, 23, 38, .34));

  --quote-band-padding: 5rem 0;
  --quote-band-padding-sm: var(--section-padding-sm);
  --quote-form-bg: var(--surface);
  --quote-form-border: rgba(255, 255, 255, .24);

  /* --- Components ------------------------------------------------------- */

  --card-bg: var(--surface);
  --card-image-height: 220px;
  --blog-image-height: 210px;
  --cert-border-top: 1px solid var(--line);   /* rule across the top of a certification card */
  --band-border-top: 0;
  --band-border-bottom: 0;

  --tag-bg: #e7f7f5;
  --tag-border: transparent;
  --tag-ink: var(--brand-dark);
  --tag-size: .78rem;
  --tag-transform: none;
  --tag-tracking: normal;
  --tag-hover-bg: var(--tag-bg);
  --tag-hover-border: var(--tag-border);

  --step-bg: #fff3d5;         /* numbered process step */
  --step-ink: #925a00;
  --step-shadow: none;

  --control-border: #d7dde5;
  --control-focus-border: var(--brand-ring);
  --control-min-height: 46px;
  --label-ink: inherit;
  --label-size: inherit;
  --label-transform: none;
  --label-tracking: normal;

  /* Block-editor buttons inside WooCommerce blocks: the product grid the cart
     page renders when the cart is empty, and the All Products block. The block
     editor gives those buttons a dark slate fill of its own that ignores the
     palette completely, and against a light page it reads as a hole punched in
     the grid. assets/css/woocommerce.css repaints them from these tokens.

     Grey border rather than --brand-edge on purpose: several of these sit in a
     row under the product images, and a row of brand-edged buttons competes
     with the products it belongs to. The brand only appears on hover. */
  --block-btn-bg: var(--surface);
  --block-btn-ink: var(--ink);
  --block-btn-border: var(--line);
  --block-btn-bg-hover: var(--soft);
  --block-btn-ink-hover: var(--brand-dark);
  --block-btn-border-hover: var(--brand-edge);

  --price-block-bg: var(--surface-alt);
  --price-block-border: var(--line);
  /* Overridden on its own to put a coloured rule down the leading edge. */
  --price-block-edge: 1px solid var(--price-block-border);

  --spec-label-width: 34%;
  --spec-label-width-sm: var(--spec-label-width);
  --spec-label-bg: var(--surface-alt);
  /* Bootstrap paints table text with --bs-emphasis-color; naming it here means
     a child theme can quieten the label column without touching the values. */
  --spec-label-ink: var(--bs-emphasis-color);
  --spec-value-ink: var(--bs-emphasis-color);
  --spec-label-size: inherit;
  --spec-label-transform: none;
  --spec-label-tracking: normal;

  --widget-title-ink: inherit;
  --widget-title-size: 1.05rem;
  --widget-title-border: 2px solid var(--brand);
  --widget-divider: var(--line-soft);
  /* One step of indent per level in a hierarchical widget list, so a third level
     indents twice. The guide line down the leading edge is what makes the nesting
     legible at a glance — a 1rem indent on its own reads as a ragged margin once a
     few long category names wrap. */
  --widget-nest-indent: 1rem;
  --widget-nest-guide: 1px solid var(--line);
  --widget-nest-ink: var(--muted);
  --widget-nest-size: .92em;
  --widget-parent-weight: var(--fw-semibold);

  --pagination-hover-bg: var(--brand-tint);
  --pagination-hover-border: var(--brand-ring);
  --pagination-hover-ink: var(--brand-dark);

  --map-hint-bg: rgba(var(--brand-rgb), .94);
  --map-hint-weight: var(--fw-semibold);

  --nav-ink: #263241;
  --nav-hover-ink: var(--brand);
}

/* Bootstrap's own tokens, pointed at the palette above. Without this, anything
   Bootstrap, Elementor or a plugin renders from its defaults — utilities,
   links, alerts, tables, focus rings — stays Bootstrap indigo while the theme
   is teal. Everything here is expressed through theme tokens, so retinting
   :root above carries Bootstrap along with it. */
:root {
  --bs-primary: var(--brand);
  --bs-primary-rgb: var(--brand-rgb);
  --bs-link-color: var(--brand-dark);
  --bs-link-color-rgb: var(--brand-dark-rgb);
  --bs-link-hover-color: var(--brand);
  --bs-border-color: var(--line);
  --bs-border-radius: var(--radius);
  --bs-focus-ring-color: rgba(var(--brand-rgb), .25);
}

body {
  color: var(--ink);
  background-color: var(--body-bg);
  font-family: var(--font-body);
}

a { color: inherit; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  letter-spacing: var(--tracking-heading);
}

.wp-block-heading {font-size: 1.5em;}

::selection { background: var(--selection-bg); color: var(--selection-ink); }

/* Figures line up in a column wherever numbers carry meaning — but only if
   --numeric-figures asks for it. */
.spec-table,
.price-block,
.metric,
.pf-pagination,
table.shop_attributes,
.woocommerce-Price-amount {
  font-variant-numeric: var(--numeric-figures);
}

/* ==========================================================================
   2. Buttons
   ========================================================================== */

.btn {
  border-radius: var(--radius-btn);
  font-weight: var(--fw-btn);
  letter-spacing: var(--tracking-btn);
}

/* Bootstrap leaves the hover, active, disabled and focus-ring variables unset
   on a bare .btn, so a custom variant that fills only --bs-btn-bg turns
   transparent when pressed or disabled and shows no focus ring at all. Each
   variant below therefore states the full set. */
.btn-brand {
  --bs-btn-bg: var(--brand);
  --bs-btn-border-color: var(--brand);
  --bs-btn-hover-bg: var(--brand-dark);
  --bs-btn-hover-border-color: var(--brand-dark);
  --bs-btn-active-bg: var(--brand-dark);
  --bs-btn-active-border-color: var(--brand-dark);
  --bs-btn-disabled-bg: var(--brand);
  --bs-btn-disabled-border-color: var(--brand);
  --bs-btn-color: var(--on-brand);
  --bs-btn-hover-color: var(--on-brand);
  --bs-btn-active-color: var(--on-brand);
  --bs-btn-disabled-color: var(--on-brand);
  --bs-btn-focus-shadow-rgb: var(--brand-rgb);
}

.btn-outline-brand {
  --bs-btn-color: var(--brand-dark);
  /* Transparent rather than --surface, so the button reads as an outline on a
     tinted .band too. On the white surfaces it started life on, the two are
     indistinguishable. */
  --bs-btn-bg: transparent;
  --bs-btn-border-color: var(--brand-edge);
  --bs-btn-hover-bg: var(--brand-tint);
  --bs-btn-hover-border-color: var(--brand-ring);
  --bs-btn-hover-color: var(--brand-dark);
  --bs-btn-active-bg: var(--brand-tint);
  --bs-btn-active-border-color: var(--brand-ring);
  --bs-btn-active-color: var(--brand-dark);
  --bs-btn-disabled-color: var(--muted);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: var(--line);
  --bs-btn-focus-shadow-rgb: var(--brand-rgb);
}

/* Secondary call to action, for the request that should not compete with the
   primary one — "Download catalogue" beside "Get a quote". */
.btn-accent {
  --bs-btn-bg: var(--accent);
  --bs-btn-border-color: var(--accent);
  --bs-btn-hover-bg: var(--accent);
  --bs-btn-hover-border-color: var(--accent);
  --bs-btn-active-bg: var(--accent);
  --bs-btn-active-border-color: var(--accent);
  --bs-btn-disabled-bg: var(--accent);
  --bs-btn-disabled-border-color: var(--accent);
  --bs-btn-color: var(--on-accent);
  --bs-btn-hover-color: var(--on-accent);
  --bs-btn-active-color: var(--on-accent);
  --bs-btn-disabled-color: var(--on-accent);
  --bs-btn-focus-shadow-rgb: var(--accent-rgb);
}

/* Bootstrap compiles .btn-primary to literal hex, so retinting --bs-primary
   does not reach it. Elementor widgets and many plugins emit .btn-primary, so
   it is mapped onto the brand explicitly. */
.btn-primary {
  --bs-btn-bg: var(--brand);
  --bs-btn-border-color: var(--brand);
  --bs-btn-hover-bg: var(--brand-dark);
  --bs-btn-hover-border-color: var(--brand-dark);
  --bs-btn-active-bg: var(--brand-dark);
  --bs-btn-active-border-color: var(--brand-dark);
  --bs-btn-disabled-bg: var(--brand);
  --bs-btn-disabled-border-color: var(--brand);
  --bs-btn-color: var(--on-brand);
  --bs-btn-hover-color: var(--on-brand);
  --bs-btn-active-color: var(--on-brand);
  --bs-btn-disabled-color: var(--on-brand);
  --bs-btn-focus-shadow-rgb: var(--brand-rgb);
}

.btn-outline-primary {
  --bs-btn-color: var(--brand-dark);
  --bs-btn-border-color: var(--brand);
  --bs-btn-hover-bg: var(--brand);
  --bs-btn-hover-border-color: var(--brand);
  --bs-btn-hover-color: var(--on-brand);
  --bs-btn-active-bg: var(--brand-dark);
  --bs-btn-active-border-color: var(--brand-dark);
  --bs-btn-active-color: var(--on-brand);
  --bs-btn-focus-shadow-rgb: var(--brand-rgb);
}

/* ==========================================================================
   3. Header — top strip and navbar
   ========================================================================== */

.top-strip {
  background: var(--panel-texture), var(--panel);
  color: var(--panel-ink);
  font-size: .875rem;
  border-bottom: var(--panel-border);
}
.top-strip a { text-decoration: none; color: inherit; }
.top-strip a:hover { color: var(--surface); }
.top-strip i { color: var(--panel-icon-ink); }

.navbar { background-color: var(--surface); box-shadow: var(--shadow-navbar); }
.navbar-brand { font-weight: var(--fw-brand); }
.navbar-brand span { color: var(--brand); }
.navbar-brand img { max-height: 48px; width: auto; height: auto; }
.nav-link { font-weight: var(--fw-nav); color: var(--nav-ink); }
.nav-link:hover, .nav-link:focus { color: var(--nav-hover-ink); }
.navbar-nav .dropdown-menu { border-color: var(--line); border-radius: var(--radius); box-shadow: var(--shadow-dropdown); }
.navbar-nav .dropdown-item { font-weight: var(--fw-menu); border-radius: var(--radius-sm); }

/* Bootstrap marks the current item with its blue --bs-dropdown-link-active-bg,
   which turns a whole branch blue on any page whose menu item lives inside a
   dropdown — a post filed under a parent item, say. The menu stays white; the
   current item is marked by weight instead. */
.navbar-nav .dropdown-menu {
  --bs-dropdown-link-active-color: var(--ink);
  --bs-dropdown-link-active-bg: transparent;
}
.navbar-nav .dropdown-item.active { font-weight: var(--fw-menu-active); }
/* Bootstrap's .active rule comes after its :hover rule, so without this the
   current item is the one item that does not respond to the pointer. */
.navbar-nav .dropdown-item.active:hover,
.navbar-nav .dropdown-item.active:focus { background-color: var(--bs-dropdown-link-hover-bg); }

/* Pressed, as opposed to current: a brief brand-coloured flash. */
.navbar-nav .dropdown-item:active { background-color: var(--brand); color: var(--on-brand); }

/* Chevron button beside a parent item. It opens the level below; the text next
   to it stays an ordinary link. Hidden where hover can do the job — see the
   "Multi-level navigation" block in assets/js/site.js. */
.pf-submenu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.5rem;
  padding: .4rem;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: inherit;
  line-height: 1;
}
.pf-submenu-toggle:hover, .pf-submenu-toggle:focus-visible { background: var(--hover-wash); }
.pf-submenu-toggle .bi { transition: transform .15s ease-in-out; }
.pf-open > .pf-submenu-toggle .bi { transform: rotate(180deg); }

/* Search icon in the bar, and the panel it opens under it.

   The button is a sibling of .navbar-collapse rather than a child of it, so the
   icon is there on a phone without opening the menu first. That DOM position
   would place it left of the menu on the wide layout, so `order` below moves it
   behind the collapse — which grows to fill the bar — leaving the icon at the
   right end, next to the CTA button. */
.pf-search-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  margin-left: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--nav-ink);
  font-size: 1.125rem;
  line-height: 1;
}
.pf-search-toggle:hover,
.pf-search-toggle:focus-visible,
.pf-search-toggle[aria-expanded="true"] { background: var(--hover-wash); color: var(--nav-hover-ink); }

/* The panel hangs off the bar instead of sitting inside it: absolute keeps the
   bar the same height open or closed, so opening the search shifts nothing on
   the page behind it. .sticky-top makes the bar a positioned ancestor, so this
   resolves against the bar and not the page. */
.pf-search-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  padding: .875rem 0;
  background-color: var(--surface);
  border-top: 1px solid var(--line);
  box-shadow: var(--shadow-navbar);
}
/* Bootstrap's reboot already carries [hidden] { display: none !important }, but
   stating it here means the panel is not left open by a child theme or a build
   that loads style.css without Bootstrap. */
.pf-search-panel[hidden] { display: none; }

@media (max-width: 991.98px) {
  /* Between the brand and the hamburger, pushed over to sit beside it. */
  .pf-search-toggle { margin-right: .25rem; }
}

@media (max-width: 991.98px) {
  /* Stacked menu: link and chevron share a row, the submenu takes the next one. */
  .navbar-nav li { display: flex; flex-wrap: wrap; align-items: center; }
  /* Bootstrap gives .dropdown-item width: 100%, which would wrap the chevron
     onto its own line — grow from zero instead. */
  .navbar-nav li > .nav-link,
  .navbar-nav li > .dropdown-item { flex: 1 1 0; width: auto; min-width: 0; }
  .navbar-nav li > .dropdown-divider { flex: 1 0 100%; }
  .navbar-nav li > .dropdown-menu { flex: 1 0 100%; margin: 0 0 .25rem; padding-left: .5rem; border: 0; border-left: 2px solid var(--line); border-radius: 0; box-shadow: none; }
  /* The chevron already says there is more below. */
  .navbar-nav .dropdown-toggle::after { display: none; }
}

@media (min-width: 992px) {
  /* Levels two and deeper open to the side of their parent. */
  .navbar-nav .dropdown-menu li { position: relative; }
  .navbar-nav .dropdown-menu .dropdown-menu { top: 0; left: 100%; margin-top: -.5rem; }
  /* Flipped by site.js when the default side would leave the viewport. */
  .navbar-nav .dropdown-menu .dropdown-menu.pf-flip { left: auto; right: 100%; }
  .navbar-nav > li > .dropdown-menu.pf-menu-end { left: auto; right: 0; }
  /* A caret pointing into the submenu reads better than one pointing down. */
  .navbar-nav .dropdown-menu .dropdown-item.dropdown-toggle { display: flex; align-items: center; justify-content: space-between; }
  .navbar-nav .dropdown-menu .dropdown-item.dropdown-toggle::after { margin-left: .75rem; border-top: .3em solid transparent; border-right: 0; border-bottom: .3em solid transparent; border-left: .3em solid; }

  /* Hover opens the submenu, so the chevron is redundant on the wide layout. */
  .pf-submenu-toggle { display: none; }

  /* …unless the pointer cannot hover (a tablet in landscape), where the chevron
     is the only way in and shares a row with the link. site.js sets the class. */
  .navbar.pf-no-hover .pf-submenu-toggle { display: inline-flex; }
  .navbar.pf-no-hover .navbar-nav li { display: flex; flex-wrap: wrap; align-items: center; }
  .navbar.pf-no-hover .navbar-nav li > .nav-link,
  .navbar.pf-no-hover .navbar-nav li > .dropdown-item { flex: 1 1 0; width: auto; min-width: 0; }
  .navbar.pf-no-hover .navbar-nav .dropdown-toggle::after { display: none; }

  /* Past the collapse, so the icon lands to the right of the CTA button. */
  .pf-search-toggle { order: 1; margin-left: .5rem; }

  /* A field the full width of the container reads as a section of the page
     rather than as something the icon opened; this keeps it under the icon. */
  .pf-search-panel .input-group { max-width: 26rem; margin-left: auto; }
}

/* ==========================================================================
   4. Hero
   Retained for rebuilding the homepage hero in Elementor with original styling.
   ========================================================================== */

.hero {
  min-height: var(--hero-min-height);
  display: flex;
  align-items: center;
  position: relative;
  overflow: hidden;
  background:
    var(--hero-texture),
    var(--hero-overlay),
    var(--hero-image, none) center / cover no-repeat,
    var(--hero-bg);
}
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 88px;
  background: var(--hero-fade);
}
.hero-content { position: relative; z-index: 1; max-width: 720px; color: var(--hero-ink); padding: 5rem 0 7rem; }
.eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  color: var(--eyebrow-ink); font-size: var(--eyebrow-size); font-weight: var(--fw-label);
  text-transform: uppercase; letter-spacing: var(--tracking-label);
}
.eyebrow i { color: var(--eyebrow-icon-ink); }
.hero h1 {
  font-size: var(--hero-title-size);
  line-height: var(--hero-title-line-height);
  font-weight: var(--fw-display);
  letter-spacing: var(--tracking-hero);
  margin: 1rem 0 1.25rem;
}
.hero .lead { color: var(--hero-lead-ink); max-width: 620px; }

.metric-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  max-width: 640px;
  background: var(--metric-grid);
  margin-top: 2rem;
}
.metric { background: var(--metric-bg); padding: 1rem; }
.metric strong { display: block; font-size: 1.5rem; font-weight: var(--fw-metric-value); color: var(--metric-value-ink); }
.metric span {
  display: block; color: var(--metric-ink);
  font-size: var(--metric-label-size);
  text-transform: var(--metric-label-transform);
  letter-spacing: var(--metric-label-tracking);
}

/* ==========================================================================
   5. Sections and utilities
   ========================================================================== */

.pf-section { padding: var(--section-padding); margin: var(--page-margin); }
.section-kicker { color: var(--brand-dark); font-weight: var(--fw-kicker); text-transform: uppercase; font-size: var(--kicker-size); letter-spacing: var(--tracking-label); }
.section-title { font-weight: var(--fw-display); letter-spacing: var(--tracking-display); }
.text-muted-2 { color: var(--muted); }
.text-brand { color: var(--brand); }
.fw-black { font-weight: var(--fw-display); }
.band { background: var(--soft); border-top: var(--band-border-top); border-bottom: var(--band-border-bottom); }

/* ==========================================================================
   6. Cards
   ========================================================================== */

.product-card, .case-card, .process-item, .cert-item {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--card-bg);
  height: 100%;
  box-shadow: var(--shadow-card);
}
.product-card img, .case-card img { width: 100%; height: var(--card-image-height); object-fit: cover; border-radius: var(--radius-card) var(--radius-card) 0 0; }
.product-card { transition: transform .2s, box-shadow .2s, border-color .2s; }
.product-card:hover { transform: var(--card-hover-lift); box-shadow: var(--shadow-card-hover); border-color: var(--card-hover-border); }
.cert-item { border-top: var(--cert-border-top); }
.cert-item i { color: var(--icon-ink); }

.tag {
  display: inline-flex; align-items: center; min-height: 28px;
  padding: .25rem .55rem; border-radius: var(--radius-chip);
  background: var(--tag-bg); border: 1px solid var(--tag-border); color: var(--tag-ink);
  font-size: var(--tag-size); font-weight: var(--fw-label);
  text-transform: var(--tag-transform); letter-spacing: var(--tag-tracking);
  text-decoration: none;
  transition: background-color .15s ease, border-color .15s ease;
}
.tag:hover { background: var(--tag-hover-bg); border-color: var(--tag-hover-border); }

.capability-list { list-style: none; padding: 0; margin: 0; }
.capability-list li { display: flex; gap: .75rem; padding: .7rem 0; border-bottom: 1px solid var(--line-alt); }
.capability-list li:last-child { border-bottom: 0; }
.capability-list i { color: var(--icon-ink); font-size: 1.15rem; }

.factory-photo {
  min-height: var(--factory-min-height); border-radius: var(--radius-card);
  background:
    var(--factory-overlay),
    var(--factory-image, none) center / cover no-repeat,
    var(--factory-bg);
}

.process-number {
  width: 42px; height: 42px;
  display: inline-grid; place-items: center;
  border-radius: var(--radius);
  background: var(--step-bg); color: var(--step-ink); font-weight: var(--fw-display);
  box-shadow: var(--step-shadow);
}

/* ==========================================================================
   7. Quote band and forms
   ========================================================================== */

.quote-band { background: var(--panel-texture), var(--panel); color: var(--on-brand); padding: var(--quote-band-padding); }
.quote-form {
  background: var(--quote-form-bg); color: var(--ink);
  border-radius: var(--radius-card);
  border: 1px solid var(--quote-form-border);
  box-shadow: var(--shadow-form);
}
.form-control, .form-select { border-radius: var(--radius-control); border-color: var(--control-border); min-height: var(--control-min-height); }
.form-control:focus, .form-select:focus {
  border-color: var(--control-focus-border);
  box-shadow: var(--ring);
}
.form-label {
  font-weight: var(--fw-form-label);
  font-size: var(--label-size);
  color: var(--label-ink);
  text-transform: var(--label-transform);
  letter-spacing: var(--label-tracking);
}
.form-check-input:checked { background-color: var(--brand); border-color: var(--brand); }
.form-check-input:focus { border-color: var(--control-focus-border); box-shadow: var(--ring); }

/* ==========================================================================
   8. Page header and breadcrumb
   ========================================================================== */

.page-header {
  background:
    var(--page-header-texture),
    var(--page-header-overlay),
    var(--page-header-image, none) center / cover no-repeat,
    var(--page-header-bg);
  color: var(--page-header-ink);
  padding: var(--page-header-padding);
  border: 0;
  border-bottom: var(--page-header-border-bottom);
  /* Vertical centring for every banner. It only becomes visible once the band
     is taller than its content — a min-height, or an Elementor/child theme
     height — but it is set here so any such band centres without extra rules. */
  display: flex;
  align-items: center;
}
/* Required by the flex centring above: as a flex item the container would
   shrink to its text, and its own margin-inline: auto would then pull the title
   to the horizontal centre. */
.page-header > .container { width: 100%; }
.page-header h1 { font-weight: var(--fw-display); font-size: var(--page-title-size); letter-spacing: var(--tracking-display); margin: 0; }
.page-header .lead { color: var(--page-header-lead-ink); max-width: 780px; margin-top: .8rem; }

/* Taller banner on single posts. Scoped to .single-post, not .single, so
   products and other single post types keep the content-sized band. */
.single-post .page-header { min-height: var(--page-header-single-min-height); }

/* The band's stand-in when "Show page-header with big title" is off. Nothing here
   paints a background: the heading moves into the breadcrumb's last item, or into
   the article on a single post, and only the sub-heading keeps a block of its own.
   Bottom padding is left at zero deliberately, so the gap below is the top padding
   of whatever follows (.pf-content's --page-padding) rather than the two added. */
.pf-page-lead { padding: var(--page-lead-padding); }
.pf-page-lead .lead { color: var(--page-lead-ink); max-width: 780px; margin: 0; }

/* The <h1> inside .breadcrumb-item.active. Sized and weighted to the trail, so
   the trail still reads as a trail — `display: inline` keeps it on the same line
   as the separators either side of it. */
.breadcrumb-title {
  display: inline;
  font-size: var(--breadcrumb-title-size); font-weight: var(--breadcrumb-title-weight);
  color: var(--breadcrumb-title-ink); letter-spacing: inherit; line-height: inherit;
  margin: 0;
}

/* A single post's own heading, above its category and date line. */
.entry > .entry-title {
  font-weight: var(--fw-display); font-size: var(--entry-title-size);
  letter-spacing: var(--tracking-display); margin: 0 0 .6rem;
}

.breadcrumb-wrap {
  background: var(--breadcrumb-bg); border-bottom: 1px solid var(--line); padding: .8rem 0; font-size: .9rem;
}
.breadcrumb-wrap .breadcrumb { margin: 0; }
.breadcrumb-item a { color: var(--brand-dark); text-decoration: none; }
.breadcrumb-item a:hover { text-decoration: underline; }
.breadcrumb-item.active { color: var(--muted); }
.breadcrumb-item + .breadcrumb-item::before { color: var(--breadcrumb-divider-ink); }

/* ==========================================================================
   9. Product detail
   ========================================================================== */

.product-gallery-main {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius-card); border: 1px solid var(--line);
  background: var(--surface-alt);
}
.thumb-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; margin-top: .6rem; }
.thumb-row img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--radius-media);
  border: 2px solid transparent; cursor: pointer; transition: border-color .15s;
}
.thumb-row img.active, .thumb-row img:hover { border-color: var(--brand); }
.price-block {
  border: 1px solid var(--price-block-border);
  border-left: var(--price-block-edge);
  border-radius: var(--radius-card); padding: 1.2rem 1.4rem;
  background: var(--price-block-bg); margin: 1rem 0 1.4rem;
}

/* The specification table is what closes the sale, so it is treated as a
   datasheet: a label column on the left, quiet rules, and cell padding set
   through Bootstrap's own table variables. */
.spec-table, table.shop_attributes { border-color: var(--line); }
.spec-table th, table.shop_attributes th {
  width: var(--spec-label-width);
  background: var(--spec-label-bg);
  color: var(--spec-label-ink);
  font-weight: var(--fw-table-label);
  font-size: var(--spec-label-size);
  text-transform: var(--spec-label-transform);
  letter-spacing: var(--spec-label-tracking);
}
.spec-table td, table.shop_attributes td { color: var(--spec-value-ink); }

/* ==========================================================================
   10. Blog
   ========================================================================== */

/* The category/tag description, from playforge_archive_intro(). It sits inside
   .pf-main-col, directly above the card grid, so it needs no width of its own —
   the column already gives it one, and that shared left edge is the whole point of
   putting it there rather than in the full-width lead band. Only the gap below it
   and the prose treatment are set here. */
.pf-archive-intro {
  max-width: var(--prose-width);
  margin-bottom: var(--archive-intro-gap);
  color: var(--ink-prose);
}
/* A description is authored text, so it can arrive as more than one paragraph, a
   list or a heading. Trimming the outer margins keeps the first line level with
   the top of the column and stops a trailing margin from doubling the gap above
   the grid. */
.pf-archive-intro > :first-child { margin-top: 0; }
.pf-archive-intro > :last-child { margin-bottom: 0; }
.pf-archive-intro p,
.pf-archive-intro ul,
.pf-archive-intro ol { line-height: var(--prose-line-height); font-size: var(--prose-size); }
.pf-archive-intro a { color: var(--prose-link-ink); }

.blog-card { border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; background: var(--card-bg); height: 100%; box-shadow: var(--shadow-card); transition: transform .2s, box-shadow .2s, border-color .2s; }
.blog-card:hover { transform: var(--blog-hover-lift); box-shadow: var(--shadow-blog-hover); border-color: var(--card-hover-border); }
.blog-card img { width: 100%; height: var(--blog-image-height); object-fit: cover; }
.blog-card .meta { font-size: .82rem; color: var(--muted); }
.blog-body { max-width: var(--prose-width); }
.blog-body h2 { font-weight: var(--fw-prose-heading); margin: 2rem 0 1rem; }
.blog-body h3 { font-weight: var(--fw-prose-heading); margin: 1.6rem 0 .9rem; }
.blog-body p { line-height: var(--prose-line-height); color: var(--ink-prose); font-size: var(--prose-size); }
.blog-body blockquote { border-left: 4px solid var(--brand); padding-left: 1rem; color: var(--ink-quote); font-style: italic; }
.blog-body ul, .blog-body ol { line-height: var(--prose-line-height); color: var(--ink-prose); }

/* Inside prose, links can take a colour of their own — set --prose-link-ink.
   Long specification and compliance copy is easier to scan when links are
   colour-coded rather than only underlined.

   Buttons are excluded, in two flavours.

   .btn: these selectors are one step more specific than Bootstrap's .btn, so
   without the exclusion an <a class="btn"> anywhere in the content area lost the
   colour its variant sets and took --prose-link-ink instead — which defaults to
   `inherit`, i.e. body ink on a brand-filled button. The homepage's own sections
   all sit inside .pf-content, so that is where it showed worst.

   .wp-element-button: the same failure, via a block button. WordPress core
   prints its own default for those inline, as

     :root :where(.wp-element-button, .wp-block-button__link)
       { background-color: #32373c; color: #fff }

   and :where() contributes NO specificity, so that selector weighs only (0,1,0).
   Nothing else sets a background, so #32373c survives — but its color: #fff lost
   to the (0,2,1) selectors here, and the label took --prose-link-ink on top of a
   near-black fill. The block cart's Proceed to Checkout is the case that matters:
   it is an <a class="wc-block-components-button wp-element-button
   wc-block-cart__submit-button contained">, so it is a prose link as far as the
   cascade is concerned. Under this theme --prose-link-ink is `inherit`, i.e. body
   ink, which put roughly 1.2:1 dark-on-dark text in the primary checkout CTA.
   Excluding the class here fixes it for this theme and every child at once,
   whatever each one sets --prose-link-ink to. */
.blog-body a:not(.btn):not(.wp-element-button),
.pf-content a:not(.btn):not(.wp-element-button),
.entry-content a:not(.btn):not(.wp-element-button) { color: var(--prose-link-ink); }

/* Centre the reading column only when there is no sidebar beside it. */
.pf-layout-full-box .blog-body,
.pf-layout-full-screen .blog-body { margin-inline: auto; }

/* ==========================================================================
   11. Footer
   ========================================================================== */

.footer {
  background: var(--footer-texture), var(--panel-deep);
  color: var(--footer-ink);
  padding: 3rem 0 2rem;
  border-top: var(--footer-border-top);
}
.footer h6, .footer .brand-name { color: var(--footer-heading-ink); }
.footer a { color: var(--footer-link-ink); text-decoration: none; }
.footer a:hover { color: var(--surface); }
.footer i { color: var(--footer-icon-ink); }
.footer img { max-height: 52px; width: auto; height: auto; }
.footer .widget { margin-bottom: 1.5rem; }
.footer ul { list-style: none; padding: 0; margin: 0; }
.footer ul li { padding: .2rem 0; }

.pf-license-notice {
  background: var(--notice-bg);
  border-top: 1px solid var(--notice-border);
  color: var(--notice-ink);
  padding: .75rem 0;
  font-size: .875rem;
  text-align: center;
}

/* ==========================================================================
   12. Floating CTA
   ========================================================================== */

.float-cta {
  position: fixed; right: 20px; bottom: 20px; z-index: 999;
  display: grid; gap: .5rem;
}
.float-cta a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: var(--radius-float);
  background: var(--brand); color: var(--on-brand); font-size: 1.3rem;
  box-shadow: var(--shadow-float);
  text-decoration: none; transition: transform .15s, background .15s;
}
.float-cta a:hover { transform: scale(1.08); background: var(--brand-dark); }
.float-cta a.whatsapp { background: var(--whatsapp); }
.float-cta a.whatsapp:hover { background: var(--whatsapp-hover); }
.float-cta a.email { background: var(--accent); color: var(--on-accent); }

/* ==========================================================================
   13. Static map thumbnail
   ========================================================================== */

.map-static { position: relative; overflow: hidden; border-radius: var(--radius-card); text-decoration: none; display: block; }
.map-static img {
  display: block; width: 100%; height: auto; max-height: 460px; object-fit: cover;
  transition: transform .35s ease;
}
.map-static:hover img { transform: scale(1.02); }
.map-static__hint {
  position: absolute; left: 50%; bottom: 1rem; transform: translateX(-50%);
  background: var(--map-hint-bg); color: var(--on-brand);
  padding: .5rem 1rem; border-radius: var(--radius-pill);
  font-size: .9rem; font-weight: var(--map-hint-weight);
  box-shadow: var(--shadow-float);
  max-width: calc(100% - 2rem);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ==========================================================================
   14. Layout system
   ========================================================================== */

/* Boxed width. Bootstrap's .container steps its max-width up per breakpoint;
   min() keeps those steps while letting --box-width cap them, so a narrower
   token narrows every breakpoint and a wider one only takes effect at 1400px,
   where the step is the token itself. */
@media (min-width: 576px)  { .container { max-width: min(540px, var(--box-width)); } }
@media (min-width: 768px)  { .container { max-width: min(720px, var(--box-width)); } }
@media (min-width: 992px)  { .container { max-width: min(960px, var(--box-width)); } }
@media (min-width: 1200px) { .container { max-width: min(1140px, var(--box-width)); } }
@media (min-width: 1400px) { .container { max-width: var(--box-width); } }

.pf-content { padding: var(--page-padding); margin: var(--page-margin); }
.pf-layout-full-screen > .pf-container-fluid { width: 100%; padding-inline: 0; }

/* Sidebar width. The markup carries col-lg-4/col-lg-8 (or three col-lg-4) — the
   twelfth-grid splits Bootstrap can express, the closest it gets — and this
   overrides them from the two width tokens so the columns in a row can never
   disagree about how much is left. The main column's rule depends on which sides
   are present, which is what the .pf-row--sidebar-* modifier on the row names.
   Scoped to .row so the class-less <aside> in sidebar.php / sidebar-right.php,
   used outside the grid, is untouched. Below 992px Bootstrap's own stacking
   applies and section 19 spaces it. */
@media (min-width: 992px) {
  .row > .pf-sidebar {
    flex: 0 0 auto;
    width: var(--sidebar-width);
  }

  .row > .pf-sidebar--right {
    width: var(--sidebar-width-right);
  }

  .row > .pf-main-col {
    flex: 0 0 auto;
    width: calc(100% - var(--sidebar-width));
  }

  /* Equal specificity to the rule above, so these must stay after it to win. */
  .pf-row--sidebar-right > .pf-main-col {
    width: calc(100% - var(--sidebar-width-right));
  }

  .pf-row--sidebar-both > .pf-main-col {
    width: calc(100% - var(--sidebar-width) - var(--sidebar-width-right));
  }
}

/* The edge-to-edge three-column layouts. Unlike .pf-layout-full-screen they keep
   side padding: the row inside pulls its columns 1.5rem outwards with the g-5
   gutter, and without room for that the first and last columns would sit past the
   viewport edge. max() enforces that floor whatever a child theme sets the token
   to, so the layout cannot be given a horizontal scrollbar by retuning it. */
.pf-layout-full-screen-with-left-and-right-sidebar > .pf-container-fluid,
.pf-layout-woo-full-screen-with-left-and-right-sidebar > .pf-container-fluid {
  width: 100%;
  padding-inline: max(1.5rem, var(--fullscreen-sidebar-gutter));
}

/* The two Elementor layouts share one idea — none of the theme's own spacing,
   so the design starts flush against the navbar — and differ only in width.
   Both are compounded with .pf-content on purpose: the narrow-screen
   --page-padding retune further down this file would otherwise win, being the
   later rule at equal specificity. */
.pf-content.pf-layout-elementor-full-canvas { padding: 0; margin: 0; }
/* Boxed clears the vertical spacing only, so the content still sits inside the
   container's gutters — and any side values in --page-padding survive. Its
   width comes from .container above, i.e. from --box-width. */
.pf-content.pf-layout-elementor-boxed { padding-block: 0; margin-block: 0; }

.pf-layout-elementor-full-canvas > .pf-container-fluid { width: 100%; padding-inline: 0; }

.pf-layout-elementor-full-canvas .entry,
.pf-layout-elementor-full-canvas .entry-content { margin: 0; padding: 0; }
.pf-layout-elementor-boxed .entry,
.pf-layout-elementor-boxed .entry-content { margin-block: 0; padding-block: 0; }
/* A leading or trailing block margin would reintroduce the gap the layouts are
   meant to remove. */
.pf-layout-elementor-full-canvas .entry-content > :first-child,
.pf-layout-elementor-boxed .entry-content > :first-child { margin-top: 0; }
.pf-layout-elementor-full-canvas .entry-content > :last-child,
.pf-layout-elementor-boxed .entry-content > :last-child { margin-bottom: 0; }
.pf-sidebar .widget {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 1.25rem 1.4rem;
  margin-bottom: 1.5rem;
  background: var(--card-bg);
  box-shadow: var(--shadow-card);
}
.pf-sidebar .widget-title {
  font-weight: var(--fw-widget-title);
  font-size: var(--widget-title-size);
  color: var(--widget-title-ink);
  margin-bottom: .9rem;
  padding-bottom: .6rem;
  border-bottom: var(--widget-title-border);
}
.pf-sidebar ul { list-style: none; padding: 0; margin: 0; }
.pf-sidebar ul li { padding: .35rem 0; border-bottom: 1px solid var(--widget-divider); }
.pf-sidebar ul li:last-child { border-bottom: 0; }
.pf-sidebar a { text-decoration: none; }
.pf-sidebar a:hover { color: var(--brand); }

/* Hierarchy in widget lists. wp_list_categories, wp_list_pages and the Categories
   block all nest with ul.children; nav menus use ul.sub-menu; WooCommerce's product
   categories block nests a second list of its own class and ships no indent rule of
   its own, leaning on the browser default. The blanket `padding: 0` above strips
   that default, so without the rules below a subcategory sits flush with its parent
   and the whole tree reads as one flat column. The selectors are descendant rather
   than child, so the indent compounds: a third level lands two steps in. */
.pf-sidebar ul .children,
.pf-sidebar ul .sub-menu,
.pf-sidebar .wc-block-product-categories-list .wc-block-product-categories-list {
  margin-top: .35rem;
  padding-left: var(--widget-nest-indent);
  border-left: var(--widget-nest-guide);
}

/* The row rhythm belongs to the top level. A divider under each child would carry
   the same weight as the dividers between parents, which is the other half of what
   flattens the tree — the guide line separates children instead. */
.pf-sidebar ul .children li,
.pf-sidebar ul .sub-menu li,
.pf-sidebar .wc-block-product-categories-list .wc-block-product-categories-list li {
  padding-block: .2rem;
  border-bottom: 0;
}
.pf-sidebar ul .children > li > a,
.pf-sidebar ul .sub-menu > li > a,
.pf-sidebar .wc-block-product-categories-list .wc-block-product-categories-list > li > a {
  font-size: var(--widget-nest-size);
  color: var(--widget-nest-ink);
}
/* The quietened colour above out-specifies the shared `.pf-sidebar a:hover`, so the
   hover has to be restated at this depth or child rows stop responding to the
   pointer while their parents still do. */
.pf-sidebar ul .children > li > a:hover,
.pf-sidebar ul .sub-menu > li > a:hover,
.pf-sidebar .wc-block-product-categories-list .wc-block-product-categories-list > li > a:hover {
  color: var(--brand);
}

/* A term holding children reads a step heavier than the children under it, so the
   eye can find the top of each group. Categories get no has-children class from
   WordPress the way pages and menu items do, so :has() is the only way to reach
   them; where it is unsupported the indent and guide line still carry the nesting. */
.pf-sidebar ul li:has(> .children) > a,
.pf-sidebar ul li:has(> .sub-menu) > a,
.pf-sidebar li:has(> .wc-block-product-categories-list) > a {
  font-weight: var(--widget-parent-weight);
}

/* ==========================================================================
   15. Pagination
   ========================================================================== */

.pf-pagination { margin-top: 3rem; }
.pf-pagination .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 42px; height: 42px; padding: 0 .75rem;
  border: 1px solid var(--line); border-radius: var(--radius-btn);
  margin: 0 .2rem; font-weight: var(--fw-pagination); text-decoration: none;
  color: var(--brand-dark); background: var(--surface);
}
.pf-pagination .page-numbers:hover { background: var(--pagination-hover-bg); border-color: var(--pagination-hover-border); color: var(--pagination-hover-ink); }
.pf-pagination .page-numbers.current { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.pf-pagination .page-numbers.dots { border-color: transparent; background: transparent; }

/* Client-side Prev/Next pager, carried over from the Hugo theme. */
.js-pager button:disabled { opacity: .45; }

/* ==========================================================================
   16. Comments
   ========================================================================== */

.comment-list { list-style: none; padding: 0; margin: 0; }
.comment-list .children { list-style: none; padding-left: 1.5rem; }
.comment-body {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
  background: var(--card-bg);
  box-shadow: var(--shadow-card);
}
.comment-author img { border-radius: 50%; margin-right: .6rem; }
.comment-author .fn { font-weight: var(--fw-prose-heading); font-style: normal; }
.comment-metadata { font-size: .82rem; color: var(--muted); }
.comment-metadata a { text-decoration: none; }
.bypostauthor > .comment-body { border-left: 3px solid var(--brand); }

/* ==========================================================================
   17. WordPress core content classes
   ========================================================================== */

.screen-reader-text {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
  word-wrap: normal !important;
}
.screen-reader-text:focus {
  background-color: var(--surface);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-skiplink);
  clip-path: none;
  color: var(--brand-dark);
  display: block;
  font-size: .875rem;
  font-weight: var(--fw-bold);
  height: auto;
  left: 5px;
  line-height: normal;
  padding: 15px 23px 14px;
  text-decoration: none;
  top: 5px;
  width: auto;
  z-index: 100000;
}

.alignnone { margin: .5rem 1rem 1rem 0; }
.aligncenter, div.aligncenter { display: block; margin: .5rem auto 1rem; }
.alignright { float: right; margin: .5rem 0 1rem 1rem; }
.alignleft { float: left; margin: .5rem 1rem 1rem 0; }
.alignwide { max-width: var(--alignwide-width); margin-inline: auto; }
.alignfull { max-width: 100%; margin-inline: 0; }

.wp-caption { max-width: 100%; }
.wp-caption img { height: auto; max-width: 100%; }
.wp-caption-text, .wp-block-image figcaption {
  font-size: .85rem; color: var(--muted); text-align: center; padding: .6rem 0;
}

.sticky .blog-card { border-color: var(--brand); }

.gallery { display: flex; flex-wrap: wrap; gap: .5rem; }
.gallery-item { flex: 1 1 30%; }
.gallery-caption { font-size: .85rem; color: var(--muted); }

embed, iframe, object, img { max-width: 100%; }
.wp-block-embed iframe { width: 100%; }

/* Match core block editor widths to the theme container. */
.entry-content > * { max-width: 100%; }

/* ==========================================================================
   18. Homepage builder
   ========================================================================== */

/* The five sections carry their own padding through .pf-section, so the wrapper
   contributes none — otherwise the first section's padding is stacked on the
   content area's and the banner sits away from the navbar. Compounded with
   .pf-content for the same reason the Elementor layouts are: the narrow-screen
   --page-padding retune in section 19 would otherwise win at equal specificity. */
.pf-content.pf-layout-homepage { padding: 0; margin: 0; }

/* Two adjacent bands would read as one tall block, so a band following a band
   keeps a visible seam. */
.pf-layout-homepage .band + .band { border-top: 1px solid var(--line); }

/* Banner content is edge to edge and supplies its own spacing — a shortcode's
   slider or hero, or markup pasted into the field. */
.pf-home-banner > :first-child { margin-top: 0; }
.pf-home-banner > :last-child { margin-bottom: 0; }

/* The custom HTML slots are treated the same way: no padding, no container, no
   assumptions — whatever is typed into the field supplies its own layout. Only the
   outer margins are collapsed so a slot cannot open a gap the author did not ask for.
   The .band + .band seam above matches siblings only, so a band written inside a slot
   sits next to the slot's wrapper rather than next to the neighbouring section; the
   three selectors below carry the seam across that wrapper. */
.pf-home-html > :first-child { margin-top: 0; }
.pf-home-html > :last-child { margin-bottom: 0; }

.pf-layout-homepage .band + .pf-home-html > .band:first-child,
.pf-layout-homepage .pf-home-html:has(> .band:last-child) + .band,
.pf-layout-homepage .pf-home-html:has(> .band:last-child) + .pf-home-html > .band:first-child {
  border-top: 1px solid var(--line);
}

/* --- Product category cards -------------------------------------------- */

/* The card holds three destinations — the image and the heading go to the
   category, each subcategory goes to its own archive — so it is a plain article
   with several links rather than one link wrapping everything, the way the
   product cards are built. See template-parts/home/product-categories.php. */

/* The image sits in an anchor of its own, which is inline by default and would
   leave a strip of line-box whitespace between the picture and the card body. */
.pf-cat-image { display: block; }

.pf-cat-name a { color: var(--ink); }
.pf-cat-name a:hover { color: var(--brand-dark); }

/* The arrow carries the brand colour the removed "View products" line used to,
   so the heading still reads as the way into the category. */
.pf-cat-name .bi-arrow-right {
  color: var(--brand);
  transition: transform .2s;
}
.pf-cat-card:hover .bi-arrow-right { transform: translateX(3px); }

/* The subcategory list, one per line. It is printed even when a category has no
   subcategories, because min-height is what keeps the cards in a row the same
   height and their images on a common baseline — three lines' worth, so the
   usual short list does not change the row's height at all.

   The line count and the leading are named rather than folded into one number so
   a child theme can reserve four lines by redefining --pf-cat-sub-lines alone. */
.pf-cat-subs {
  --pf-cat-sub-lines: 3;
  --pf-cat-sub-leading: 1.7;
  list-style: none;
  margin: .75rem 0 0;
  padding: 0;
  font-size: .9rem;
  line-height: var(--pf-cat-sub-leading);
  min-height: calc(var(--pf-cat-sub-lines) * var(--pf-cat-sub-leading) * 1em);
}

.pf-cat-subs a {
  color: var(--muted);
  text-decoration: none;
  transition: color .15s ease;
}

.pf-cat-subs a:hover,
.pf-cat-subs a:focus-visible {
  color: var(--brand-dark);
  text-decoration: underline;
}

/* --- Tabs -------------------------------------------------------------- */

/* Shared by Editor's Choice and the tabbed form of Latest News. Each section also
   carries its own class (.pf-editor-tab, .pf-news-tab) for styling one without the
   other, but everything common lives here and the script binds to these. */

/* A centred row of category names that wraps on a narrow screen rather than
   scrolling, because four to six short names fit two lines and a scrolling strip
   hides the ones a visitor has not thought to look for. */
.pf-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .5rem;
  margin-bottom: 2.5rem;
}

.pf-tab {
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  padding: .55rem 1.35rem;
  font-weight: var(--fw-btn);
  letter-spacing: var(--tracking-btn);
  line-height: 1.4;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.pf-tab:hover,
.pf-tab:focus-visible {
  border-color: var(--brand-ring);
  background: var(--brand-tint);
  color: var(--brand-dark);
}

/* The open tab, whether the pointer is on it or not — hover alone would leave no
   indication of which panel is showing once the pointer moves away. */
.pf-tab.is-active {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}

/* The panels all occupy the same space, so switching must not move the page. Only
   one is ever in the flow: the others carry the `hidden` attribute, which the
   product grid's `display: grid` would otherwise override. */
.pf-tab-panel[hidden] { display: none; }

/* --- About Us media --------------------------------------------------- */

.pf-home-about-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--home-media-radius);
  box-shadow: var(--home-media-shadow);
}

.pf-home-about-body > :last-child { margin-bottom: 0; }

/* The video facade. Bootstrap's .ratio stretches every child to fill the frame,
   which is what the poster, the button and the swapped-in iframe all want. */
.pf-home-video {
  border-radius: var(--home-media-radius);
  box-shadow: var(--home-media-shadow);
  overflow: hidden;
}

.pf-home-video-poster { width: 100%; height: 100%; object-fit: cover; }

.pf-home-video-play {
  display: grid;
  place-items: center;
  border: 0;
  padding: 0;
  cursor: pointer;
  /* A scrim over the poster, so a light still cannot swallow the button. */
  background: var(--home-video-scrim);
}

.pf-home-video-play i {
  width: var(--home-play-size);
  height: var(--home-play-size);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--home-play-bg);
  color: var(--home-play-ink);
  font-size: calc(var(--home-play-size) * .45);
  box-shadow: var(--home-play-shadow);
  transition: transform .2s, background-color .2s;
}

.pf-home-video-play:hover i,
.pf-home-video-play:focus-visible i {
  background: var(--home-play-hover-bg);
  transform: scale(1.08);
}

/* The iframe replaces the poster and the button once a visitor clicks. */
.pf-home-video iframe { width: 100%; height: 100%; border: 0; }

/* ==========================================================================
   19. Responsive
   ========================================================================== */

@media (max-width: 991.98px) {
  .hero { min-height: auto; background-position: 62% center; }
  .hero-content { padding: 4rem 0 5.5rem; }
  .metric-row { grid-template-columns: 1fr; }
  .factory-photo { min-height: var(--factory-min-height-md); }
  .pf-sidebar { margin-top: 3rem; }

  /* Stacked, two sidebars would push the content a screenful down, so the main
     column comes first here. Only for the three-column layouts: the two-column
     ones keep their long-standing order, where a left sidebar stacks above. */
  .pf-row--sidebar-both > .pf-main-col { order: -1; }
}

@media (max-width: 575.98px) {
  /* Narrow-screen spacing is applied to the rules, not by retuning the tokens
     they read. A child theme's :root sets --page-padding unconditionally and
     would outrank a token retuned inside this media query, quietly restoring
     the wide-screen value on phones; the rules below cannot be lost that way,
     and each has its own token for a child that wants a different phone value.
     .pf-content.pf-layout-elementor-* stays a compound selector so it still
     outranks the bare .pf-content here. */
  .pf-content { padding: var(--page-padding-sm); }
  .pf-section { padding: var(--section-padding-sm); }
  .quote-band { padding: var(--quote-band-padding-sm); }
  .page-header { padding: var(--page-header-padding-sm); }
  .top-strip .container { justify-content: center !important; text-align: center; }
  .hero h1 { font-size: var(--hero-title-size-sm); }
  .hero .d-flex { align-items: stretch !important; }
  .hero .btn { width: 100%; }
  .float-cta a { width: 46px; height: 46px; font-size: 1.1rem; }
  .spec-table th, table.shop_attributes th { width: var(--spec-label-width-sm); }
  /* Set on the rule rather than by retuning --home-play-size, for the reason at
     the top of this block. */
  .pf-home-video-play i {
    width: var(--home-play-size-sm);
    height: var(--home-play-size-sm);
    font-size: calc(var(--home-play-size-sm) * .45);
  }
}
