/**
 * R3.7A.1A-R1/R4/R6/R8/R11: centralized semantic CSS for the Portfolio Archive Template (Elementor
 * Template 3160) and Project Archive Card Loop Item (Elementor Loop Item 3157) -- the minimum
 * needed for Chrome to remove the remaining element-level Custom CSS on both while preserving the
 * current visual output.
 *
 * Reuses the same --fgma-* design-system custom properties and gutter/spacing conventions already
 * established elsewhere on fgmadev (--fgma-gutter, --fgma-space-xs/sm/lg, --fgma-step-0/1/2/3,
 * --fgma-content-max, --fgma-media-ratio) rather than any new arbitrary value -- no px/rem literal
 * is introduced here, and `margin-inline: auto` is a structural keyword, not a design value, so it
 * is exempt from that rule.
 *
 * The card media crop (R3.7A.1A-R4) reuses `--fgma-media-ratio` (confirmed live = `3 / 2`) and the
 * exact position/overflow/object-fit idiom already proven live by `.fgma-featured-projects__card-
 * media` / `__card-image` -- not a new pattern invented for this card.
 *
 * R3.7A.1A-R6 specificity fix: the Hero and Results-shell root elements are both Elementor `.e-con`
 * Containers that are DIRECT CHILDREN of the root `[data-elementor-id]` element, so both are also
 * matched by two of Elementor's own base rules, confirmed directly from the live generated CSS:
 *   - `.elementor .e-flexbox-base{padding:10px;...}` (base-desktop.css) -- (0,2,0)
 *   - `:is(.elementor-section-wrap,[data-elementor-id])>.e-con{...;max-width:min(100%,var(--width))}`
 *     (elementor/assets/css/frontend.min.css) -- (0,2,0)
 * Our own plain `.fgma-portfolio-archive-hero`/`-results` class alone is only (0,1,0) and loses. The
 * mathematically minimal fix is a 3-class compound selector -- (0,3,0), strictly greater than (0,2,0)
 * so it wins regardless of stylesheet load order, never a tie -- built from the FGMA semantic class
 * plus the real, stable, non-generated `.elementor`/`.e-con` structural classes already confirmed
 * present on these exact elements in the live DOM. No `.elementor-element-XXXXXXXX` generated class,
 * no ID, no `!important` anywhere in this file.
 *
 * R3.7D.1 Portfolio Archive: the `.fgma-portfolio-archive-results .elementor-widget-loop-grid
 * .elementor-grid{gap:var(--fgma-space-sm);}` override this section originally documented (R3.7A.1A)
 * is REMOVED, not corrected. It was an unrequested, incorrect override in the first place: Elementor's
 * own per-instance Loop Grid setting already sets `--grid-column-gap:40px;--grid-row-gap:70px` on the
 * widget (`.elementor-element-fedfebb`, confirmed live in post-3160.css) feeding directly into
 * Elementor's own `.elementor-widget-loop-grid .elementor-grid{grid-column-gap:var(--grid-column-gap,
 * 30px);grid-row-gap:var(--grid-row-gap,30px);...}` rule -- 40px is a near-exact match for
 * Production's own real, measured column gap at a comparable viewport (~41-42px; Production's own
 * `--space-lg` token, confirmed byte-identical to `--fgma-space-lg`, resolves to ~41px at 1372px --
 * the true source-of-truth token this project's own design system already shares with Production for
 * this gap, never guessed). This file's own `--fgma-space-sm` override was smaller than that,
 * visibly narrowing the column gap (measured ~21px on DEV vs Production's ~42px) and, in a fixed
 * 4-column grid at a fixed container width, correspondingly widening each card/image column (measured
 * ~290px on DEV vs Production's ~275px) -- removing the override restores both simultaneously, with
 * no separate card-width rule needed anywhere in this file.
 *
 * Color is otherwise deliberately never set here: the eyebrow/title/card-title treatment is a
 * Global Color already bound through each Elementor widget's own Style-tab controls, not a
 * Custom-CSS concern. The one exception is `.fgma-project-archive-card__meta` (R3.7A.1A-R11) --
 * the Shortcode widget it lives on has no native Style-tab/Global Color control at all, so there is
 * no Elementor-side binding available to own it instead; see that rule's own comment below.
 *
 * Scoped entirely to these eight semantic classes (plus the necessary compound/descendant selectors
 * documented above, and the `a`/`img` descendants of `.fgma-project-archive-card__media`, needed
 * because Elementor's Featured Image widget nests the real `<img>` two levels below the class Loop
 * Item 3157 actually carries); never an Elementor-generated selector, never an element-ID selector,
 * never `!important`, no new global z-index.
 */

/**
 * R3.7A.1-V9: the eyebrow-to-H1 gap was `var(--fgma-space-xs)` -- confirmed live via CDP to compute
 * to ~13.03px desktop / ~9.45px mobile, well short of Production's real ~25.85px desktop / ~17.96px
 * mobile. `--fgma-space-md` was confirmed live (same clamp-token family already used elsewhere in
 * this file) to compute to ~25.36px desktop / ~17.95px mobile -- essentially the exact Production
 * contract -- so it replaces `--fgma-space-xs` as the sole gap owner here. This is the Hero's own
 * flex `gap`, the one and only spacing owner between the eyebrow and H1 widgets; no Elementor margin
 * is added anywhere to compensate.
 */
.elementor .fgma-portfolio-archive-hero.e-con {
    display: flex;
    flex-direction: column;
    gap: var(--fgma-space-md);
    padding-block: var(--fgma-space-lg);
    padding-inline: var(--fgma-gutter);
    max-width: var(--fgma-content-max);
    margin-inline: auto;
}

.fgma-portfolio-archive-eyebrow {
    margin: 0;
    font-size: var(--fgma-step-1);
}

.fgma-portfolio-archive-title {
    margin: 0;
    font-size: var(--fgma-step-2);
}

/**
 * The results/grid shell. `padding-inline`/`max-width`/`margin-inline` are the outer Container's
 * own layout concerns (it is itself a direct-child `.e-con`, same cascade fight as the Hero above).
 * `gap` genuinely belongs on the actual grid element three levels deeper (`.elementor-loop-
 * container.elementor-grid`) -- deliberately left unowned by this file (see this file's own header
 * comment): Elementor's own per-instance Loop Grid setting already reproduces Production there.
 */
.elementor .fgma-portfolio-archive-results.e-con {
    padding-inline: var(--fgma-gutter);
    max-width: var(--fgma-content-max);
    margin-inline: auto;
}

/**
 * R3.7A.2M: `gap` neutralized to `0` (was `var(--fgma-space-xs)`) -- superseded by the shared
 * `fgma-archive.css` vertical-rhythm contract, which now owns media->title and title->meta spacing via
 * explicit `margin-block-start` on the title/meta elements themselves (`.fgma-project-archive-card__
 * title`/`.fgma-project-archive-card__meta`, compounded into that shared rule). Confirmed live this was
 * a genuine double-ownership risk, not hypothetical: leaving this `gap` at its old value would ADD on
 * top of the new explicit margins, producing visibly doubled spacing. `display: flex`/`flex-direction:
 * column` are kept -- still required for the card's own layout, and also now reinforced by the shared
 * `.elementor .fgma-project-archive-card.e-flexbox-base{gap:0;}` rule.
 */
.fgma-project-archive-card {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.fgma-project-archive-card__media {
    position: relative;
    display: block;
    overflow: hidden;
    aspect-ratio: var(--fgma-media-ratio);
}

.fgma-project-archive-card__media a {
    display: block;
    inline-size: 100%;
    block-size: 100%;
}

/**
 * R3.7A.1A-R8: the actual `<img>` needs `.elementor` compounded in here too -- confirmed live,
 * `.elementor img{height:auto;...}` (elementor/assets/css/frontend.min.css) and
 * `.elementor-widget-image img{display:inline-block;...}` (widget-image.min.css) are both (0,1,1),
 * an exact TIE with a plain `.fgma-project-archive-card__media img` rule (also (0,1,1)) -- which is
 * why the image previously stopped short of the frame (height resolved from its own intrinsic
 * ratio via Elementor's `height:auto`, not from this rule). `.elementor .fgma-project-archive-
 * card__media img` is (0,2,1), strictly greater, so it wins outright regardless of load order --
 * same fix shape as the R6 Hero/Results specificity fix. Physical `width`/`height` (not
 * `inline-size`/`block-size`) are used deliberately here so this rule maps onto the exact same
 * property Elementor's competing rule sets, leaving no logical/physical ambiguity.
 *
 * R3.7A.1-V5: `transition: transform` added here (same `.7s cubic-bezier(.4,0,.2,1)` curve already
 * proven live on `.fgma-featured-projects__card-image`, Customizer Additional CSS, post 2817) --
 * the real `<img>` is the actual hover-scale target now (see the R3.7A.1-V5 rules below), and it
 * previously had no transition of its own to smooth that scale.
 */
.elementor .fgma-project-archive-card__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .7s cubic-bezier(.4, 0, .2, 1);
}

/**
 * R3.7D.1 Portfolio Archive: `--fgma-step-3` was the wrong token, not merely a value regression --
 * Production's own real card-title contract (`.header-5{font-size:var(--step-2)}`, confirmed live
 * from Production's portfolio archive) uses `--step-2`, byte-identical to this project's own
 * `--fgma-step-2` (both `clamp(1.2656rem,1.1674rem + .4911vw,1.9531rem)`) -- the correct,
 * already-established token, never a new one. Elementor's own native per-instance heading size for
 * this same widget is a fixed `27px` (confirmed live in Loop Item 3157's own inline `<style>` tag,
 * `.elementor-3157 .elementor-element-bace6d3 .elementor-heading-title{font-size:27px;...}`) -- closer
 * than the old `--fgma-step-3` but still not Production's real, fluid, source-confirmed value, so the
 * override stays, corrected to the right token rather than removed outright.
 */
.fgma-project-archive-card__title {
    margin: 0;
    font-size: var(--fgma-step-2);
}

/**
 * R3.7A.1A-R11: the one deliberate exception to "color is never a Custom-CSS concern" above -- the
 * Elementor Shortcode widget (used for the `[fgma_project_practice_area]` metadata line) has no
 * native Style-tab/Global Color control at all, so there is no Elementor-side binding to own this
 * instead. Confirmed live in the Kit's own generated CSS (post-7.css, loaded on every page):
 * `:root { ...; --fgma-black:#000000; --fgma-off-black:#282828; --fgma-dark-gray:#555555;
 * --fgma-gray:#949494; ...; }` -- a plain, stable, directly-named custom property (not a generated
 * `--e-global-color-v4-*` Atomic Global Color identifier), reused here verbatim rather than the
 * hardcoded `#949494` it resolves to. `color` is an inherited property with the lowest cascade
 * priority, so a single class-selector declaration on the widget wrapper already unconditionally
 * beats the current plain `body` inheritance (confirmed: no rule anywhere sets `color` on
 * `.elementor-shortcode` itself) -- no compound Elementor-ancestor selector is needed here, unlike
 * the R6/R8 property-vs-property specificity fights above.
 *
 * R3.7A.1-V3: `font-size`/`line-height` corrected from `--fgma-step-1` (no line-height) to
 * `--fgma-step-0` + `line-height: 1.35` -- confirmed against Production's own real CSS contract for
 * the equivalent Practice Area metadata element (`.paragraph-sm`/`.paragraph-sm-bold`, read directly
 * from a live CDP style-resolution capture: `docs/visual-audit/evidence/network/phase-5b4-team-
 * deepdive-data.json`): `.paragraph-sm, .paragraph-sm-bold { font-size: var(--step-0);
 * line-height: 1.35; }`, with Production's own `--step-0: clamp(1rem,.9643rem + .1786vw,1.25rem)` --
 * byte-for-byte identical to fgmadev's already-existing `--fgma-step-0` token, so no new token is
 * introduced. `color`/`margin` are unchanged.
 *
 * R3.7Q-035C: `font-family`/`font-weight` were the one remaining gap -- this rule never set either,
 * so the Shortcode widget's own default rendered Roboto/system-stack instead of Production's real
 * Avenir Book. Both new declarations reuse the same `--fgma-font-family`/`--fgma-weight-book` tokens
 * already established elsewhere in this same file's own new-section filter-chip contract (see
 * `.fgma-portfolio-filter-option__link` below) -- no new token introduced. `font-size`/`line-height`/
 * `color`/`margin` are unchanged.
 */
.fgma-project-archive-card__meta {
    margin: 0;
    font-family: var(--fgma-font-family);
    font-weight: var(--fgma-weight-book);
    font-size: var(--fgma-step-0);
    line-height: 1.35;
    color: var(--fgma-gray);
}

/**
 * R3.7A.1-V3: title hover/focus color -- Loop Item 3157's title widget already carries both
 * `.fgma-project-archive-card__title` and `.fgma-featured-projects__card-title` (confirmed live), and
 * the outer card carries both `.fgma-project-archive-card` and `.fgma-featured-projects__card-link`
 * (a `<div>`, not an `<a>`, so `:focus-within` is used for keyboard support instead of `:focus`/
 * `:focus-visible`, which the div itself can never natively receive). The actual visible title text
 * sits two levels deeper still, on Elementor's own generated inner rule
 * `.elementor-3157 .elementor-element.elementor-element-bace6d3 .elementor-heading-title` (confirmed
 * live in the Loop Item's own inline `<style>` tag) -- specificity (0,4,0), which any plain
 * `__card-title:hover` rule loses to. Both Template/Post-ID classes in that generated rule
 * (`.elementor-3157`, `.elementor-element-bace6d3`) are forbidden here, so instead this compounds the
 * two already-confirmed-present stable semantic classes on both the outer card and the title widget,
 * reaching down to the real `.elementor-heading-title` element: (0,6,0), strictly greater than
 * (0,4,0), so it wins outright regardless of stylesheet load order. Reuses the same
 * `--e-global-color-v4-fgma-brand-red` token already proven live on the original Featured Projects
 * card hover (Customizer Additional CSS, post 2817) -- normal/non-hover title color is untouched,
 * still owned entirely by Elementor's own Style-tab Global Color binding.
 */
.fgma-project-archive-card.fgma-featured-projects__card-link:hover .fgma-project-archive-card__title.fgma-featured-projects__card-title .elementor-heading-title,
.fgma-project-archive-card.fgma-featured-projects__card-link:focus-within .fgma-project-archive-card__title.fgma-featured-projects__card-title .elementor-heading-title {
    color: var(--e-global-color-v4-fgma-brand-red);
}

/**
 * R3.7A.1-V5: neutralizes the inherited hover-zoom transform on the media WIDGET WRAPPER. Confirmed
 * live: Elementor's Featured Image widget puts `.fgma-project-archive-card__media`/`.fgma-featured-
 * projects__card-image` on the wrapper `<div>` itself (Loop Item 3157), not on the real `<img>` two
 * levels below it -- unlike the original hand-authored Featured Projects markup, where `.fgma-
 * featured-projects__card-image` is the `<img>` tag directly. The live Additional CSS rule
 * `.fgma-featured-projects__card-link:hover .fgma-featured-projects__card-image{transform:
 * scale(1.04);}` (post 2817) was written for that original `<img>`-is-the-class case, so on Portfolio
 * it instead scales the fixed-geometry frame/wrapper itself, visually escaping the card -- specificity
 * (0,3,0), loaded after this stylesheet in every real response (confirmed, same load-order fact as the
 * R3.7A.1B-R3 empty-state rule above). This rule reaches (0,4,0) via the same two already-confirmed
 * outer-card classes used by the title-hover fix above, strictly greater, so it wins outright
 * regardless of load order and resets the wrapper back to untransformed.
 */
.fgma-project-archive-card.fgma-featured-projects__card-link:hover .fgma-project-archive-card__media,
.fgma-project-archive-card.fgma-featured-projects__card-link:focus-within .fgma-project-archive-card__media {
    transform: none;
}

/**
 * R3.7A.1-V5: the real hover-zoom target -- the actual `<img>` nested inside the fixed, `overflow:
 * hidden` `.fgma-project-archive-card__media` frame (untouched above), matching the reference
 * Expertise/Featured-Projects contract (`.fgma-featured-projects__card-link:hover .fgma-featured-
 * projects__card-image{transform:scale(1.04);}`) exactly, just correctly re-scoped to the real
 * Portfolio `<img>` element instead of the widget wrapper it's nested under. The frame's own `aspect-
 * ratio`/`overflow: hidden` (unchanged above) keep the card's outer dimensions fixed and the scaled
 * image clipped; the `transition: transform` added to the base image rule above (same curve already
 * proven live) smooths both the zoom-in and the mouse-out return to `scale(1)`.
 */
.fgma-project-archive-card.fgma-featured-projects__card-link:hover .fgma-project-archive-card__media img,
.fgma-project-archive-card.fgma-featured-projects__card-link:focus-within .fgma-project-archive-card__media img {
    transform: scale(1.04);
}

/**
 * R3.7A.1B: `.fgma-portfolio-empty-state` -- `Portfolio_Empty_State_Renderer`'s own "No Results"
 * markup, new content Code renders that has no prior Elementor-owned styling to inherit. Reuses the
 * same design-system custom properties as every other rule in this file; no new literal value is
 * introduced.
 *
 * R3.7A.1B-R1: the R3.7A.1B `[data-fgma-portfolio-filter-group][aria-disabled="true"]` rule is
 * removed here, not carried forward -- `Portfolio_Filter_Controls_Renderer` now renders only
 * currently-available options (Production-parity "hide", not "disable"; see that class's own header
 * comment), so `aria-disabled` is never set on a filter option under the current architecture and the
 * rule would be permanently dead CSS.
 *
 * R3.7A.1B-R3: merged with the `.fgma-portfolio-empty-state` rule Chrome had been carrying in
 * Customizer -> Additional CSS (`color`/`font-size`/`padding-block`) -- that block loaded strictly
 * after this stylesheet in every real response (confirmed live: its own `<style>` tag appears later
 * in `<head>` than this file's `<link>`), so on this rule's identical class-selector specificity its
 * `font-size`/`padding-block` values were already the ones actually winning in production. Taking
 * them here, verbatim, keeps the merged rule's rendered result byte-for-byte identical to what was
 * already live -- this is a consolidation of ownership, not a redesign. `margin`/`text-align` are
 * carried forward unchanged from this file's own original rule (Additional CSS never set either).
 */
.fgma-portfolio-empty-state {
    margin: 0;
    text-align: center;
    color: var(--e-global-color-v4-fgma-gray);
    font-size: 1.1em;
    padding-block: var(--fgma-space-sm);
}

/**
 * R3.7A.1-V10: both V9 `.fgma-portfolio-filter-bar` rules were silently defeated live -- re-diagnosed
 * against fresh evidence rather than guessed:
 *
 * (1) `justify-content: space-between` never had any visible effect of its own: Elementor's own
 * "Global Class" stylesheet (`global-3160-frontend-desktop.css`, loaded after this file) carries
 * `.elementor .fgma-portfolio-filter-bar{flex-wrap:wrap;justify-content:space-between;align-items:
 * center;}` -- (0,2,0), strictly greater than V9's plain (0,1,0) selector, so IT was already winning
 * regardless, setting the identical `space-between` value PLUS an unrequested `flex-wrap: wrap`. Two
 * further confirmed-live per-instance rules (`local-3160-frontend-desktop.css`: `.elementor .e-
 * efd9125{width:50%;...align-items:end;}` on the trigger's own generated wrapper, `.elementor .e-
 * 5685616{width:50%;...}` on the chips wrapper) pin both children to an exact 50/50 split -- with that
 * `flex-wrap: wrap` also in effect, any sub-pixel overflow drops the trigger wrapper onto its own line,
 * where a lone item under `space-between` sits at flex-start (left) -- the exact reported regression.
 *
 * (2) `margin-block-end: var(--fgma-space-xl)` was fully defeated: Elementor's own base rule in
 * `frontend.min.css` (loaded after this file), `.e-con{margin-block-end:var(--margin-block-end);...}`,
 * is ALSO (0,1,0) -- an exact tie with V9's plain selector, so load order alone decided it, and
 * Elementor's later-loaded rule won, resolving to its own `--margin-block-end`/`--margin-bottom`
 * chain (`0px`, unconfirmed to be overridden anywhere for this element) -- our token never rendered.
 *
 * The actual flex item that is the direct child of `.fgma-portfolio-filter-bar` and wraps the Filter
 * trigger is confirmed live to be Elementor's own generated `e-efd9125` container (`.fgma-portfolio-
 * filter-trigger` itself sits one level deeper, inside it) -- a generated class, never referenceable
 * directly. `.fgma-portfolio-filter-bar > *:has(.fgma-portfolio-filter-trigger)` reaches that exact
 * element using only stable semantic classes and a standard CSS relational selector, no generated
 * class or ID anywhere. Its Elementor-set `width: 50%` must also be neutralized (a fixed 50/50 split
 * leaves zero free main-axis space for any auto margin to consume), reset to `width: auto` so the
 * wrapper shrinks to the button's own intrinsic size -- `margin-inline-start: auto` then consumes all
 * remaining row space, pinning the trigger flush right regardless of the (now width:auto, near-zero
 * when empty) chips wrapper's actual content -- exactly Production's own real, confirmed contract
 * (`margin-left: auto` on the Filter button itself). `flex-wrap: nowrap` neutralizes Elementor's
 * confirmed-live wrap rule so this never regresses back to the V9 failure mode.
 *
 * Confirmed live at the mobile breakpoint (`local-3160-frontend-mobile.css`, `max-width:767px`):
 * `.elementor .e-efd9125{width:100%}` / `.elementor .e-5685616{width:100%}` -- (0,2,0) -- would be
 * strictly beaten and overridden by an unscoped `width: auto` at (0,3,0), breaking the existing
 * mobile full-width contract. All three overrides below are therefore desktop-scoped
 * (`min-width: 768px`, the exact inverse of Elementor's own confirmed `max-width: 767px` mobile
 * boundary -- the established breakpoint convention already in use here) except the spacing fix,
 * which has no confirmed mobile-specific conflict and so stays universal.
 *
 * `.e-con` is compounded throughout to reach a specificity strictly greater than every confirmed
 * competing rule above -- (0,2,0) beats the (0,1,0) `frontend.min.css` base rules outright; `.elementor`
 * is additionally compounded on the flex-wrap/width/margin rules to reach (0,3,0), strictly beating
 * the (0,2,0) Global Class / per-instance rules regardless of load order, mirroring the established
 * R3.7A.1A-R6/R8 specificity-fix pattern used elsewhere in this file.
 */
.elementor .fgma-portfolio-filter-bar.e-con {
    margin-block-end: var(--fgma-space-xl);
}

@media (min-width: 768px) {
    .elementor .fgma-portfolio-filter-bar.e-con {
        flex-wrap: nowrap;
    }

    .elementor .fgma-portfolio-filter-bar > *:has(.fgma-portfolio-filter-trigger) {
        width: auto;
        margin-inline-start: auto;
    }
}

/**
 * R3.7A.1B-R3: CSS ownership migration -- the Portfolio filter-UI block Chrome had been carrying in
 * Customizer -> Additional CSS (added there during R3.7A.1B-R2's UI-prototype pass, marked "FGMA
 * Portfolio Filters -- added R3.7A.1B-R2 (Dynamic Elementor Filter UI Integration)" in that Additional
 * CSS field) now lives here instead, its final, permanent home. Every selector, every `--e-global-
 * color-v4-fgma-*`/`--fgma-*` token, and every value below is ported verbatim from that live block --
 * nothing redesigned, nothing invented. Targets exactly the semantic classes already established by
 * this block's own renderers (`Portfolio_Filter_Controls_Renderer`/`Portfolio_Active_Filters_
 * Renderer`) and by Chrome's own Elementor structure (`.fgma-portfolio-filter-trigger`/`-drawer`/
 * `-close`/`-apply`) -- no Elementor-generated element ID, no template/post ID, no `!important`, no
 * new z-index anywhere in it. Chrome removes the now-duplicated Additional CSS block once this
 * deploy is verified live (R3.7A.1B-R3 report section 9) -- until then the two are simply redundant
 * with each other, never conflicting (identical selectors, identical values).
 *
 * R3.7A.1B-R5 verification: re-diffed against the real WordPress revision history for the Customizer
 * Additional CSS post (`2817`) -- revision 3184 (2026-08-26 20:32, the exact revision immediately
 * before this block's own R3.7A.1B-R3 port) is the one and only authored state of the
 * "added R3.7A.1B-R2" block; there is no earlier revision containing any different version of it
 * (the immediately preceding revision, 3152 from 2026-08-25, has no such block at all -- it was
 * authored whole, in one edit, as 3184). That authoritative revision's own selected-option rule is
 * confirmed BYTE-IDENTICAL (modulo formatting) to `.fgma-portfolio-filter-option__link[aria-current]`
 * below -- filled `background`/`border-color: var(--e-global-color-v4-fgma-brand-red)`, `color: var(
 * --e-global-color-v4-fgma-white)` -- so that IS the authoritative original contract; it was never an
 * outlined red-on-white treatment at any point in this post's real revision history.
 *
 * Cascade re-verification: read the actual live-installed `elementor/assets/css/frontend.min.css` --
 * its own base default is the single-class `.elementor-button{background-color:#69727d;...}` (0,1,0
 * specificity); no compound default rule of equal-or-greater specificity exists for the plain
 * (non `-info`/`-success`/`-warning`/`-danger`) Button-widget skin these Trigger/Close/Apply controls
 * use. Every rule below that targets `.elementor-button` is already a real two-class descendant
 * selector (`.fgma-portfolio-filter-trigger .elementor-button`, etc., 0,2,0) -- strictly greater than
 * Elementor's own (0,1,0) default regardless of stylesheet load order, exactly like the existing
 * R3.7A.1A-R6/R8 specificity fixes elsewhere in this file. No additional compounding was needed or
 * added.
 */
.fgma-portfolio-filter-trigger .elementor-button {
    background: var(--e-global-color-v4-fgma-brand-red);
    color: var(--e-global-color-v4-fgma-white);
    border-radius: 999px;
    font-weight: 600;
}

.fgma-portfolio-filter-trigger .elementor-button:hover,
.fgma-portfolio-filter-trigger .elementor-button:focus-visible {
    background: var(--e-global-color-v4-fgma-red-hover);
    color: var(--e-global-color-v4-fgma-white);
}

.fgma-portfolio-filter-trigger .elementor-button:focus-visible {
    outline: 2px solid var(--e-global-color-v4-fgma-control-blue);
    outline-offset: 2px;
}

.fgma-portfolio-filter-apply .elementor-button {
    background: var(--e-global-color-v4-fgma-brand-red);
    color: var(--e-global-color-v4-fgma-white);
    border-radius: 999px;
    font-weight: 600;
    width: 100%;
}

.fgma-portfolio-filter-apply .elementor-button:hover,
.fgma-portfolio-filter-apply .elementor-button:focus-visible {
    background: var(--e-global-color-v4-fgma-red-hover);
}

.fgma-portfolio-filter-close .elementor-button {
    background: var(--e-global-color-v4-fgma-white);
    color: var(--e-global-color-v4-fgma-off-black);
    border: 1px solid var(--e-global-color-v4-fgma-light-gray);
    border-radius: 999px;
    font-weight: 600;
}

.fgma-portfolio-filter-close .elementor-button:hover,
.fgma-portfolio-filter-close .elementor-button:focus-visible {
    background: var(--e-global-color-v4-fgma-off-white);
}

.fgma-portfolio-filter-apply .elementor-button:focus-visible,
.fgma-portfolio-filter-close .elementor-button:focus-visible {
    outline: 2px solid var(--e-global-color-v4-fgma-control-blue);
    outline-offset: 2px;
}

.fgma-portfolio-filter-drawer {
    gap: var(--fgma-space-sm);
}

/**
 * R3.7A.F3: "Filter by:" left-aligned / Close X top-right. Confirmed live (`post-3160.css`):
 * `.elementor-element.elementor-element-f0fbd5a{--justify-content:space-evenly;...}` -- this header
 * row's own real, live Elementor per-instance setting -- feeds into a real property only via
 * `.elementor-element:where(.e-con-full,.elementor-widget){justify-content:var(--justify-content)}`
 * (`frontend.min.css`): the `:where()` wrapper always contributes ZERO selector specificity, no matter
 * what it wraps, so any selector here with non-zero specificity setting the LITERAL `justify-content`
 * property (never the `--justify-content` custom property itself, which is a separate, higher-
 * specificity fight not worth entering) wins outright regardless of load order. `space-evenly` was the
 * actual root cause of both reported symptoms at once: it pulls the Close control in from the edge by
 * the same gap it pushes the heading in from the opposite edge, so neither ever reaches its own true
 * edge. `space-between` pins the heading flush left and the Close control flush right -- top-right of
 * the drawer (this header is the drawer's first/top row), clearly separated from the heading.
 */
.fgma-portfolio-filter-drawer__header {
    justify-content: space-between;
    border-bottom: 1px solid var(--e-global-color-v4-fgma-light-gray);
}

/**
 * R3.7A.F3: footer CTA row -- Clear All (left) / Apply (right), each ~50% width, same row.
 * Confirmed live (`post-3160.css`): `.elementor-element.elementor-element-498886d{--display:flex;...}`
 * carries no `--flex-direction`/`--justify-content` override at all, so it falls through to
 * `.e-flex`'s own real default (`frontend.min.css`: `.e-flex{...flex-direction:column;...}`) -- a
 * single-column stack, which is why Apply alone currently renders full-width/full-row. `flex-
 * direction: row` (same `:where()`-bypass technique as the header fix above) puts both CTAs on one
 * row. Apply's own existing widget wrapper already carries the stable `.fgma-portfolio-filter-apply`
 * class directly (confirmed live); the drawer-footer Clear All Chrome places
 * (`[fgma_portfolio_clear_all]`, a Shortcode widget) will carry the real `.fgma-portfolio-filter-
 * clear-all` anchor one level *inside* its own generated widget wrapper -- exactly the same "real flex
 * item is a generated container, reached via a stable descendant class" shape the R3.7A.1-V10 Filter
 * CTA fix already solved, reused verbatim via the identical `:has()` technique (no generated ID/class
 * referenced). `order` guarantees Clear-All-first/Apply-second visually regardless of which widget
 * Chrome's editor happens to insert first in source order; `flex: 1 1 0` splits the row exactly evenly
 * (gap-aware, unlike a fixed `width: 50%` which would need to subtract half the row's own gap to avoid
 * a few pixels of avoidable shrink). `.fgma-portfolio-filter-clear-all` itself gets `width: 100%` to
 * fill that flex item, mirroring the existing `.fgma-portfolio-filter-apply .elementor-button{width:
 * 100%}` treatment so both CTAs fill their own half identically. Sticky/footer positioning (owned
 * entirely by Elementor's own Off-Canvas structure) is completely untouched -- only `flex-direction`/
 * `order`/sizing are set here.
 */
.fgma-portfolio-filter-drawer__footer {
    flex-direction: row;
    border-top: 1px solid var(--e-global-color-v4-fgma-light-gray);
}

.fgma-portfolio-filter-drawer__footer > .fgma-portfolio-filter-apply,
.fgma-portfolio-filter-drawer__footer > *:has(.fgma-portfolio-filter-clear-all) {
    flex: 1 1 0;
}

.fgma-portfolio-filter-drawer__footer > *:has(.fgma-portfolio-filter-clear-all) {
    order: 1;
}

.fgma-portfolio-filter-drawer__footer > .fgma-portfolio-filter-apply {
    order: 2;
}

.fgma-portfolio-filters {
    display: flex;
    flex-direction: column;
    gap: var(--fgma-space-sm);
}

/**
 * R3.7A.F2: group heading typography -- matches Production's readable/bold hierarchy using only
 * already-established FGMA tokens: `--fgma-font-family` (the installed Avenir family), `--fgma-
 * weight-heavy` (bold), `--fgma-step-0` (confirmed live to compute ~18px desktop, the same token
 * already mapped to Production's own real `.paragraph-sm`/chip-scale typography elsewhere in this
 * file) -- no `@font-face`, no new literal font asset.
 */
.fgma-portfolio-filter-group__label {
    display: block;
    margin-bottom: .5em;
    font-family: var(--fgma-font-family);
    font-weight: var(--fgma-weight-heavy);
    font-size: var(--fgma-step-0);
    color: var(--e-global-color-v4-fgma-black);
}

.fgma-portfolio-filter-options {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .5em;
}

.fgma-portfolio-filter-option {
    list-style: none;
}

/**
 * R3.7A.F2: normal chip -- Production's confirmed real contract (white background, 1px light-gray
 * border, fully rounded, Avenir Book, ~17.8px/black text, ~8px 18px 7px padding). `--fgma-step-0`
 * (confirmed live ~18px at desktop) and `--fgma-weight-book` map directly to the confirmed size/
 * weight; the `8px`/`18px`/`7px` padding stays a real literal (never a fluid `--fgma-space-*` token)
 * -- this file's own established convention for component-internal chip padding, documented in this
 * section's own earlier header comment, is unchanged by this pass. `gap` on the flex container itself
 * (rather than a dedicated rule for the inline `×`) spaces the visible label from the decorative
 * remove indicator on selected chips below, with zero extra selectors needed.
 */
.fgma-portfolio-filter-option__link {
    display: inline-flex;
    align-items: center;
    gap: .35em;
    border: 1px solid var(--e-global-color-v4-fgma-light-gray);
    border-radius: 999px;
    padding: 8px 18px 7px;
    background: var(--e-global-color-v4-fgma-white);
    color: var(--e-global-color-v4-fgma-black);
    text-decoration: none;
    font-family: var(--fgma-font-family);
    font-weight: var(--fgma-weight-book);
    font-size: var(--fgma-step-0);
    line-height: 1.35;
}

.fgma-portfolio-filter-option__link:hover {
    border-color: var(--e-global-color-v4-fgma-brand-red);
    color: var(--e-global-color-v4-fgma-brand-red);
}

.fgma-portfolio-filter-option__link:focus-visible {
    outline: 2px solid var(--e-global-color-v4-fgma-control-blue);
    outline-offset: 2px;
}

/**
 * R3.7A.F2 correction: the selected chip is a REMOVE control (see `Portfolio_Filter_Controls_
 * Renderer`'s own header comment for the full accessible-name/URL rationale), styled as Production's
 * re-confirmed real contract -- off-white fill, bold black text -- never the previously-assumed red
 * fill/white text. `aria-current` is no longer rendered for this state at all (replaced by the plain
 * `data-fgma-portfolio-filter-selected` data attribute, which is all this selector now needs to
 * target).
 */
.fgma-portfolio-filter-option__link[data-fgma-portfolio-filter-selected] {
    background: var(--e-global-color-v4-fgma-off-white);
    color: var(--e-global-color-v4-fgma-black);
    font-weight: var(--fgma-weight-heavy);
}

/**
 * R3.7A.F2: the dedicated drawer-footer Clear All (`[fgma_portfolio_clear_all]`) -- an "outline/light"
 * pill complementary to the red Apply pill, deliberately mirroring the already-established sibling
 * `.fgma-portfolio-filter-close .elementor-button` treatment (white fill, light-gray border, off-black
 * text, same `600` weight) for visual consistency across all Trigger/Close/Apply/Clear-All drawer
 * controls, with the same `16px 30px` padding as Apply/Close for identical height/rhythm. Targets only
 * this stable semantic class -- never a generated Elementor ID, since this is Code-authored markup
 * (a real anchor, not an Elementor Button widget). `width: 100%` (R3.7A.F3) fills the ~50%-wide footer
 * flex item the drawer-footer layout fix below gives it, mirroring the existing `.fgma-portfolio-
 * filter-apply .elementor-button{width:100%}` treatment so both CTAs fill their own half identically.
 */
.fgma-portfolio-filter-clear-all {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    border: 1px solid var(--e-global-color-v4-fgma-light-gray);
    border-radius: 999px;
    padding: 16px 30px;
    background: var(--e-global-color-v4-fgma-white);
    color: var(--e-global-color-v4-fgma-off-black);
    text-decoration: none;
    font-family: var(--fgma-font-family);
    font-weight: 600;
    font-size: var(--fgma-step-0);
}

.fgma-portfolio-filter-clear-all:hover {
    background: var(--e-global-color-v4-fgma-off-white);
}

.fgma-portfolio-filter-clear-all:focus-visible {
    outline: 2px solid var(--e-global-color-v4-fgma-control-blue);
    outline-offset: 2px;
}

.fgma-portfolio-active-filters {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5em;
}

.fgma-portfolio-active-filters__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .5em;
}

.fgma-portfolio-active-filters__tag {
    list-style: none;
}

/**
 * R3.7A.F2 correction: light-gray filled pill, black text -- Production's re-confirmed real contract.
 * `text-transform: capitalize` is Production's own confirmed real technique for presenting the raw
 * active slug (rendered verbatim by `Portfolio_Active_Filters_Renderer`, e.g. `civic-and-municipal`)
 * as `Civic-And-Municipal` -- no second label-mapping table, exactly as required.
 */
.fgma-portfolio-active-filters__remove {
    display: inline-flex;
    align-items: center;
    gap: .4em;
    border-radius: 999px;
    padding: .35em .9em;
    background: var(--e-global-color-v4-fgma-light-gray);
    color: var(--e-global-color-v4-fgma-black);
    text-decoration: none;
    font-family: var(--fgma-font-family);
    font-weight: var(--fgma-weight-book);
    font-size: var(--fgma-step-0);
    text-transform: capitalize;
}

.fgma-portfolio-active-filters__remove:hover {
    color: var(--e-global-color-v4-fgma-brand-red);
}

.fgma-portfolio-active-filters__remove:focus-visible {
    outline: 2px solid var(--e-global-color-v4-fgma-control-blue);
    outline-offset: 2px;
}

/**
 * R3.7A.1C: `.fgma-portfolio-loading-status` -- `fgma-portfolio-filters.js`'s own infinite-loading
 * status region (created/emptied by that script itself, never server-rendered; see that file's own
 * header comment). Reuses the same design-system tokens as every other rule in this file; no new
 * literal value introduced. Deliberately minimal -- Chrome owns any further visual treatment
 * (spinner/icon) if one is wanted; this only guarantees the concise text status is never unstyled.
 */
.fgma-portfolio-loading-status {
    margin: 0;
    padding-block: var(--fgma-space-sm);
    text-align: center;
    color: var(--e-global-color-v4-fgma-gray);
    font-size: .9em;
}

/**
 * R3.7A.1 FINAL: suppresses the real, live-confirmed native Elementor "Numbers" pagination nav
 * (`<nav class="elementor-pagination">`, `pagination_type: "numbers"`) -- but ONLY once
 * `fgma-portfolio-filters.js` has confirmed infinite loading can actually run (see that file's own
 * `markInfiniteLoadingActiveIfSupported()`) -- never by default. Without JavaScript, or in a browser
 * without IntersectionObserver, the `[data-fgma-portfolio-infinite-loading]` attribute on `<html>` is
 * never set, so this rule never matches and the native nav stays fully visible/usable -- the required
 * no-JS pagination fallback (block brief section 5/6, R3.7A.1C). `.elementor-pagination` is a real,
 * stable, non-generated Elementor structural class (confirmed live, and already the same class this
 * file's own style-contract test allowlists) -- never a generated `.elementor-element-XXXX`, never a
 * template/post ID, no `!important` needed (a plain two-class descendant selector already strictly
 * outranks Elementor's own single-class pagination default).
 */
html[data-fgma-portfolio-infinite-loading] .fgma-portfolio-archive-results .elementor-pagination {
    display: none;
}
