/*
 * Post Runtime Engine — post field rendering styles (v1.1).
 *
 * Powers PCPTPages_Card_Renderer output. Two render contexts share these rules:
 *   - Single-post hero (.pre-card-fields--single-hero, .pre-hero) — fields render
 *     alongside the post title and featured image inside the existing
 *     .pre-hero wrapper. Inherits the .pre-single intermediate variables
 *     already declared in frontend.css; no separate mode declarations
 *     needed for this context.
 *   - Card (.pre-card-fields--card) — fields render inside PostGrid card
 *     wrappers and theme archive cards. Lacks the .pre-single ancestor,
 *     so the intermediate variables are declared here directly.
 *
 * Mode handling, token consumption, and the no-!important / no-hardcoded-
 * color discipline all mirror frontend.css. See docs/AISB_TOKEN_CONTRACT.md
 * for the full --aisb-* contract the intermediates flow through.
 *
 * Component class composition:
 *   .pre-card-fields                          wrapper
 *   .pre-card-fields--{card|single-hero}      context
 *   .pre-card-fields__position                position container
 *   .pre-card-fields__position--{position}    position modifier
 *   .pre-field                                field base
 *   .pre-field--{display_type}                display-type modifier
 *   .pre-field--position-{position}           per-field position hook
 *   .pre-field--badge-{intent}                color-intent for badge type
 *   .pre-field--key-{field_key}               per-field customization hook
 *
 * @since 1.1.0
 */

/* ----------------------------------------------------------------------- */
/* Mode variables for card context                                          */
/*                                                                          */
/* Single-hero inherits these from .pre-single (set in frontend.css).       */
/* Cards declare them here so PostGrid / archive cards render correctly     */
/* even when .pre-single isn't an ancestor.                                 */
/* ----------------------------------------------------------------------- */

.pre-card-fields--card,
.aisb-features__item {
	--pre-color-text: var(--aisb-color-text, #1f2937);
	--pre-color-text-muted: var(--aisb-color-text-muted, #6b7280);
	--pre-color-background: var(--aisb-color-background, #ffffff);
	--pre-color-surface: var(--aisb-color-surface, #f9fafb);
	--pre-color-border: var(--aisb-color-border, #e5e7eb);
	--pre-color-primary: var(--aisb-color-primary, #6366f1);

	/* Intent (status) colors are PALETTE-INDEPENDENT CONSTANTS, not brand
	   tokens. Kitchen-sink contrast audit (2026-07-04) found that sites
	   whose --aisb-color-success/warning/error/info tokens are mid-tone
	   FILL colors (e.g. emerald-500 #10b981) produced badge text at
	   1.9–3.2:1 on the tint backgrounds — those tokens are meant for
	   solid fills, not text on tints. Status colors are semantic, not
	   brand, so they use fixed AA-safe shades (same philosophy as the
	   overlay hero scrim constants in frontend.css). */
	--pre-color-success-bg: rgba(16, 185, 129, 0.14);
	--pre-color-success-text: #047857;
	--pre-color-warning-bg: rgba(245, 158, 11, 0.16);
	--pre-color-warning-text: #92400e;
	--pre-color-danger-bg: rgba(239, 68, 68, 0.13);
	--pre-color-danger-text: #b91c1c;
	--pre-color-info-bg: rgba(59, 130, 246, 0.13);
	--pre-color-info-text: #1d4ed8;
	--pre-color-neutral-bg: var(--aisb-color-surface, rgba(0, 0, 0, 0.05));
	/* Track the theme-aware muted token (which flips light↔dark) rather than the
	   raw light --aisb-color-text-muted, so neutral pill text stays legible on a
	   dark Content Theme / dark section. A neutral pill's text IS muted text. */
	--pre-color-neutral-text: var(--pre-color-text-muted, var(--aisb-color-text-muted, #4b5563));
}

/* When PRE post fields are injected DIRECTLY into AISB PostGrid /
 * theme archive cards (Phase 12), the .aisb-features__item-image-wrapper
 * needs position: relative so the image_overlay anchors correctly. The
 * :has() guard means we only touch wrappers that contain our overlay —
 * existing AISB cards without post fields are untouched. */
.aisb-features__item-image-wrapper:has(.pre-card-fields__position--image-overlay) {
	position: relative;
}

/* Dark mode (inside .aisb-section--dark). Same pattern as frontend.css.
 *
 * MUST mirror the light-mode token block above, which declares these tokens
 * on BOTH .pre-card-fields--card AND .aisb-features__item. When PRE post
 * fields are injected directly into AISB PostGrid / theme archive cards
 * (Phase 12), there is no .pre-card-fields--card wrapper — the position
 * blocks sit inside .aisb-features__item. Omitting .aisb-features__item here
 * left the light muted token in place on dark cards, so post-field meta
 * (e.g. a footer_meta date) rendered near-invisible on dark sections. */
.aisb-section--dark .pre-card-fields--card,
.pre-card-fields--card.is-dark,
.aisb-section--dark .aisb-features__item,
.aisb-features__item.is-dark {
	--pre-color-text: var(--aisb-color-dark-text, #fafafa);
	--pre-color-text-muted: var(--aisb-color-dark-text-muted, #9ca3af);
	--pre-color-background: var(--aisb-color-dark-background, #1a1a1a);
	--pre-color-surface: var(--aisb-color-dark-surface, #2a2a2a);
	--pre-color-border: var(--aisb-color-dark-border, #4b5563);
}

/* Single-hero context: declare success/warning/danger/info intent
 * tokens on the wrapper so badges work even when this CSS is loaded
 * before frontend.css's .pre-single block has resolved. Same
 * palette-independent constants as the card block above. */
.pre-card-fields--single-hero, .pre-hero {
	--pre-color-success-bg: rgba(16, 185, 129, 0.14);
	--pre-color-success-text: #047857;
	--pre-color-warning-bg: rgba(245, 158, 11, 0.16);
	--pre-color-warning-text: #92400e;
	--pre-color-danger-bg: rgba(239, 68, 68, 0.13);
	--pre-color-danger-text: #b91c1c;
	--pre-color-info-bg: rgba(59, 130, 246, 0.13);
	--pre-color-info-text: #1d4ed8;
	--pre-color-neutral-bg: var(--aisb-color-surface, rgba(0, 0, 0, 0.05));
	/* Track the theme-aware muted token (which flips light↔dark) rather than the
	   raw light --aisb-color-text-muted, so neutral pill text stays legible on a
	   dark Content Theme / dark section. A neutral pill's text IS muted text. */
	--pre-color-neutral-text: var(--pre-color-text-muted, var(--aisb-color-text-muted, #4b5563));
}

/* ----------------------------------------------------------------------
 * DARK-CONTEXT intent remap (kitchen-sink audit fix, 2026-07-04).
 *
 * The light intent set above uses dark text on pale tints — on a dark
 * surface those tints barely lighten the background and the dark text
 * disappears (audited at 1.9–4.4:1). Every dark surface a badge or
 * multi-badge pill can sit on gets light text shades on stronger tints:
 *   - page dark mode (cards, PostGrid/theme-archive items, hero)
 *   - forced-dark hero band (.pre-hero--theme-dark, Phase A)
 *   - overlay hero (always dark-on-scrim by contract, Phase B)
 * Audited ≥7:1 for all four intents over the darkest band background.
 * -------------------------------------------------------------------- */
.aisb-section--dark .pre-card-fields--card,
.pre-card-fields--card.is-dark,
.aisb-section--dark .aisb-features__item,
.aisb-features__item.is-dark,
.aisb-section--dark .pre-hero,
.pre-single--dark .pre-hero,
.pre-hero.pre-hero--theme-dark,
.pre-hero.pre-hero--overlay {
	--pre-color-success-bg: rgba(16, 185, 129, 0.22);
	--pre-color-success-text: #6ee7b7;
	--pre-color-warning-bg: rgba(245, 158, 11, 0.22);
	--pre-color-warning-text: #fcd34d;
	--pre-color-danger-bg: rgba(239, 68, 68, 0.24);
	--pre-color-danger-text: #fca5a5;
	--pre-color-info-bg: rgba(59, 130, 246, 0.24);
	--pre-color-info-text: #93c5fd;
	--pre-color-neutral-bg: rgba(255, 255, 255, 0.10);
}

/* Forced-LIGHT hero band inside a dark page must get the light intent
 * set back. :not(.pre-hero--overlay) both raises specificity above the
 * dark block's compound selectors AND keeps the overlay exempt (overlay
 * ignores hero_theme by contract — its badges always sit on the scrim). */
.pre-hero.pre-hero--theme-light:not(.pre-hero--overlay) {
	--pre-color-success-bg: rgba(16, 185, 129, 0.14);
	--pre-color-success-text: #047857;
	--pre-color-warning-bg: rgba(245, 158, 11, 0.16);
	--pre-color-warning-text: #92400e;
	--pre-color-danger-bg: rgba(239, 68, 68, 0.13);
	--pre-color-danger-text: #b91c1c;
	--pre-color-info-bg: rgba(59, 130, 246, 0.13);
	--pre-color-info-text: #1d4ed8;
	--pre-color-neutral-bg: var(--aisb-color-surface, rgba(0, 0, 0, 0.05));
}

/* ----------------------------------------------------------------------- */
/* Wrapper + position containers                                            */
/* ----------------------------------------------------------------------- */

/* Anchor for the absolutely-positioned image_overlay position. The
 * existing .pre-hero__media (set in frontend.css) defaults to static
 * positioning, which would let the overlay escape the media wrapper.
 * Scoping the relative position to a media wrapper that ACTUALLY
 * contains an overlay child means existing v0.3.x pages without post
 * fields aren't repositioned. */
.pre-hero__media:has(.pre-card-fields__position--image-overlay) {
	position: relative;
}

/* Fallback for browsers without :has() support (Firefox < 121, Safari
 * < 15.4). Slightly less surgical — applies position: relative to every
 * media wrapper on a single-post page that ALSO has the post-field
 * stylesheet loaded. Net effect on existing pages: zero visual change,
 * since position: relative on a static-laid-out block has no effect
 * unless it contains absolute children. */
.pre-single .pre-hero__media {
	position: relative;
}

.pre-card-fields {
	font-family: var(--aisb-section-font-body, inherit);
	color: var(--pre-color-text);
}

.pre-card-fields__position {
	display: block;
}

/* Headline position: flex container with baseline alignment so when two
 * or more fields share the headline (price + bed count, salary + role,
 * date + duration), they lay out inline on the same line. Single-field
 * headlines still render correctly because a flex container with one
 * child collapses to that child's size. The gap provides comfortable
 * separation when fields ARE compound (Zillow-style "$2,328+ 2 bds"). */
.pre-card-fields__position--headline {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.4em 0.85em;
}

/* Subtitle position: same flex+gap treatment as headline, but baseline-
 * aligned and slightly tighter. Without this, multiple subtitle fields
 * (e.g. room + early-bird-price on a session, location + cuisine on a
 * restaurant) render adjacent with no visible separation between them. */
.pre-card-fields__position--subtitle {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.3em 0.85em;
}

/* Footer-meta position: flex+gap so multi_badge + adjacent fields (e.g.
 * topics + "N sessions in track") sit on the same row with visible
 * separation. Tighter gap than meta_strip because footer-meta items are
 * informational rather than primary. */
.pre-card-fields__position--footer-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4em 0.85em;
}

/* meta_strip is the canonical horizontal layout — a wrapping flex row whose
 * items are separated by GAP SPACING ONLY (no character separator).
 *
 * Why no middot/bar/border between items: any rendered separator (a `·`
 * ::after, a `|`, or a left border) dangles at a wrap point, because CSS
 * cannot target "the last item of a wrapped line" — `:not(:last-child)` only
 * suppresses the trailing one on the final item overall. The previous middot
 * left an orphaned `·` at the end of a wrapped line in narrow columns. Spacing
 * via `gap` is bulletproof: it never dangles at any width or item count, and
 * wrapped lines get their own row-gap. Each meta-pair also carries its own
 * leading icon, which already delimits items visually, so the dots were
 * largely redundant. Column gap is widened (vs the old 0.85em) to keep clear
 * separation now that the glyph is gone. */
.pre-card-fields__position--meta-strip {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5em 1.25em;
}

/* image_overlay positions absolutely over the parent media wrapper. The
 * caller (PCPTPages_Renderer for the hero, AISB PostGrid for cards) provides
 * a position: relative container. */
.pre-card-fields__position--image-overlay {
	position: absolute;
	top: 0.75rem;
	left: 0.75rem;
	z-index: 2;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	pointer-events: none;
}

.pre-card-fields__position--image-overlay .pre-field {
	pointer-events: auto;
}

/* AISB PostGrid COMPACT side rows (featured display style) relocate the
 * image_overlay position into the content flow: AISB fires the hook in
 * the content cell there because a 160px thumbnail can't host overlay
 * badges, and imageless rows would drop them entirely. Neutralize the
 * absolute overlay treatment into an in-flow badge row. Deliberately
 * duplicated in AISB's postgrid.css with the same declarations so
 * whichever plugin updates first keeps the composition correct
 * (identical rules cannot conflict). */
.aisb-postgrid__item--compact .pre-card-fields__position--image-overlay {
	position: static;
	top: auto;
	left: auto;
	pointer-events: auto;
	margin-bottom: 0.35em;
}

/* Single-post OVERLAY hero: badges render in flow at the top of the band,
 * exactly as the renderer comment promises. The generic absolute rule above
 * pinned them to the inner column's top-left, which is harmless while the
 * bottom-pinned text block sits far below — but the moment the content fills
 * the band (small viewports, long titles, many fields) the badge lands ON the
 * headline (kitchen-sink pressure test, 2026-07-25). In flow, the badge row
 * pushes content down instead of overlapping it, whatever the metadata. The
 * stacked/split hero layouts keep the absolute treatment: there the badge
 * floats over the IMAGE, which is the intended composition. */
.pre-hero__inner--overlay .pre-card-fields__position--image-overlay {
	position: static;
	top: auto;
	left: auto;
	pointer-events: auto;
	margin-bottom: 0.5em;
}

/* Vertical rhythm between sibling position blocks. */
:is(.pre-card-fields--single-hero, .pre-hero) .pre-card-fields__position + .pre-card-fields__position {
	margin-top: 0.5em;
}

:is(.pre-card-fields--card, .aisb-features__item) .pre-card-fields__position + .pre-card-fields__position {
	margin-top: 0.35em;
}

/* ----------------------------------------------------------------------- */
/* Field base                                                               */
/* ----------------------------------------------------------------------- */

.pre-field {
	display: inline-flex;
	align-items: baseline;
	color: var(--pre-color-text);
	font-family: inherit;
}

/* ----------------------------------------------------------------------- */
/* Per-display-type styling                                                 */
/* ----------------------------------------------------------------------- */

/* Currency — prominent value, brand-color tint when at headline position */
.pre-field--currency {
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

:is(.pre-card-fields--single-hero, .pre-hero) .pre-field--currency.pre-field--position-headline {
	font-size: clamp(1.5rem, 2.5vw, 2rem);
	/* Tighter line-height for display-size type, plus a small negative
	 * letter-spacing — standard typography convention for headings ≥24px
	 * to keep large numerals visually cohesive. */
	line-height: 1.1;
	letter-spacing: -0.01em;
	display: block;
	margin-bottom: 0.25em;
}

:is(.pre-card-fields--card, .aisb-features__item) .pre-field--currency.pre-field--position-headline {
	font-size: 1.25rem;
	line-height: 1.2;
	display: block;
	margin-bottom: 0.15em;
}

/* number_with_label — used heavily in meta_strip. Plain inline. */
.pre-field--number-with-label {
	color: var(--pre-color-text-muted);
	font-size: 0.875em;
	font-variant-numeric: tabular-nums;
}

:is(.pre-card-fields--single-hero, .pre-hero) .pre-field--number-with-label.pre-field--position-headline,
:is(.pre-card-fields--card, .aisb-features__item) .pre-field--number-with-label.pre-field--position-headline {
	color: var(--pre-color-text);
	font-size: 1.125em;
	font-weight: 600;
	display: block;
}

/* Badge — pill with color intent */
/* Badges — pill-shape, bold, brand-color-driven. Font sizes use `rem`
 * (html-rooted, absolute) rather than `em` so pills don't compound-
 * shrink when they land inside parents that already scale down (e.g.
 * footer_meta inside cards inside post grids). 12-13px floor is the
 * modern pill standard (Linear, Stripe Primer, Vercel Geist) and the
 * accessibility-comfortable lower bound for non-body text. */
.pre-field--badge {
	display: inline-flex;
	align-items: center;
	padding: 0.3em 0.85em;
	border-radius: 999px;
	font-size: 0.75rem; /* 12px absolute — modern pill floor */
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.01em;
	white-space: nowrap;
	background: var(--pre-color-neutral-bg);
	color: var(--pre-color-neutral-text);
}

.pre-field--badge-success {
	background: var(--pre-color-success-bg);
	color: var(--pre-color-success-text);
}

.pre-field--badge-warning {
	background: var(--pre-color-warning-bg);
	color: var(--pre-color-warning-text);
}

.pre-field--badge-danger {
	background: var(--pre-color-danger-bg);
	color: var(--pre-color-danger-text);
}

.pre-field--badge-info {
	background: var(--pre-color-info-bg);
	color: var(--pre-color-info-text);
}

/* ---------------------------------------------------------------------
 * Primary v1.1 intent set: primary / secondary / neutral.
 *
 * Text colors use the SmartColorManager-computed tokens
 * (--aisb-button-primary-text, --aisb-button-secondary-text). These are
 * recalculated by AISB at wp_head priority 11 to guarantee WCAG AA
 * contrast against the user's brand color choice — no matter what color
 * the user picks for --aisb-color-primary, the text token resolves to a
 * legible value. Same pattern AISB's own primary buttons and SALE badge
 * use, so badges and buttons stay visually aligned and uniformly
 * accessible.
 *
 * Neutral is intentionally NOT brand-coupled — it's a semi-transparent
 * dark overlay with white text. Used as the safe default and as the
 * Zillow "Designer finishes" pattern: works on any image background,
 * works regardless of brand choice, and reads as informational rather
 * than promotional.
 * --------------------------------------------------------------------- */

.pre-field--badge-primary {
	background: var(--aisb-color-primary, #6366f1);
	color: var(--aisb-button-primary-text, #ffffff);
}

.pre-field--badge-secondary {
	background: var(--aisb-color-secondary, #8b5cf6);
	color: var(--aisb-button-secondary-text, var(--aisb-color-text-inverse, #ffffff));
}

.pre-field--badge-neutral {
	background: rgba(15, 23, 42, 0.85);
	color: #ffffff;
	backdrop-filter: blur(4px);
	-webkit-backdrop-filter: blur(4px);
}

/* Image overlay badges need solid, high-contrast backgrounds to stay
 * readable on top of arbitrary photo content. The default rgba(_, _, _,
 * 0.12) tints work great in subtitle / meta_strip / footer_meta where the
 * background is the card surface — but they vanish against bright photo
 * pixels. Image_overlay-positioned badges get saturated solid backgrounds
 * with white text instead. Matches the Zillow / Airbnb / Booking pattern
 * for card image badges. */
.pre-field--badge.pre-field--position-image-overlay {
	background: rgba(15, 23, 42, 0.85);
	color: #ffffff;
	font-weight: 600;
	/* Slightly bigger + more padded than other badge contexts — overlay
	 * badges sit on photos and need real presence to be readable. */
	font-size: 0.8125rem; /* 13px absolute */
	padding: 0.45em 0.95em;
	backdrop-filter: blur(4px);
	-webkit-backdrop-filter: blur(4px);
}

/* Solid backgrounds are FIXED AA-safe shades, not brand tokens — the
 * kitchen-sink audit (2026-07-04) measured white text at ~2.6:1 on sites
 * whose intent tokens are mid-tone fills (e.g. emerald-500). White on
 * these constants: success 7.9:1, warning 4.9:1, danger 5.9:1, info 6.1:1. */
.pre-field--badge.pre-field--position-image-overlay.pre-field--badge-success {
	background: #047857;
	color: #ffffff;
}

.pre-field--badge.pre-field--position-image-overlay.pre-field--badge-warning {
	background: #b45309;
	color: #ffffff;
}

.pre-field--badge.pre-field--position-image-overlay.pre-field--badge-danger {
	background: #b91c1c;
	color: #ffffff;
}

.pre-field--badge.pre-field--position-image-overlay.pre-field--badge-info {
	background: #1d4ed8;
	color: #ffffff;
}

.pre-field--badge.pre-field--position-image-overlay.pre-field--badge-neutral {
	background: rgba(15, 23, 42, 0.85);
	color: #ffffff;
}

/* Image overlay variants for the v1.1 intent set. Same SmartColor-
 * computed text tokens as the non-overlay variants — accessibility is
 * the same whether the badge sits on a card surface or over an image.
 * Token alignment with AISB's .aisb-productgrid__sale-badge means SALE
 * flash on WooCommerce cards and brand-color badges on PRE cards stay
 * visually identical. */
.pre-field--badge.pre-field--position-image-overlay.pre-field--badge-primary {
	background: var(--aisb-color-primary, #6366f1);
	color: var(--aisb-button-primary-text, #ffffff);
}

.pre-field--badge.pre-field--position-image-overlay.pre-field--badge-secondary {
	background: var(--aisb-color-secondary, #8b5cf6);
	color: var(--aisb-button-secondary-text, var(--aisb-color-text-inverse, #ffffff));
}

/* meta_pair — icon + value, designed for meta_strip layouts. Override
 * the inherited `align-items: baseline` from .pre-field with `center` so
 * the icon glyph (which has its own internal layout) sits visually
 * centered with the text rather than dropped to the text baseline. */
.pre-field--meta-pair {
	align-items: center;
	color: var(--pre-color-text-muted);
	/* rem-based so meta_pair text reads at 14px regardless of whether
	 * the meta_strip parent shrunk to 0.85em (card context) or not. */
	font-size: 0.875rem;
	gap: 0.4em;
}

.pre-field--meta-pair .pre-field__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1em;
	height: 1em;
	flex-shrink: 0;
	line-height: 1;
}

.pre-field--meta-pair .pre-field__icon svg,
.pre-field--meta-pair .pre-field__icon iconify-icon {
	width: 1em;
	height: 1em;
	color: currentColor;
	display: block;
}

.pre-field--meta-pair .pre-field__value {
	font-variant-numeric: tabular-nums;
	line-height: 1.2;
}

/* date — small muted text by default; promotes to larger size in
 * headline / subtitle positions */
.pre-field--date {
	color: var(--pre-color-text-muted);
	font-size: 0.85em;
}

.pre-field--date.pre-field--position-headline {
	color: var(--pre-color-text);
	font-size: 1.25em;
	font-weight: 600;
	display: block;
}

:is(.pre-card-fields--single-hero, .pre-hero) .pre-field--date.pre-field--position-headline {
	font-size: clamp(1.25rem, 2vw, 1.75rem);
}

.pre-field--date.pre-field--position-subtitle {
	font-size: 1em;
}

/* text — inherits color; promotes weight at headline */
.pre-field--text {
	color: var(--pre-color-text);
}

.pre-field--text.pre-field--position-subtitle {
	color: var(--pre-color-text-muted);
	font-size: 0.95em;
}

/* When multiple fields land in subtitle (e.g. location + early-bird
 * price), normalize ALL of them to the same scale so they read as a
 * single typographic line rather than as two unrelated sizes. */
.pre-card-fields__position--subtitle > .pre-field {
	font-size: 0.95em;
}

/* Currency in subtitle keeps its semibold weight (it's still a price)
 * but harmonizes with neighbour sizes. */
.pre-field--currency.pre-field--position-subtitle {
	font-weight: 600;
}

.pre-field--text.pre-field--position-footer-meta {
	color: var(--pre-color-text-muted);
	/* 13px absolute — touch-friendly + accessibility floor for muted text. */
	font-size: 0.8125rem;
}

/* rating — composite element: stars + value + optional count */
.pre-field--rating {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	/* 14px absolute — readable in card + hero contexts without compounding. */
	font-size: 0.875rem;
}

.pre-field--rating .pre-field__stars {
	color: var(--aisb-color-warning, #f59e0b);
	/* Stars need real breathing room — 0.02em was too tight. 0.08em
	 * matches the visual spacing of how rating widgets render in
	 * Linear / Apple Maps / Yelp. */
	letter-spacing: 0.08em;
	line-height: 1;
}

.pre-field--rating .pre-field__rating-value {
	font-weight: 600;
	color: var(--pre-color-text);
	font-variant-numeric: tabular-nums;
}

.pre-field--rating .pre-field__rating-count {
	color: var(--pre-color-text-muted);
	font-size: 0.85em;
}

/* progress — bar + label. Default layout is column-stacked (bar above
 * label) for use as a standalone or in headline / subtitle positions
 * where the bar can take real horizontal real estate. */
.pre-field--progress {
	display: flex;
	flex-direction: column;
	gap: 0.35em;
	min-width: 12em;
	max-width: 100%;
}

.pre-field--progress .pre-field__progress-track {
	width: 100%;
	height: 0.5em;
	border-radius: 999px;
	background: var(--pre-color-surface);
	border: 1px solid var(--pre-color-border);
	overflow: hidden;
}

.pre-field--progress .pre-field__progress-bar {
	height: 100%;
	background: var(--pre-color-primary);
	border-radius: 999px;
	transition: width 0.3s ease-out;
}

.pre-field--progress .pre-field__progress-label {
	font-size: 0.85em;
	color: var(--pre-color-text-muted);
	font-variant-numeric: tabular-nums;
}

/* Progress in meta_strip: flip to ROW layout so the bar + label sit
 * inline next to siblings (meta_pair, rating) without making the strip
 * three times taller. Without this override the stacked-column layout
 * forces the whole meta_strip row to ~65-80px tall and breaks the
 * inline rhythm. */
.pre-field--progress.pre-field--position-meta-strip {
	flex-direction: row;
	align-items: center;
	gap: 0.55em;
	min-width: 0; /* let the bar shrink */
}

.pre-field--progress.pre-field--position-meta-strip .pre-field__progress-track {
	width: 6em;
	flex-shrink: 0;
	height: 0.45em;
}

.pre-field--progress.pre-field--position-meta-strip .pre-field__progress-label {
	font-size: 0.875rem; /* matches meta_strip's 14px floor */
	white-space: nowrap;
}

:is(.pre-card-fields--card, .aisb-features__item) .pre-field--progress {
	min-width: 100%;
}

/* Card-context meta_strip: card columns are narrow, so the inline
 * progress bar should be tighter than the single-hero version. */
:is(.pre-card-fields--card, .aisb-features__item) .pre-field--progress.pre-field--position-meta-strip {
	min-width: 0;
}
:is(.pre-card-fields--card, .aisb-features__item) .pre-field--progress.pre-field--position-meta-strip .pre-field__progress-track {
	width: 4.5em;
}

/* multi_badge — multiple small pills with optional per-segment intent */
.pre-field--multi-badge {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.3em;
}

/* Multi-badge pills. Same `rem`-based sizing as .pre-field--badge — pills
 * need to read at ~12px regardless of where the multi_badge field lands
 * (footer_meta on cards shrinks the parent twice over and the old
 * 0.7em rule compounded to ~9px). 12px is the modern floor; the bigger
 * padding gives the pill enough body to feel like a chip, not a label. */
.pre-field__multi-badge-pill {
	display: inline-flex;
	align-items: center;
	padding: 0.35em 0.8em;
	border-radius: 999px;
	font-size: 0.75rem; /* 12px absolute, matches .pre-field--badge */
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.01em;
	white-space: nowrap;
	/* Every token carries a literal fallback so a multi_badge still renders as a
	   proper chip even if it lands OUTSIDE the card wrapper that defines the
	   --pre-color-* tokens (inside a card it inherits the brand palette as
	   normal; outside it degrades to these sane defaults instead of bare text). */
	background: var(--pre-color-neutral-bg, #f9fafb);
	color: var(--pre-color-neutral-text, #4b5563);
}

.pre-field__multi-badge-pill--success {
	background: var(--pre-color-success-bg, rgba(16, 185, 129, 0.12));
	color: var(--pre-color-success-text, #047857);
}

.pre-field__multi-badge-pill--warning {
	background: var(--pre-color-warning-bg, rgba(245, 158, 11, 0.14));
	color: var(--pre-color-warning-text, #b45309);
}

.pre-field__multi-badge-pill--danger {
	background: var(--pre-color-danger-bg, rgba(239, 68, 68, 0.12));
	color: var(--pre-color-danger-text, #b91c1c);
}

.pre-field__multi-badge-pill--info {
	background: var(--pre-color-info-bg, rgba(59, 130, 246, 0.12));
	color: var(--pre-color-info-text, #1d4ed8);
}

.pre-field__multi-badge-pill--neutral {
	/* `--pre-color-neutral-bg` resolves to the SURFACE token, so a neutral pill
	   on a card (whose background IS that surface) rendered invisible — only the
	   padding showed, which read as oddly-indented text. The fix is an OUTLINE
	   tag: keep the surface fill (so the label sits on the same background as
	   the rest of the card — no contrast loss, fully on the design system) and
	   define the pill with a hairline border. The border is mixed off the ink
	   colour rather than --pre-color-border, because on some palettes the border
	   token is nearly identical to the surface (which is exactly why the pill
	   was invisible before); the ink mix guarantees a visible outline on any
	   surface, light or dark. */
	background: var(--pre-color-surface, #f9fafb);
	color: var(--pre-color-neutral-text, #4b5563);
	border: 1px solid color-mix(in srgb, var(--pre-color-text, #1f2937) 20%, var(--pre-color-surface, #f9fafb));
}

/* color-mix fallback (older browsers): surface fill + a translucent ink border
   so the outline stays visible regardless of how close the border token is to
   the surface. */
@supports not (background: color-mix(in srgb, red, blue)) {
	.pre-field__multi-badge-pill--neutral {
		background: var(--pre-color-surface);
		border-color: rgba(0, 0, 0, 0.18);
	}
}

.pre-field__multi-badge-pill--primary {
	background: var(--aisb-color-primary, #6366f1);
	color: var(--aisb-button-primary-text, #ffffff);
}

.pre-field__multi-badge-pill--secondary {
	background: var(--aisb-color-secondary, #8b5cf6);
	color: var(--aisb-button-secondary-text, var(--aisb-color-text-inverse, #ffffff));
}

/* ----------------------------------------------------------------------- */
/* Single-hero specific layout polish                                       */
/* ----------------------------------------------------------------------- */

/* headline position in single-hero gets generous breathing room above the
 * post title. The card renderer's output is interleaved with the existing
 * .pre-hero__title h1 by PCPTPages_Renderer. */
:is(.pre-card-fields--single-hero, .pre-hero) .pre-card-fields__position--headline {
	margin-bottom: 0.5em;
}

:is(.pre-card-fields--single-hero, .pre-hero) .pre-card-fields__position--subtitle {
	/* Modern hero rhythm — subtitle gets more breathing room from the
	 * title than from the meta strip below it. */
	margin-top: 0.5rem;
	margin-bottom: 1rem;
}

:is(.pre-card-fields--single-hero, .pre-hero) .pre-card-fields__position--meta-strip {
	margin-top: 1.25rem;
	padding-top: 1rem;
	border-top: 1px solid var(--pre-color-border);
}

:is(.pre-card-fields--single-hero, .pre-hero) .pre-card-fields__position--footer-meta {
	margin-top: 0.75rem;
	color: var(--pre-color-text-muted);
	/* 14px absolute — accessibility-floor for muted body-adjacent text. */
	font-size: 0.875rem;
}

/* ----------------------------------------------------------------------- */
/* Card-specific layout polish                                              */
/* ----------------------------------------------------------------------- */

:is(.pre-card-fields--card, .aisb-features__item) .pre-card-fields__position--meta-strip {
	/* 14px absolute on cards too — was 0.85em (relative) which dropped
	 * to ~12px on smaller card layouts. */
	font-size: 0.875rem;
}

:is(.pre-card-fields--card, .aisb-features__item) .pre-card-fields__position--footer-meta {
	margin-top: 0.5em;
	color: var(--pre-color-text-muted);
	/* 13px absolute — slightly smaller than single-hero footer (14px)
	 * but above the 12px touch-friendly floor. */
	font-size: 0.8125rem;
}

/* ----------------------------------------------------------------------- */
/* Mobile responsive                                                        */
/* ----------------------------------------------------------------------- */

@media (max-width: 600px) {
	.pre-card-fields__position--meta-strip {
		gap: 0.5em 0.75em;
	}

	/* Footer-meta pills get slightly tighter row-gap on mobile so the
	 * wrapped row stack stays compact without losing touch-comfort. */
	.pre-card-fields__position--footer-meta {
		gap: 0.4em 0.65em;
	}

	:is(.pre-card-fields--single-hero, .pre-hero) .pre-field--currency.pre-field--position-headline {
		font-size: 1.5rem;
	}

	:is(.pre-card-fields--single-hero, .pre-hero) .pre-card-fields__position--meta-strip {
		flex-wrap: wrap;
	}

	/* Hide the dot separators on mobile when the meta strip wraps —
	 * they read awkwardly mid-line-break. */
	.pre-card-fields__position--meta-strip > .pre-field:not(:last-child)::after {
		display: none;
	}

	.pre-card-fields__position--meta-strip > .pre-field {
		flex-basis: auto;
	}

	/* Touch-comfort: pills get a minimum tap-target height on mobile.
	 * 24px is below WCAG's 44px button minimum (badges aren't tap
	 * targets here) but matches the visual rhythm of native iOS / Android
	 * chips. If badges later become interactive, bump to 44px. */
	.pre-field--badge,
	.pre-field__multi-badge-pill {
		min-height: 24px;
	}

	/* Bigger image-overlay badges on mobile — photos shrink so the
	 * badge needs to keep enough presence to read at a glance. */
	.pre-field--badge.pre-field--position-image-overlay {
		font-size: 0.875rem;
		padding: 0.5em 1em;
	}
}

/* ----------------------------------------------------------------------- */
/* Neo-brutalist mode — DELIBERATELY NO FIELD-CHIP RULES                     */
/*                                                                          */
/* Promptless WP's card/button border emphasis (body classes                 */
/* aisb-neo-brutalist-cards / -outline) applies to CARDS and BUTTONS —       */
/* surfaces. Post-field chips (badges, multi-badge pills, progress bars,     */
/* meta pairs, ratings) are data display, not surfaces: they must keep       */
/* their color-intent styling identical across every card style. An          */
/* earlier version of this file gave badges a currentColor border and        */
/* overrode their intent background with --pre-color-background under        */
/* neo mode, which visually destroyed tier badges in PostGrid/archive        */
/* cards and single-post positions the moment a site enabled Outline or      */
/* Lifted (found in demo-site testing, 2026-07-12). Do not re-add chip-      */
/* level neo rules here; the card CONTAINERS (.aisb-postgrid__item,          */
/* .pre-grouping__item, theme archive cards) already carry the mode.         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/* Print styles — keep the field values legible, drop decorative chrome     */
/* ----------------------------------------------------------------------- */

@media print {
	.pre-card-fields__position--image-overlay {
		position: static;
	}

	.pre-field--badge,
	.pre-field__multi-badge-pill {
		background: transparent !important;
		border: 1px solid #000;
		color: #000;
	}

	.pre-field--progress .pre-field__progress-bar {
		background: #888;
	}
}
