/**
 * Component styling for the reusable block patterns registered in
 * inc/block-patterns.php. Everything here reads from tokens.css — no
 * hex values are introduced in this file.
 */

/*
 * Page hero — no longer uses `align:full` (it fought Kadence's own
 * content-width system on the live site, see homepage.css for the same
 * issue/fix on the style-test pattern). Keeps its normal box width
 * (matching Kadence's content column/header) and uses a box-shadow +
 * clip-path bleed for the full-viewport background look instead.
 *
 * Revision 3 (palette pivot): uses `--gillani-color-brand-deep` (the new
 * deep-variant shade of the dominant brand blue), NOT the plain
 * `--gillani-color-primary`. The pure saturated brand blue reads as too
 * bright/tech-product-like at this full-bleed scale — the deep variant is
 * reserved for exactly this kind of large flat-fill "darker moment" (see
 * tokens.css), the same value the navigation bar, CTA band and footer all
 * now use — so matching it here keeps the header + hero reading as one
 * continuous dark zone, the same design intent this rule has always had,
 * just with the new hue. Plain brand blue remains in use for headings and
 * button fills on light section backgrounds.
 *
 * Revision 4 briefly desaturated this one step further, to `--gillani-
 * color-primary-muted`; Revision 6 reverted that (see tokens.css's
 * Revision 6 note) back to `--gillani-color-brand-deep` — the client
 * wanted the logo-blue hue to stay clearly dominant here, not greyed out.
 */
.gillani-hero {
	position: relative;
	background-color: var(--gillani-color-brand-deep);
	box-shadow: 0 0 0 100vmax var(--gillani-color-brand-deep);
	clip-path: inset(0 -100vmax);
	color: var(--gillani-color-on-secondary);
	text-align: center;
	padding-top: var(--gillani-space-4);
	padding-bottom: var(--gillani-space-4);
}

/*
 * Whitespace pass — desktop-only step up (mobile base above, `--gillani-
 * space-4`, is unchanged). This rule's selector/specificity intentionally
 * matches the equivalent `.gillani-hero` rule in layout.css exactly, and
 * this file loads after layout.css (see enqueue.php), so this is the one
 * that actually wins/renders — kept in sync with that file's own bump so
 * both agree on the same desktop value.
 */
@media (min-width: 782px) {
	.gillani-hero {
		padding-top: var(--gillani-space-6);
		padding-bottom: var(--gillani-space-6);
	}
}

/*
 * Revision 4 — inner/hub-page hero enlargement. Plain `.gillani-hero`
 * (the `page-hero` pattern — a bare H1 + optional one-line subheading,
 * no other content) was collapsing to a thin ~130px strip on inner pages,
 * since its height came from padding alone with almost nothing inside to
 * push it taller. `min-height` + flex-centring makes it read as a real
 * hero band instead, matching WLSS's bigger inner-page hero treatment.
 *
 * Deliberately scoped to `:not(.gillani-homepage-hero)`: the homepage
 * hero already carries its own, taller, content-driven height (extra
 * `--gillani-space-5`/`-7` padding plus a heading + button + quiet link +
 * image note — see homepage.css and inc/homepage-pattern.php) and must
 * not be affected by this change. `.gillani-homepage-hero` is always
 * present alongside `.gillani-hero` in that pattern's markup, so this
 * exclusion is exact, not a guess.
 *
 * CORRECTION (later pass, see README.md "Bug: Revision 4's inner-hero
 * fix was a no-op"): this rule is currently DEAD CODE on the live site.
 * `.gillani-hero` is this theme's own custom block-pattern class,
 * registered/used ONLY by the homepage hero in
 * `inc/homepage-pattern.php` — every occurrence of it in that file is
 * always paired with `.gillani-homepage-hero` on the same element, which
 * this rule's `:not(.gillani-homepage-hero)` deliberately excludes. No
 * real inner page (About Us, FAQs, Shooting Experiences/Sporting Agency
 * and children, Contact Us, etc.) ever inserts a bare `.gillani-hero`
 * without that homepage modifier — those pages instead render Kadence's
 * own native page-title band (`.entry-hero.page-hero-section
 * .entry-header`), which is a completely different element with its own
 * override now in `header-footer.css`. This rule is left in place
 * (harmless, not deleted) in case a future page ever reuses the
 * `.gillani-hero` pattern block directly inside inner-page content
 * without the homepage modifier — if that ever happens, this rule would
 * become live/relevant again exactly as originally intended.
 */
.gillani-hero:not(.gillani-homepage-hero) {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	min-height: clamp(280px, 40vh, 480px);
}

@media (min-width: 782px) {
	.gillani-hero:not(.gillani-homepage-hero) {
		min-height: clamp(360px, 48vh, 560px);
	}
}

/*
 * Bucket A — permanent contrast-ready gradient overlay. Formalizes the
 * gradient already prototyped in the Style Test's `.gillani-style-test__
 * overlay-demo` (see homepage.css) into the real hero component itself, so
 * text contrast is solved once, here, rather than being re-litigated every
 * time a real photo gets dropped into the Cover block. Applied to the base
 * `.gillani-hero` unconditionally via a `::before` layer (so it never
 * fights the hero's own background paint) — harmless as a subtle bottom-
 * darkening even against the solid-navy fallback below.
 */
.gillani-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: linear-gradient(to top, rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0));
	pointer-events: none;
}

.gillani-hero > * {
	position: relative;
}

/*
 * Reconciliation with the Cover block's own dim overlay (the mechanism
 * behind the live homepage hero, which wraps `.gillani-hero` in a Cover
 * block with a photo + `has-background-dim`). Confirmed via the live
 * rendered markup and Kadence's own generated CSS: `.wp-block-cover__
 * inner-container` (which contains `.gillani-hero`) is later in DOM order
 * than both the Cover's image and its dim span, with no explicit z-index
 * separating them here — so it paints on top of both. That means
 * `.gillani-hero`'s own OPAQUE background-colour + 100vmax box-shadow
 * bleed (needed for the standalone/no-photo case above) was completely
 * hiding the Cover block's photo the entire time it's been live; the photo
 * was never actually visible behind the hero text. Scoped to only the
 * Cover-nested case (leaves the standalone solid-navy hero above
 * untouched): makes the hero itself transparent so the photo now shows
 * through, and switches off the Cover block's own flat dim layer so only
 * our one gradient above provides contrast — not two stacked dark layers.
 */
.wp-block-cover:has(.gillani-hero) .wp-block-cover__background {
	opacity: 0;
}

.wp-block-cover .gillani-hero {
	background-color: transparent;
	box-shadow: none;
}

/*
 * Selector deliberately includes the `.gillani-hero` ancestor (not just
 * `.gillani-hero__heading` alone) so its specificity (two classes) safely
 * beats typography.css's `h1.wp-block-heading` rule (one type + one
 * class) — otherwise the hero's H1 would incorrectly render in navy
 * (invisible against its own navy background) instead of the light
 * on-secondary colour it needs for contrast.
 */
.gillani-hero .gillani-hero__heading {
	color: var(--gillani-color-on-secondary);
}

.gillani-hero__subheading {
	color: var(--gillani-color-on-secondary);
	opacity: 0.9;
}

/*
 * Revision 3 — hero simplification. A quiet, text-link-style secondary
 * action for the homepage hero, replacing what used to be a second,
 * equal-weight button ("Explore Shooting Experiences") competing with the
 * single primary CTA ("Make an Enquiry"). Deliberately no button chrome
 * (no border/background/padding-box) — just underlined text a shade
 * quieter than the heading, so it reads as a secondary, optional path
 * rather than a second decision the visitor has to make.
 */
.gillani-hero__quiet-link {
	margin-top: var(--gillani-space-2);
}

.gillani-hero__quiet-link a {
	color: var(--gillani-color-on-secondary);
	opacity: 0.85;
	text-decoration: underline;
	text-underline-offset: 3px;
	font-size: 0.95rem;
	transition: opacity 0.2s ease, color 0.2s ease;
}

/*
 * Revision 3 contrast fix: this link initially also swapped `color` to
 * the warm accent on hover, matching the other secondary-CTA-accent
 * hover moments elsewhere in this file — but `--gillani-color-accent-
 * warm` measures only 3.06:1 against this link's `--gillani-color-
 * brand-deep` hero background, failing the 4.5:1 normal-text AA
 * threshold. The opacity bump to full alone is a sufficient, already-
 * accessible hover cue, so the colour stays on the already-proven
 * on-secondary token instead.
 */
.gillani-hero__quiet-link a:hover,
.gillani-hero__quiet-link a:focus-visible {
	opacity: 1;
}

/*
 * Buttons — overrides WordPress/Kadence core button-block defaults (which
 * otherwise render in default WordPress blue on the live site). The
 * un-scoped, moderate-specificity version of this rule wasn't enough to
 * beat Kadence's own button styling in practice, so this targets both
 * classes Gutenberg actually renders on the link
 * (`wp-block-button__link` + `wp-element-button`), adds an extra
 * `.entry-content` ancestor variant for higher specificity, and uses a
 * narrowly-scoped `!important` on only the three colour properties
 * (background-color/color/border-color) — never on layout properties —
 * since colour was the specific property still being lost to Kadence's
 * cascade. Border radius/weight/transition stay un-flagged.
 *
 * Revision 4 — added `padding`/`letter-spacing` here (not `!important`,
 * and not repeated on any of the more specific primary/secondary/hero/
 * CTA-band variant selectors below): this is the one shared, lowest-
 * specificity selector every button variant on the site already matches
 * (`.gillani-button-primary`/`-secondary`, `.is-style-outline`, and the
 * hero/CTA-band inverted variants all just add extra classes to the same
 * `.wp-block-button__link.wp-element-button` element), so the bigger
 * "more substantial" footprint cascades to all of them from this one
 * rule. Kadence's own default button padding was otherwise noticeably
 * tighter than WLSS's smaller-text/larger-padding button style. The
 * existing `min-height: 44px` tap-target rule in accessibility.css is
 * unaffected/still satisfied — this padding only ever makes the button
 * taller than 44px, never shorter.
 *
 * Revision 5 — `font-family` added (`--gillani-font-ui`, Lato): buttons
 * are one of this token's explicitly-named uses, matching WLSS's real
 * button typeface. Weight bumped 600 → 700 in the same edit, for the
 * same real-vs-synthetic-weight reason as the nav in header-footer.css —
 * Lato has no 600 file, only Regular (400) and Bold (700).
 */
.wp-block-button .wp-block-button__link.wp-element-button,
.entry-content .wp-block-button .wp-block-button__link.wp-element-button {
	background-color: var(--gillani-color-primary) !important;
	color: var(--gillani-color-on-primary) !important;
	border-color: var(--gillani-color-primary) !important;
	border-width: 2px;
	border-style: solid;
	border-radius: var(--gillani-radius);
	padding: 0.9em 2em;
	font-family: var(--gillani-font-ui);
	font-weight: 700;
	letter-spacing: 0.02em;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

/*
 * Revision 7: this hover/focus fill IS `--gillani-color-brand-deep`, so
 * the border sitting on top of it uses `--gillani-color-accent-on-dark`
 * (3.11:1 against brand-deep) rather than the plain `--gillani-color-
 * accent` — which measures only 2.49:1 there since the Revision 7
 * "Option A" warm-grey swap (`#6C7480` → `#6B6558`), below the 3:1 non-
 * text/UI-component threshold this border needs to clear. See tokens.css's
 * Revision 7 note for the full reasoning behind the new companion token.
 */
.wp-block-button .wp-block-button__link.wp-element-button:hover,
.wp-block-button .wp-block-button__link.wp-element-button:focus-visible,
.entry-content .wp-block-button .wp-block-button__link.wp-element-button:hover,
.entry-content .wp-block-button .wp-block-button__link.wp-element-button:focus-visible {
	background-color: var(--gillani-color-brand-deep) !important;
	border-color: var(--gillani-color-accent-on-dark) !important;
	color: var(--gillani-color-on-secondary) !important;
}

/*
 * Secondary button — the core "Outline" button style. Revision 3: its
 * hover/focus accent now uses the new warm accent (`--gillani-color-
 * accent-warm`), not the neutral muted-slate `--gillani-color-accent` —
 * this is one of the task's named "secondary-CTA accent" moments, giving
 * outline/secondary actions a distinct warm touch that primary buttons
 * (which keep the neutral slate accent on hover) don't share.
 */
.wp-block-button.is-style-outline .wp-block-button__link.wp-element-button,
.entry-content .wp-block-button.is-style-outline .wp-block-button__link.wp-element-button {
	background-color: transparent !important;
	color: var(--gillani-color-primary) !important;
	border-color: var(--gillani-color-primary) !important;
	border-width: 2px;
	border-style: solid;
}

.wp-block-button.is-style-outline .wp-block-button__link.wp-element-button:hover,
.wp-block-button.is-style-outline .wp-block-button__link.wp-element-button:focus-visible,
.entry-content .wp-block-button.is-style-outline .wp-block-button__link.wp-element-button:hover,
.entry-content .wp-block-button.is-style-outline .wp-block-button__link.wp-element-button:focus-visible {
	background-color: var(--gillani-color-primary) !important;
	color: var(--gillani-color-on-primary) !important;
	border-color: var(--gillani-color-accent-warm) !important;
}

/*
 * Style Test pattern — explicit wrapper classes are on the outer
 * `wp:button` block itself in the pattern markup, confirmed directly in
 * inc/style-test-pattern.php:
 *
 *   <div class="wp-block-button gillani-button-primary">
 *     <a class="wp-block-button__link wp-element-button">...</a>
 *   </div>
 *
 * — not on a surrounding paragraph/group/buttons wrapper. No Gutenberg
 * preset colour classes, inline styles, or link-colour attributes are
 * present on either button block. Selectors below combine the class
 * directly onto `.wp-block-button` (matching what's actually rendered)
 * and require an `.entry-content` ancestor for maximum specificity; a
 * bare (non-`.entry-content`) version is kept too in case that ancestor
 * class doesn't apply here, so this doesn't silently fail to match.
 * `!important` is scoped to only background-color/border-color/color.
 */
.wp-block-button.gillani-button-primary .wp-block-button__link,
.wp-block-button.gillani-button-primary .wp-element-button,
.entry-content .wp-block-button.gillani-button-primary .wp-block-button__link,
.entry-content .wp-block-button.gillani-button-primary .wp-element-button {
	background-color: var(--gillani-color-primary) !important;
	border-color: var(--gillani-color-primary) !important;
	color: var(--gillani-color-on-primary) !important;
}

/*
 * Contrast note (Revision 7 audit, pre-existing — not introduced or
 * worsened in any meaningful way by this revision): this border sits on
 * the vivid `--gillani-color-primary` fill, not `--gillani-color-brand-
 * deep`. Both the old muted-slate accent (2.05:1) and the new warm-grey
 * accent (1.67:1) already fail the 3:1 non-text/UI threshold here — a
 * same-hue-family border against a highly-saturated same-family blue
 * fill was never going to clear 3:1 regardless of which specific accent
 * shade is used, so this is a pre-existing, out-of-scope gap rather than
 * a regression caused by the Revision 7 colour swap. Left as-is (not
 * swapped to `--gillani-color-accent-on-dark`, which was tuned for
 * `--gillani-color-brand-deep` specifically, not this brighter fill, and
 * wouldn't meaningfully fix this either).
 */
.wp-block-button.gillani-button-primary .wp-block-button__link:hover,
.wp-block-button.gillani-button-primary .wp-element-button:hover,
.wp-block-button.gillani-button-primary .wp-block-button__link:focus-visible,
.wp-block-button.gillani-button-primary .wp-element-button:focus-visible,
.entry-content .wp-block-button.gillani-button-primary .wp-block-button__link:hover,
.entry-content .wp-block-button.gillani-button-primary .wp-element-button:hover,
.entry-content .wp-block-button.gillani-button-primary .wp-block-button__link:focus-visible,
.entry-content .wp-block-button.gillani-button-primary .wp-element-button:focus-visible {
	background-color: var(--gillani-color-primary) !important;
	border-color: var(--gillani-color-accent) !important;
	color: var(--gillani-color-on-primary) !important;
}

.wp-block-button.gillani-button-secondary .wp-block-button__link,
.wp-block-button.gillani-button-secondary .wp-element-button,
.entry-content .wp-block-button.gillani-button-secondary .wp-block-button__link,
.entry-content .wp-block-button.gillani-button-secondary .wp-element-button {
	background-color: transparent !important;
	border-color: var(--gillani-color-primary) !important;
	color: var(--gillani-color-primary) !important;
}

/*
 * Revision 3: warm accent on hover/focus — same "secondary-CTA accent"
 * reasoning as the outline button above. The BORDER switches to the warm
 * accent (a decorative, non-text UI-component cue — WCAG's 3:1 non-text
 * threshold, which `--gillani-color-accent-warm` clears against every
 * section background this button appears on: ivory, stone, and
 * off-white — see the computed contrast table in README.md's changelog
 * for this revision). The TEXT deliberately stays on `--gillani-color-
 * primary` rather than also switching to the warm accent — measured at
 * only 3.1–4.1:1 against this button's light section backgrounds, which
 * fails the 4.5:1 normal-text AA threshold on two of the three (ivory,
 * stone). This project has had real previously-flagged accent-colour
 * text-contrast failures; this is a deliberate fix to avoid repeating
 * that here.
 */
.wp-block-button.gillani-button-secondary .wp-block-button__link:hover,
.wp-block-button.gillani-button-secondary .wp-element-button:hover,
.wp-block-button.gillani-button-secondary .wp-block-button__link:focus-visible,
.wp-block-button.gillani-button-secondary .wp-element-button:focus-visible,
.entry-content .wp-block-button.gillani-button-secondary .wp-block-button__link:hover,
.entry-content .wp-block-button.gillani-button-secondary .wp-element-button:hover,
.entry-content .wp-block-button.gillani-button-secondary .wp-block-button__link:focus-visible,
.entry-content .wp-block-button.gillani-button-secondary .wp-element-button:focus-visible {
	background-color: transparent !important;
	border-color: var(--gillani-color-accent-warm) !important;
	color: var(--gillani-color-primary) !important;
}

/*
 * Buttons on dark brand-deep backgrounds (the hero, the CTA band) need an
 * inverted treatment — the rules above assume a light section background,
 * so a brand-blue-fill primary button (and a brand-blue-border/text
 * secondary button) is invisible against `.gillani-hero`'s and `.gillani-
 * cta-band`'s own deep-variant background (both now share the same
 * `--gillani-color-brand-deep` value — see the `.gillani-hero` rule
 * above). Confirmed on the live homepage: both hero buttons were
 * genuinely invisible in their default state, only appearing once the
 * border/text switched to accent on hover.
 *
 * The primary button fix (cream fill) worked immediately when first
 * tried, but the secondary button fix did not — live testing showed the
 * outline button was still rendering low-contrast/near-invisible in its
 * default state. Root cause: these selectors were only 4 classes deep,
 * tying the specificity of the existing light-context rules above (and
 * possibly Kadence/WordPress core's own `.is-style-outline` default
 * button styling, which is applied via a differently-ordered stylesheet
 * this theme doesn't control the exact position of) — a tie that isn't
 * safe to rely on. `.wp-block-buttons` is added to the ancestor chain
 * here purely to push specificity strictly higher (five classes) than
 * every rule it needs to beat, and `border-width` is set explicitly so
 * the outline reads clearly rather than as a hairline against a busy
 * dark background.
 */
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-primary .wp-block-button__link,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-primary .wp-element-button,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-primary .wp-block-button__link,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-primary .wp-element-button {
	background-color: var(--gillani-color-on-primary) !important;
	border-color: var(--gillani-color-on-primary) !important;
	color: var(--gillani-color-primary) !important;
}

/*
 * Contrast note (Revision 7 audit): this rule's fill is `--gillani-
 * color-on-primary`, i.e. cream (`--gillani-color-background`), not
 * brand-deep — so both the border AND the text-coloured `color` property
 * here are checked against cream, not the dark hero/CTA-band surface.
 * The old muted-slate accent measured 4.08:1 against cream (a pre-
 * existing marginal FAIL of the 4.5:1 normal-text threshold for the
 * `color` usage, though a clear PASS of the 3:1 non-text threshold for
 * the border); the new warm-grey accent measures 5.00:1 — a clear PASS
 * of both thresholds, an improvement introduced as a side effect of the
 * Revision 7 swap, not a regression.
 */
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-primary .wp-block-button__link:hover,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-primary .wp-element-button:hover,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-primary .wp-block-button__link:focus-visible,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-primary .wp-element-button:focus-visible,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-primary .wp-block-button__link:hover,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-primary .wp-element-button:hover,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-primary .wp-block-button__link:focus-visible,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-primary .wp-element-button:focus-visible {
	background-color: var(--gillani-color-on-primary) !important;
	border-color: var(--gillani-color-accent) !important;
	color: var(--gillani-color-accent) !important;
}

.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-block-button__link,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-element-button,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-block-button__link,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-element-button {
	background-color: transparent !important;
	border-width: 2px !important;
	border-style: solid !important;
	border-color: var(--gillani-color-on-primary) !important;
	color: var(--gillani-color-on-primary) !important;
}

/*
 * Revision 3 contrast fix (superseded by the Revision 4 note below): same
 * reasoning as the light-background secondary-button hover above —
 * `--gillani-color-accent-warm` on `--gillani-color-brand-deep` measured
 * 3.06:1, clearing the 3:1 non-text/UI-component threshold (fine for the
 * border) but failing the 4.5:1 normal-text threshold. The border kept
 * the warm accent touch; the text stayed on the already-proven
 * `--gillani-color-on-primary` (12.4:1 against brand-deep) instead of
 * also switching to the warm accent.
 *
 * Revision 4 briefly moved `.gillani-hero`/`.gillani-cta-band` to a more
 * desaturated fill, against which neither accent colour cleared 3:1, so
 * the border was kept on the already-proven `--gillani-color-on-primary`
 * with no colour swap on hover. Revision 6 reverted the fill back to
 * `--gillani-color-brand-deep` (same as Revision 3), which is what the
 * original 3.06:1 accent-warm measurement above was actually taken
 * against — but the border is left as-is on `--gillani-color-on-primary`
 * rather than reintroducing the accent-warm swap, since 3.06:1 was
 * already a marginal pass and this hover state reads perfectly clearly
 * without it; the sitewide lift/shadow hover cue (see the shared
 * `.wp-block-button` rule further down this file) still signals
 * interactivity regardless.
 */
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-block-button__link:hover,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-element-button:hover,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-block-button__link:focus-visible,
.gillani-hero .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-element-button:focus-visible,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-block-button__link:hover,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-element-button:hover,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-block-button__link:focus-visible,
.gillani-cta-band .wp-block-buttons .wp-block-button.gillani-button-secondary .wp-element-button:focus-visible {
	background-color: transparent !important;
	border-color: var(--gillani-color-on-primary) !important;
	color: var(--gillani-color-on-primary) !important;
}

/*
 * Task 4 — subtle hover/focus lift for every button on the site, additive
 * to the colour rules above (this rule deliberately never touches
 * background-color/border-color/color, so it can't re-open the earlier
 * Kadence colour-cascade fight those rules already solved with
 * `!important`). One selector covers every button variant — primary,
 * secondary, the gillani-button-primary/secondary wrapper-class variants,
 * and the hero/CTA-band inverted variants — since the modifier classes
 * only ever add extra classes to the same `.wp-block-button` ancestor,
 * never replace this base selector.
 */
.wp-block-button .wp-block-button__link.wp-element-button {
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.wp-block-button .wp-block-button__link.wp-element-button:hover,
.wp-block-button .wp-block-button__link.wp-element-button:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 8px 18px rgba(7, 30, 61, 0.2);
}

/*
 * Reduced motion: disable the transform/shadow movement entirely (not
 * just speed it up) and fall back to the colour-only hover cue the rules
 * above already provide.
 */
@media (prefers-reduced-motion: reduce) {
	.wp-block-button .wp-block-button__link.wp-element-button {
		transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
	}

	.wp-block-button .wp-block-button__link.wp-element-button:hover,
	.wp-block-button .wp-block-button__link.wp-element-button:focus-visible {
		transform: none;
		box-shadow: none;
	}
}

/*
 * Page title area — deliberately NOT styled with CSS.
 *
 * Two rounds of CSS attempts targeted `.entry-hero` (bare, then combined
 * with `.page-hero-section`, then with `!important` added) and NONE of
 * them visibly changed anything on the live site — including the
 * `!important` version, which should have beaten any normal-weight
 * Kadence rule regardless of specificity. That result means the selector
 * itself doesn't match this site's actual rendered element at all, i.e.
 * "entry-hero" isn't the real class name in this specific Kadence
 * install/configuration. Continuing to guess further class names isn't a
 * productive use of CSS here.
 *
 * The page-title background, spacing, and homepage visibility are
 * instead controlled directly via Kadence's own Customizer — see
 * README.md "Page-title settings" for the exact steps. That's the native,
 * guaranteed-to-work mechanism regardless of the underlying markup.
 */

/*
 * Split content section (currently just the founder preview).
 *
 * `min-height`/flex-centring dates from when this held only placeholder
 * text of unknown final size. Now that a real photo sits here, the image
 * itself is pinned to a fixed aspect ratio (see rule below) — the
 * background colour remains as a fallback in case a future image is
 * ever missing/slow to load, and `overflow: hidden` clips the image to
 * the container's rounded corners.
 */
.gillani-split-content__media {
	background-color: var(--gillani-color-border);
	border-radius: var(--gillani-radius);
	overflow: hidden;
}

/*
 * The founder photo is a full-length standing portrait (naturally a very
 * tall ~0.46 width/height ratio) — `object-position: top` deliberately
 * crops from the bottom (boots/legs) rather than the top, so the face
 * and upper body are never cut off regardless of the exact source photo.
 */
.gillani-split-content__media .wp-block-image {
	margin: 0;
}

.gillani-split-content__media .wp-block-image img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 4;
	object-fit: cover;
	object-position: top center;
}

/*
 * Layered-panels round — subtle horizontal bleed on the founder portrait,
 * the same "doesn't sit in a sealed flat rectangle" depth cue as the
 * homepage card-grid bleeds (see homepage.css). This column currently
 * sits on the LEFT of "Meet the Founder" (media-left, text-right), so it
 * bleeds further left, past its own column and towards the section's
 * edge, rather than towards the text column beside it.
 *
 * Scoped to `>= 1024px` rather than this theme's usual `782px`
 * breakpoint — deliberately more conservative here: Kadence's own
 * content-width side gutter narrows well before 1024px, and this rule
 * has no equivalent `.gillani-section`-style clip-path safety net, so a
 * higher, more cautious breakpoint is used specifically to keep a
 * comfortable, tested margin of safety against any horizontal-scroll
 * risk on in-between (tablet) widths. Disabled entirely below it.
 */
@media (min-width: 1024px) {
	.gillani-split-content__media {
		position: relative;
		z-index: 1;
		margin-left: -28px;
	}
}

/*
 * Card grid (service / destination cards) — Revision 3: full-bleed photo
 * tile, replacing the previous bordered/padded surface box (surface
 * background, 1px border, boxed padding, image-then-heading-below).
 * Sitewide via this one shared class (Home's UK Shooting Experiences +
 * International Sporting Agency grids, and the Shooting Experiences hub /
 * Sporting Agency hub child-page grids, wherever they reuse
 * `.gillani-card` — verified live across multiple page types after
 * deployment, see README.md changelog).
 *
 * Technique: CSS Grid with a single explicit row, and the image + heading
 * both placed in that SAME cell (`grid-row: 1; grid-column: 1;`) — this
 * stacks them without needing to change any existing page's markup (every
 * card's real content is already just image → heading → paragraph → link
 * as plain siblings). The heading is pulled to the bottom of that shared
 * cell (`align-self: end`) and given its own dark gradient background —
 * reusing the same top-to-transparent gradient technique already proven
 * in `.gillani-hero::before` — so it reads as a caption overlaid on the
 * photo, in light/cream text for contrast. The paragraph and "Learn more"
 * link are NOT grid-placed, so CSS Grid's normal auto-placement puts them
 * into the next implicit row, i.e. they simply continue to sit below the
 * tile as plain text, unchanged in substance — only the image+heading
 * portion becomes full-bleed.
 */
.gillani-card {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: auto;
	background-color: transparent;
	border: none;
	border-radius: var(--gillani-radius);
	padding: 0;
	box-shadow: none;
	overflow: hidden;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}

/*
 * Task 4 — subtle hover/focus lift (unchanged from the previous
 * treatment, minus the border-colour cue, since the card no longer has a
 * visible border to recolour — the lift + shadow alone still supplies the
 * same "this is interactive" signal).
 */
.gillani-card:hover,
.gillani-card:focus-within {
	transform: translateY(-3px);
	box-shadow: 0 10px 24px rgba(27, 20, 128, 0.22);
}

@media (prefers-reduced-motion: reduce) {
	.gillani-card {
		transition: none;
	}

	.gillani-card:hover,
	.gillani-card:focus-within {
		transform: none;
		box-shadow: none;
	}
}

/*
 * Card photo — same 3:4 pinned aspect-ratio/object-fit:cover reasoning as
 * before (mixed source-photo shapes/resolutions), now filling the tile
 * completely edge-to-edge (no margin, no radius of its own — the outer
 * `.gillani-card`'s `overflow: hidden` + border-radius above clips it).
 * Explicitly placed into the same grid cell as the heading below it.
 */
.gillani-card > .wp-block-image {
	grid-row: 1;
	grid-column: 1;
	margin: 0;
	min-width: 0;
}

.gillani-card > .wp-block-image img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 4;
	object-fit: cover;
	border-radius: 0;
}

/*
 * Heading overlay — shares the image's grid cell, aligned to its bottom
 * edge. `z-index` isn't strictly required (grid items paint in DOM order
 * and the heading follows the image), but is set explicitly so this
 * doesn't depend on that ordering. The gradient is deliberately opaque
 * enough at its own base to guarantee light-text contrast regardless of
 * how light or dark the specific photo underneath is — see the contrast
 * check in README.md's changelog for this revision.
 */
.gillani-card > .wp-block-heading {
	grid-row: 1;
	grid-column: 1;
	align-self: end;
	z-index: 2;
	display: block;
	margin: 0;
	padding: var(--gillani-space-4) var(--gillani-space-3) var(--gillani-space-2);
	font-size: 1.15rem;
	color: var(--gillani-color-on-secondary);
	background-image: linear-gradient(to top, rgba(20, 15, 60, 0.88) 0%, rgba(20, 15, 60, 0.55) 55%, rgba(20, 15, 60, 0) 100%);
}

/* Paragraph + "Learn more" link sit below the tile as a minimal text block — auto-placed into the grid's next implicit row (see comment above .gillani-card). */
.gillani-card > p {
	margin: var(--gillani-space-2) 0 0;
	padding: 0 var(--gillani-space-1);
}

.gillani-card > p:last-child {
	margin-bottom: var(--gillani-space-1);
}

.gillani-card > p a {
	font-weight: 600;
}

/*
 * Trust grid — Revision 3: folded into a leaner, compact inline "fact
 * strip" rather than a standalone icon-circle + eyebrow-label + heading +
 * paragraph features-grid section with its own full-width background
 * band. The markup is UNCHANGED on all 11 pages this appears on (Home,
 * About Us, Shooting Experiences hub + 3 children, Sporting Agency hub +
 * 4 children) — same `core/html` items, same icon SVGs, same eyebrow
 * labels, same headings, same supporting-paragraph sentences, every exact
 * fact/credential string preserved verbatim (Est. 2007, BASC Shotgun
 * Coach + the other four qualifications, 50+ years, nationwide coverage —
 * see README.md changelog). Two things changed instead:
 *
 * 1. The standalone `.gillani-section--ivory` group that used to wrap
 *    this grid in its own coloured band was removed on each page (a
 *    unique-match-verified WP-CLI edit, not a CSS change) — this grid now
 *    flows directly adjacent to whatever section precedes it (the intro
 *    copy on Home, the split-content intro on inner pages) instead of
 *    reading as a separate, bolted-on module.
 * 2. This stylesheet, below: icons are hidden (already `aria-hidden`, so
 *    nothing is lost for assistive tech), the eyebrow label and heading
 *    are paired onto one line ("label: fact"), the left border/padding
 *    "card" treatment is replaced with a thin top rule, and the whole
 *    grid's vertical padding is reduced well below the shared `.gillani-
 *    section`-level padding used by every other major section (see the
 *    `.gillani-trust-grid` padding override below) — all making this
 *    read as a compact row of short facts, not a large separate section.
 *
 * The pattern's markup (inc/style-test-pattern.php) is a `core/html`
 * block — raw HTML with no block-level alignment attributes WordPress
 * could be adding — so it carries `style="text-align:left"` directly on
 * every line inline, at source, which settles alignment regardless of
 * whatever an ancestor (e.g. `.wp-block-column`) defaults to. The rules
 * below are reinforcement only (and useful for any future non-`core/html`
 * usage of this class), not the primary defence.
 */
.gillani-trust-grid {
	padding-top: var(--gillani-space-3) !important;
	padding-bottom: var(--gillani-space-3) !important;
}

/* Compact items size to their own content and wrap naturally, rather than 4 forced-equal-width columns. */
.gillani-trust-grid.wp-block-columns {
	flex-wrap: wrap;
	column-gap: var(--gillani-space-5);
	row-gap: var(--gillani-space-2);
}

.gillani-trust-grid > .wp-block-column {
	flex: 0 1 auto;
	width: auto;
	max-width: 280px;
}

/*
 * "Why Choose Gillani & Gillani" heading directly above this grid (no
 * shared wrapper element to target after the section unwrap above, so
 * `:has()` targets it by its relationship to the grid instead) — tighter
 * bottom margin so it reads as a compact lead-in label, not a full
 * section title with its usual generous spacing.
 */
h2:has(+ .gillani-trust-grid) {
	margin-bottom: var(--gillani-space-2);
}

/*
 * Contrast note (Revision 7 audit): from here down, every remaining
 * `--gillani-color-accent`/`--gillani-color-earth` usage in this file
 * sits on a light section background (ivory `#F5EEDC`, white/off-white
 * surface `#FCFBF7`, or stone/border `#D8D2C5`), never on brand-deep —
 * so none of them need the new `--gillani-color-accent-on-dark`
 * companion token added in this revision (see tokens.css). The warm-grey
 * swap (`#6C7480` → `#6B6558`) measurably IMPROVES contrast against
 * ivory (4.08:1 → 5.00:1) and off-white surface (4.56:1 → 5.59:1), and
 * against stone (3.14:1 → 3.84:1) for the non-text border/underline
 * usages below (this item's top rule included). The one pre-existing
 * exception is `.gillani-placeholder-note`'s TEXT colour further down
 * this file, on the stone/border background — flagged individually at
 * that rule.
 */
.gillani-trust-grid__item.gillani-trust-grid__item {
	text-align: left;
	border-left: none;
	padding-left: 0;
	border-top: 2px solid var(--gillani-color-accent);
	padding-top: var(--gillani-space-1);
}

/* Icons are purely decorative (already `aria-hidden="true"` in the source SVG) — hidden in the compact strip treatment, not removed from the markup. */
.gillani-trust-grid__item-header {
	display: block;
	text-align: left;
	margin-bottom: 0;
}

.gillani-trust-grid__item-header .gillani-icon {
	display: none;
}

/*
 * "Label: fact" pairing — the eyebrow and heading now sit on one line
 * (Bucket A's original uppercase/letter-spacing eyebrow treatment is
 * unchanged, just repositioned inline rather than stacked above the
 * heading) instead of the previous icon-row + stacked-label layout.
 */
.gillani-trust-grid__eyebrow {
	display: inline;
	text-transform: uppercase;
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--gillani-color-accent);
}

.gillani-trust-grid__eyebrow::after {
	content: ":";
}

.gillani-trust-grid__item-header .wp-block-heading {
	display: inline;
	margin: 0 0 0 var(--gillani-space-1);
	text-align: left;
	font-size: 1rem;
}

.gillani-trust-grid__item p {
	margin: var(--gillani-space-1) 0 0;
	text-align: left;
	font-size: 0.875rem;
	opacity: 0.85;
}

@media (max-width: 599px) {
	.gillani-trust-grid > .wp-block-column {
		max-width: none;
	}

	.gillani-trust-grid__item {
		margin-bottom: var(--gillani-space-2);
	}
}

/* FAQ accordion (native core/details, no JS required) */
.gillani-faq-accordion .wp-block-details {
	border-bottom: 1px solid var(--gillani-color-border);
	padding: var(--gillani-space-2) 0;
}

/*
 * Revision 5: weight bumped 600 → 700. This previously relied on browser
 * synthesis (Libre Caslon Display had no real weight but 400); Libre
 * Baskerville (the current `--gillani-font-heading`) has a real Bold
 * (700) file but no 600, so 700 is now the closest REAL weight rather
 * than a synthesised one — a strict improvement, not just a style change.
 */
.gillani-faq-accordion summary {
	font-family: var(--gillani-font-heading);
	color: var(--gillani-color-primary);
	cursor: pointer;
	font-weight: 700;
}

/* Testimonials */
.gillani-testimonials__item {
	border-left: 3px solid var(--gillani-color-accent);
	padding-left: var(--gillani-space-3);
	font-family: var(--gillani-font-heading);
}

/*
 * Editorial pull-quote — a large, restrained callout treatment for a short
 * excerpt from the founder's story or a future testimonial. Deliberately
 * NOT set in `font-style: italic`: Revision 5's heading family (Libre
 * Baskerville) does ship a real italic upstream (unlike the previous
 * Libre Caslon Display, which had none at all), but it was never self-
 * hosted here — nothing in this theme's current content actually needs a
 * serif italic (see assets/fonts/README.md "Why only these weights"), so
 * requesting `font-style: italic` would still just ask the browser to
 * synthesise a fake oblique from the Regular/Bold files that ARE
 * downloaded. The oversized opening quotation mark (`::before`) and the
 * thin accent rule (`::after`) carry the "this is a quotation" visual cue
 * instead, consistent with "large opening quotation mark treatment" as
 * the chosen alternative to italics.
 *
 * Framework-agnostic on purpose: works on a plain paragraph (the About Us
 * demonstration below adds this class straight onto an existing, already-
 * published sentence — see README.md changelog), a blockquote, or a
 * `.gillani-testimonial-card__quote` (below) without modification.
 */
.gillani-pull-quote {
	position: relative;
	max-width: 720px;
	margin: 0 auto;
	padding-top: var(--gillani-space-3);
	font-family: var(--gillani-font-heading);
	font-weight: 400;
	font-size: clamp(1.375rem, 1.1rem + 1.3vw, 2rem);
	line-height: 1.4;
	color: var(--gillani-color-primary);
}

/*
 * Contrast note (Revision 7 audit): `::before`'s glyph is purely
 * decorative typographic ornament (a large opening quotation mark, not
 * text content itself — exempt under WCAG 1.4.11's own "pure decoration"
 * carve-out), and its 55% opacity blends it with whichever light section
 * background it sits on, pulling its EFFECTIVE contrast well below the
 * raw accent-vs-background figure. Computed against ivory/white: old
 * muted-slate ≈2.00–2.09:1 blended, new warm-grey ≈2.18–2.28:1 blended —
 * both already under 3:1, i.e. this was already below the non-text
 * threshold before this revision and is marginally IMPROVED, not
 * worsened, by the swap. `::after`'s thin accent rule is full-opacity
 * and non-text/decorative on the same light backgrounds — old 4.08–
 * 4.56:1, new 5.00–5.59:1, a clean improvement either way.
 */
.gillani-pull-quote::before {
	content: "\201C";
	display: block;
	font-family: var(--gillani-font-heading);
	font-size: clamp(2.75rem, 2.25rem + 2.5vw, 4.25rem);
	line-height: 1;
	color: var(--gillani-color-accent);
	opacity: 0.55;
}

.gillani-pull-quote::after {
	content: "";
	display: block;
	width: 48px;
	height: 2px;
	background-color: var(--gillani-color-accent);
	margin: var(--gillani-space-3) auto 0;
}

/*
 * Testimonials grid card — the "quote + attribution" building block for
 * the dormant Testimonials pattern (inc/testimonials-pattern.php). Shares
 * the same surface/border language as `.gillani-card` above and the same
 * heading-font quote treatment as `.gillani-pull-quote`, so a future real
 * testimonials section reads as part of the same design system rather
 * than a one-off new visual style.
 */
.gillani-testimonial-card {
	background-color: var(--gillani-color-surface);
	border: 1px solid var(--gillani-color-border);
	border-radius: var(--gillani-radius);
	padding: var(--gillani-space-4) var(--gillani-space-3);
	height: 100%;
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

/* Task 4 — same hover/focus lift language as .gillani-card above. */
.gillani-testimonial-card:hover,
.gillani-testimonial-card:focus-within {
	transform: translateY(-3px);
	box-shadow: 0 10px 24px rgba(11, 47, 91, 0.14);
	border-color: var(--gillani-color-accent);
}

@media (prefers-reduced-motion: reduce) {
	.gillani-testimonial-card {
		transition: border-color 0.2s ease;
	}

	.gillani-testimonial-card:hover,
	.gillani-testimonial-card:focus-within {
		transform: none;
		box-shadow: none;
	}
}

.gillani-testimonial-card__quote {
	font-family: var(--gillani-font-heading);
	font-size: 1.1rem;
	line-height: 1.5;
	color: var(--gillani-color-text);
	margin: 0 0 var(--gillani-space-2);
}

.gillani-testimonial-card__quote::before {
	content: "\201C";
	color: var(--gillani-color-accent);
	font-size: 1.4em;
	line-height: 0;
	margin-right: 0.15em;
	vertical-align: -0.2em;
}

/*
 * Revision 3: attribution text now uses the new warm accent — one of the
 * task's named uses ("testimonial attribution text, dates") for
 * `--gillani-color-accent-warm`, giving the outfitter-warmth touch
 * directly on the one piece of text that names a real person.
 */
.gillani-testimonial-card__attribution {
	display: block;
	font-family: var(--gillani-font-body);
	font-weight: 600;
	font-size: 0.9rem;
	color: var(--gillani-color-accent-warm);
	border-top: 2px solid var(--gillani-color-accent-warm);
	padding-top: var(--gillani-space-1);
	margin: 0;
}

/* CTA band — same align:full → box-shadow bleed fix as .gillani-hero above; same Revision 6 brand-deep large-fill token. */
.gillani-cta-band {
	position: relative;
	background-color: var(--gillani-color-brand-deep);
	box-shadow: 0 0 0 100vmax var(--gillani-color-brand-deep);
	clip-path: inset(0 -100vmax);
	color: var(--gillani-color-on-secondary);
	text-align: center;
	padding-top: var(--gillani-space-4);
	padding-bottom: var(--gillani-space-4);
}

/* Whitespace pass — desktop-only step up, same reasoning as .gillani-hero above. */
@media (min-width: 782px) {
	.gillani-cta-band {
		padding-top: var(--gillani-space-6);
		padding-bottom: var(--gillani-space-6);
	}
}

.gillani-cta-band .wp-block-heading {
	color: var(--gillani-color-on-secondary);
}

/*
 * Single "moment" callout photo (e.g. About Us' Holland & Holland photo) —
 * distinct from `.gillani-card`/`.gillani-gallery-preview`'s forced 3:4
 * portrait crop, which exists specifically so mixed grid photos read as one
 * consistent shape. A standalone callout photo has no grid neighbours to
 * match, so it is shown at its natural ratio (no crop) inside a capped
 * max-width, centred, with the same corner radius as the rest of the site.
 */
.gillani-callout-photo .wp-block-image {
	margin: 0 auto;
	max-width: 640px;
}

.gillani-callout-photo .wp-block-image img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--gillani-radius);
}

/*
 * Partners/venues strip — Revision 3, currently dormant (registered as a
 * pattern in inc/partners-strip-pattern.php, not inserted into any live
 * page — see README.md changelog). A simple horizontal flex row on the
 * cream/off-white background, ready to hold real partner/venue logo
 * images (e.g. Holland & Holland, Greenfield Entertainment) once
 * supplied by the client. `grayscale` + a light `mix-blend-mode:
 * multiply` keeps a mix of differently-coloured/sized logo files reading
 * as one calm, consistent row rather than a clashing row of full-colour
 * marks — a common "as-seen-in" logo-strip technique. No fake/placeholder
 * logo images are ever added here; only real supplied files should ever
 * populate `.gillani-partners-strip__item img`.
 */
.gillani-partners-strip {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--gillani-space-4);
	padding: var(--gillani-space-3) var(--gillani-space-3);
}

/*
 * Contrast note (Revision 7 audit): both `.gillani-partners-strip__label`
 * and `__item` colour actual small TEXT (4.5:1 threshold) against the
 * cream/off-white background this dormant component is designed for
 * (see the comment above `.gillani-partners-strip`). Old muted-slate on
 * ivory measured 4.08:1 — a marginal pre-existing FAIL of 4.5:1; new
 * warm-grey measures 5.00:1 on ivory and 5.59:1 on off-white — a clean
 * PASS on both, fixed as a side effect of the Revision 7 swap.
 */
.gillani-partners-strip__label {
	width: 100%;
	text-align: center;
	text-transform: uppercase;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--gillani-color-accent);
	margin: 0 0 var(--gillani-space-2);
}

.gillani-partners-strip__item {
	margin: 0;
	color: var(--gillani-color-earth);
	font-style: italic;
	font-size: 0.85rem;
}

.gillani-partners-strip__item img {
	display: block;
	max-height: 48px;
	width: auto;
	filter: grayscale(1);
	mix-blend-mode: multiply;
	opacity: 0.75;
	transition: opacity 0.2s ease, filter 0.2s ease;
}

.gillani-partners-strip__item img:hover,
.gillani-partners-strip__item img:focus-visible {
	filter: grayscale(0);
	opacity: 1;
}

/*
 * Shared placeholder-image note used across patterns until real assets
 * are added.
 *
 * Contrast note (Revision 7 audit): the dashed `border` (non-text, 3:1
 * threshold) is fine — old muted-slate measured 3.14:1 against this
 * rule's own stone/border `#D8D2C5` fill, new warm-grey measures 3.84:1,
 * an improvement. The `color` (actual italic TEXT) is a pre-existing,
 * NOT newly introduced, marginal FAIL of the 4.5:1 normal-text threshold
 * against the same stone background: old muted-slate measured 3.14:1
 * (already failing before this revision), new warm-grey measures 3.84:1
 * — still under 4.5:1, but a genuine improvement, not a regression. Left
 * as `--gillani-color-earth` rather than diverging further per the task
 * brief (only diverge from the approved `#6B6558` where the SWAP itself
 * turns a prior PASS into a FAIL — this was already failing beforehand).
 */
.gillani-placeholder-note {
	background-color: var(--gillani-color-border);
	border: 1px dashed var(--gillani-color-earth);
	border-radius: var(--gillani-radius);
	padding: var(--gillani-space-2);
	text-align: center;
	font-style: italic;
	color: var(--gillani-color-earth);
}
