/*
==========================================================
BEFORE / AFTER — before_after.css
==========================================================
WHAT IT IS:
A flexible comparison block for showing a before/after
transformation or visual difference between two states.

WHAT IT DOES:
Two display modes:
- Slider: two background images overlaid with a draggable
  range-input handle. CSS clip-path clips the "after" image
  to the right of the handle position.
- Transform: a single card. Before state is shown by default.
  After state is an absolute overlay (opacity: 0) that fades
  in on hover, :focus-within, or tap/click toggle. Before
  defines the card height; after overlays it exactly.

HOW TO USE:
1. Add the "Before / After" block to any page.
2. Choose Display Mode: Slider or Transform.
3. Slider: upload before/after images, set start position.
4. Transform: fill before/after titles, text, and chip items.
5. Both modes: optional eyebrow, heading, and intro text.

All values use boilerplate CSS tokens from style.css.
==========================================================
*/


/* ── Base Block ────────────────────────────────────────────── */

.before_after {
    padding: var(--space-20) 0;
    background-color: var(--color-bg);
}

.before_after_wrapper {
    /* layout only — max-width and horizontal padding from .wrapper */
}


/* ── Section Header ────────────────────────────────────────── */

.before_after_header {
    text-align: center;
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: var(--space-12);
}

.ba_eyebrow {
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--color-accent);
    margin-bottom: var(--space-3);
}

.ba_heading {
    font-family: var(--font-heading);
    font-size: var(--text-3xl);
    font-weight: var(--weight-bold);
    color: var(--color-primary);
    margin: 0 0 var(--space-4) 0;
    line-height: var(--leading-tight);
}

.ba_intro {
    font-size: var(--text-md);
    color: var(--color-text-muted);
    line-height: var(--leading-normal);
}

.ba_intro p:last-child { margin-bottom: 0; }

.ba_intro p,
.ba_intro li {
    color: inherit;
}


/* ── Stage ─────────────────────────────────────────────────── */

.ba_stage {
    position: relative;
}


/* ── Slider Mode ───────────────────────────────────────────── */

.ba_slider {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-lg);
    user-select: none;
    cursor: col-resize;
    aspect-ratio: 16 / 9;
    --ba-split: 50%;
    background-color: var(--color-bg-alt);
}

.ba_slider_before,
.ba_slider_after {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Before fills the full area as the base */
.ba_slider_before {
    z-index: 1;
}

/* After clips to reveal only from the handle rightward */
.ba_slider_after {
    z-index: 2;
    clip-path: inset(0 0 0 var(--ba-split));
}

/* Drag handle */
.ba_slider_handle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--ba-split);
    transform: translateX(-50%);
    z-index: 4;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.ba_slider_line {
    width: 2px;
    height: 100%;
    background-color: var(--color-white);
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
}

.ba_slider_thumb {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    border-radius: var(--radius-full);
    background-color: var(--color-white);
    box-shadow: var(--shadow-md);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Left/right chevron arrows inside the thumb */
.ba_slider_thumb::before,
.ba_slider_thumb::after {
    content: '';
    display: block;
    position: absolute;
    width: 0;
    height: 0;
}

.ba_slider_thumb::before {
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-right: 7px solid var(--color-bg-dark);
    left: 9px;
}

.ba_slider_thumb::after {
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-left: 7px solid var(--color-bg-dark);
    right: 9px;
}

/* Range input: transparent overlay, handles all pointer/keyboard interaction */
.ba_slider_range {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: col-resize;
    z-index: 5;
    margin: 0;
    -webkit-appearance: none;
    appearance: none;
}

/* Before / After labels on the images */
.ba_slider_label {
    position: absolute;
    top: var(--space-4);
    z-index: 3;
    background-color: rgba(0, 0, 0, 0.55);
    color: var(--color-text-inverse);
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 0.3rem 0.65rem;
    border-radius: var(--radius-md);
}

.ba_slider_label_before { left: var(--space-4); }
.ba_slider_label_after  { right: var(--space-4); }

/* Optional caption below the slider */
.ba_slider_caption {
    text-align: center;
    margin-top: var(--space-4);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    line-height: var(--leading-snug);
}

/* Editor only: shown when a slider is missing a photo. */
.ba_preview_empty {
    margin: 0 0 var(--space-4);
    padding: var(--space-4) var(--space-6);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg-alt);
    color: var(--color-text);
    font-size: var(--text-sm);
    text-align: center;
}

/* Contained slider style — constrains slider width */
.ba_slider_style_contained .ba_slider {
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
}


/* ── Transform Mode ────────────────────────────────────────── */

/* Single card container — before is the base, after overlays on hover.
   Batch 8H (§23 R7): both sides share one grid cell, and an empty square
   spacer sets the minimum height. Short content keeps today's exact square
   card; long text makes the card grow to fit the longer side instead of
   being cut off (before, the after side was an absolute overlay sized to
   the square, and long text on either side was clipped). */
.ba_transform {
    position: relative;
    border-radius: var(--radius-xl);
    overflow: hidden;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}

.ba_transform::before {
    content: '';
    grid-area: 1 / 1;
    aspect-ratio: 1 / 1;
}

/* Touch/pen devices: show pointer cursor as tap affordance */
@media (hover: none) {
    .ba_transform { cursor: pointer; }
}

/* Before state: the base layer, in the shared grid cell */
.ba_transform_state_before {
    position: relative;
    z-index: 1;
    grid-area: 1 / 1;
}

/* After state: stacked in the same cell above Before, hidden by default */
.ba_transform_state_after {
    position: relative;
    z-index: 2;
    grid-area: 1 / 1;
    opacity: 0;
    transition: opacity 0.4s ease;
}

/* Shared state styles */
.ba_transform_state {
    background-color: var(--color-bg-alt);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    display: flex;
    flex-direction: column;
}

/* All reveal states driven by JS, through the single ba_revealed flag —
   mouse hover, touch tap, keyboard focus, and Enter/Space all route through
   it (see before_after.js), so this is always in sync with aria-hidden on
   .ba_transform_state_after. ba_focused is a separate, JS-toggled class
   still added/removed on focus/blur, kept only as a styling hook (e.g. a
   focus ring) — it intentionally does NOT appear in this selector, since
   having it independently force the reveal here is what previously let the
   visible state disagree with aria-hidden while a card stayed focused. */
.ba_transform.ba_revealed .ba_transform_state_after {
    opacity: 1;
}

/* Content area — sits above the background image overlay */
.ba_transform_content {
    position: relative;
    z-index: 2;
    padding: var(--space-10) var(--space-8);
    display: flex;
    flex-direction: column;
    height: 100%;
}

/* Overlay on states that have a background image — improves text legibility */
.ba_transform_has_bg::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(160deg, rgba(0, 0, 0, 0.58) 0%, rgba(0, 0, 0, 0.38) 100%);
    z-index: 1;
    pointer-events: none;
}

/* New, independently configurable overlay (Batch 8F Round 2, §8F.2) — a real
   element, not the ::after above, since ::after is already taken by the
   existing fixed legibility gradient and a single pseudo-element can't carry
   two independent tints. Same z-index tier (1) as that gradient — both sit
   below .ba_transform_content (z-index: 2) and above the card's own
   background-image. Color and opacity are set inline from PHP; 0% opacity by
   default means this is invisible until an editor explicitly raises it. */
.ba_transform_overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}

/* Badge — "Before" or "After" label pill */
.ba_transform_badge {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    padding: 0.3rem 0.75rem;
    border-radius: var(--radius-full);
    font-family: var(--font-accent);
    font-size: var(--text-xs);
    font-weight: var(--weight-semi);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: var(--space-5);
    background-color: rgba(0, 0, 0, 0.1);
    color: var(--color-text);
    border: 1px solid var(--color-border);
}

.ba_transform_has_bg .ba_transform_badge {
    background-color: rgba(255, 255, 255, 0.18);
    color: var(--color-text-inverse);
    border-color: rgba(255, 255, 255, 0.3);
}

/* Card heading */
.ba_transform_title {
    font-family: var(--font-heading);
    font-size: var(--text-xl);
    font-weight: var(--weight-bold);
    color: var(--color-primary);
    margin: 0 0 var(--space-4) 0;
    line-height: var(--leading-tight);
}

.ba_transform_has_bg .ba_transform_title {
    color: var(--color-text-inverse);
}

/* Card body text */
.ba_transform_text {
    font-size: var(--text-base);
    color: var(--color-text-muted);
    line-height: var(--leading-normal);
    margin: 0 0 var(--space-6) 0;
}

.ba_transform_has_bg .ba_transform_text {
    color: var(--color-text-inverse-soft);
}

/* Chip list */
.ba_transform_chips {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: auto;
}

.ba_transform_chip {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.75rem;
    border-radius: var(--radius-full);
    font-size: var(--text-sm);
    background-color: var(--color-bg);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    line-height: 1.4;
}

.ba_transform_has_bg .ba_transform_chip {
    background-color: rgba(255, 255, 255, 0.15);
    color: var(--color-text-inverse);
    border-color: rgba(255, 255, 255, 0.25);
}

/* Interaction cue below the card */
.ba_transform_cue {
    text-align: center;
    margin-top: var(--space-6);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    font-style: italic;
}

/* Background style modifiers */
.ba_transform_state.ba_bg_dark {
    background-color: var(--color-bg-dark);
}

.ba_transform_state.ba_bg_dark .ba_transform_title {
    color: var(--color-text-inverse);
}

.ba_transform_state.ba_bg_dark .ba_transform_text {
    color: var(--color-text-inverse-soft);
}

.ba_transform_state.ba_bg_dark .ba_transform_chip {
    background-color: rgba(255, 255, 255, 0.1);
    color: var(--color-text-inverse);
    border-color: rgba(255, 255, 255, 0.2);
}

.ba_transform_state.ba_bg_dark .ba_transform_badge {
    background-color: rgba(255, 255, 255, 0.15);
    color: var(--color-text-inverse);
    border-color: rgba(255, 255, 255, 0.25);
}

.ba_transform_state.ba_bg_accent {
    background-color: var(--color-accent);
}

.ba_transform_state.ba_bg_accent .ba_transform_title,
.ba_transform_state.ba_bg_accent .ba_transform_badge {
    color: var(--color-text-inverse);
}

.ba_transform_state.ba_bg_accent .ba_transform_text {
    color: var(--color-text-inverse-soft);
}

.ba_transform_state.ba_bg_accent .ba_transform_chip {
    background-color: rgba(255, 255, 255, 0.2);
    color: var(--color-text-inverse);
    border-color: rgba(255, 255, 255, 0.3);
}

/* Custom — Background Color's new 'custom' choice (Batch 8F Round 2, §8F.2).
   The hex itself merges into the inline style built in PHP; these two classes
   carry the explicit Light/Dark text choice, matching every other region in
   this system. Written with the same 2-class compound specificity as
   .ba_bg_dark/.ba_bg_accent above, so Custom's explicit choice correctly
   overrides .ba_transform_has_bg's unconditional inverse treatment (1 class)
   even when a background image is also present — Custom always wins,
   regardless of whether an image happens to be set too. */
.ba_transform_state.ba_text_light .ba_transform_title,
.ba_transform_state.ba_text_light .ba_transform_badge {
    color: var(--color-text-inverse);
}

.ba_transform_state.ba_text_light .ba_transform_text {
    color: var(--color-text-inverse-soft);
}

.ba_transform_state.ba_text_light .ba_transform_chip {
    background-color: rgba(255, 255, 255, 0.15);
    color: var(--color-text-inverse);
    border-color: rgba(255, 255, 255, 0.25);
}

.ba_transform_state.ba_text_dark .ba_transform_title {
    color: var(--color-primary);
}

.ba_transform_state.ba_text_dark .ba_transform_badge {
    background-color: rgba(0, 0, 0, 0.1);
    color: var(--color-text);
    border-color: var(--color-border);
}

.ba_transform_state.ba_text_dark .ba_transform_text {
    color: var(--color-text-muted);
}

.ba_transform_state.ba_text_dark .ba_transform_chip {
    background-color: var(--color-bg);
    color: var(--color-text);
    border-color: var(--color-border);
}


/* ── Outer Section Background Mode — independent region (Batch 8F Round 2,
   §8F.2) ─────────────────────────────────────────────────────────────────
   A brand-new control, entirely separate from the Before/After Transform
   cards above — this governs the section itself (.before_after's own base
   background, currently --color-bg, a light token). Theme Default (no
   class) leaves that base rule completely untouched. Background/Alternate
   need an explicit forcing rule below, not just "no rule," because the
   section can simultaneously carry .before_after_variant_dark (a separate,
   pre-existing field) — the inline background-color from PHP already wins
   over variant_dark's own class-based background regardless, but text color
   needs the same specificity defense: 3-class compounds here reliably beat
   .before_after_variant_dark's existing 2-class text rules by specificity
   alone, never by source order. Dark/Accent need an explicit inverse rule
   since there's no pre-existing dark/accent-mode treatment for the header at
   all outside of .before_after_variant_dark. */

.before_after.before_after_bg_background .ba_heading,
.before_after.before_after_bg_alt_background .ba_heading,
.before_after.before_after_text_dark .ba_heading {
    color: var(--color-primary);
}

.before_after.before_after_bg_background .ba_eyebrow,
.before_after.before_after_bg_alt_background .ba_eyebrow,
.before_after.before_after_text_dark .ba_eyebrow {
    color: var(--color-accent);
}

.before_after.before_after_bg_background .ba_intro,
.before_after.before_after_bg_alt_background .ba_intro,
.before_after.before_after_text_dark .ba_intro {
    color: var(--color-text-muted);
}

.before_after.before_after_bg_background .ba_intro h1, .before_after.before_after_bg_background .ba_intro h2,
.before_after.before_after_bg_background .ba_intro h3, .before_after.before_after_bg_background .ba_intro h4,
.before_after.before_after_bg_background .ba_intro h5, .before_after.before_after_bg_background .ba_intro h6,
.before_after.before_after_bg_alt_background .ba_intro h1, .before_after.before_after_bg_alt_background .ba_intro h2,
.before_after.before_after_bg_alt_background .ba_intro h3, .before_after.before_after_bg_alt_background .ba_intro h4,
.before_after.before_after_bg_alt_background .ba_intro h5, .before_after.before_after_bg_alt_background .ba_intro h6,
.before_after.before_after_text_dark .ba_intro h1, .before_after.before_after_text_dark .ba_intro h2,
.before_after.before_after_text_dark .ba_intro h3, .before_after.before_after_text_dark .ba_intro h4,
.before_after.before_after_text_dark .ba_intro h5, .before_after.before_after_text_dark .ba_intro h6 {
    color: var(--color-primary);
}

.before_after.before_after_bg_background .ba_slider_caption,
.before_after.before_after_bg_background .ba_transform_cue,
.before_after.before_after_bg_alt_background .ba_slider_caption,
.before_after.before_after_bg_alt_background .ba_transform_cue,
.before_after.before_after_text_dark .ba_slider_caption,
.before_after.before_after_text_dark .ba_transform_cue {
    color: var(--color-text-muted);
}

.before_after.before_after_bg_dark .ba_heading,
.before_after.before_after_bg_accent .ba_heading,
.before_after.before_after_text_light .ba_heading {
    color: var(--color-text-inverse);
}

/* Correction pass (2026-10-16) — Codex found the eyebrow grouped here with
   accent-blue text, which made it disappear entirely in Accent mode (the
   text and background are the literal same color). Checked each state
   deliberately rather than assuming accent reads fine on any dark surface:
   measured (same real-browser luminance formula used throughout this
   batch) at a real 2.63:1 ratio against --color-bg-dark — below WCAG AA
   even for large text — so Dark does not keep the accent eyebrow either.
   Custom + Light Text also moves to inverse rather than assuming accent
   will contrast with whatever arbitrary hex an editor picks. */
.before_after.before_after_bg_dark .ba_eyebrow,
.before_after.before_after_bg_accent .ba_eyebrow,
.before_after.before_after_text_light .ba_eyebrow {
    color: var(--color-text-inverse);
}

.before_after.before_after_bg_dark .ba_intro,
.before_after.before_after_bg_accent .ba_intro,
.before_after.before_after_text_light .ba_intro {
    color: var(--color-text-inverse-soft);
}

.before_after.before_after_bg_dark .ba_intro h1, .before_after.before_after_bg_dark .ba_intro h2,
.before_after.before_after_bg_dark .ba_intro h3, .before_after.before_after_bg_dark .ba_intro h4,
.before_after.before_after_bg_dark .ba_intro h5, .before_after.before_after_bg_dark .ba_intro h6,
.before_after.before_after_bg_accent .ba_intro h1, .before_after.before_after_bg_accent .ba_intro h2,
.before_after.before_after_bg_accent .ba_intro h3, .before_after.before_after_bg_accent .ba_intro h4,
.before_after.before_after_bg_accent .ba_intro h5, .before_after.before_after_bg_accent .ba_intro h6,
.before_after.before_after_text_light .ba_intro h1, .before_after.before_after_text_light .ba_intro h2,
.before_after.before_after_text_light .ba_intro h3, .before_after.before_after_text_light .ba_intro h4,
.before_after.before_after_text_light .ba_intro h5, .before_after.before_after_text_light .ba_intro h6 {
    color: var(--color-text-inverse);
}

/* Audit finding (Batch 8F Round 2) — a WYSIWYG-embedded link inside .ba_intro
   had no override here or in .before_after_variant_dark below, so it fell
   to the global accent-blue `a` color regardless of background — the same
   class of gap found and fixed in Flexible Content and Image Grid this
   round, measured at the same real 2.63:1 (dark) / 1.00:1 (accent) ratios. */
.before_after.before_after_bg_dark .ba_intro a,
.before_after.before_after_bg_accent .ba_intro a,
.before_after.before_after_text_light .ba_intro a {
    color: var(--color-text-inverse);
}

.before_after.before_after_bg_dark .ba_intro a:hover,
.before_after.before_after_bg_accent .ba_intro a:hover,
.before_after.before_after_text_light .ba_intro a:hover {
    color: var(--color-text-inverse-soft);
}

.before_after.before_after_bg_dark .ba_slider_caption,
.before_after.before_after_bg_dark .ba_transform_cue,
.before_after.before_after_bg_accent .ba_slider_caption,
.before_after.before_after_bg_accent .ba_transform_cue,
.before_after.before_after_text_light .ba_slider_caption,
.before_after.before_after_text_light .ba_transform_cue {
    color: var(--color-text-inverse-muted);
}


/* ── Section Variants (v4 pattern) — AFTER base rule ──────── */

.before_after_variant_default {
    background-color: var(--color-bg);
}

.before_after_variant_minimal {
    padding: var(--space-12) 0;
    background-color: transparent;
}

.before_after_variant_dark {
    background-color: var(--color-bg-dark);
}

.before_after_variant_dark .ba_heading {
    color: var(--color-text-inverse);
}

.before_after_variant_dark .ba_eyebrow {
    color: var(--color-accent);
}

.before_after_variant_dark .ba_intro {
    color: var(--color-text-inverse-soft);
}

/* WYSIWYG Editor Consistency and Contrast — a "No color" heading saved
   inside .ba_intro otherwise falls back to the global h1-h6 rule
   (style.css §4b, --color-primary), unreadable on this dark background.
   p/li already inherit the wrapper's color (before_after.css §Header);
   headings need their own rule since inherit here would give them the
   paragraph (inverse-soft) tone instead of a true heading tone. */
.before_after_variant_dark .ba_intro h1, .before_after_variant_dark .ba_intro h2, .before_after_variant_dark .ba_intro h3,
.before_after_variant_dark .ba_intro h4, .before_after_variant_dark .ba_intro h5, .before_after_variant_dark .ba_intro h6 {
    color: var(--color-text-inverse);
}

/* Audit finding (Batch 8F Round 2) — same gap as the new Background Mode
   rules above, pre-existing for this Section Variant field too: a
   WYSIWYG-embedded link in .ba_intro had no override and fell to the
   global accent-blue `a` color against this dark variant. */
.before_after_variant_dark .ba_intro a {
    color: var(--color-text-inverse);
}

.before_after_variant_dark .ba_intro a:hover {
    color: var(--color-text-inverse-soft);
}

.before_after_variant_dark .ba_slider_caption,
.before_after_variant_dark .ba_transform_cue {
    color: var(--color-text-inverse-muted);
}

/* Stubs — define per project in style.css §10 */
.before_after_variant_homepage_feature { /* see style.css §10 */ }
.before_after_variant_split_feature    { /* see style.css §10 */ }
.before_after_variant_cards_feature    { /* see style.css §10 */ }
.before_after_variant_inner_banner     { /* see style.css §10 */ }


/* ── Responsive ────────────────────────────────────────────── */


@media (max-width: 768px) {

    .before_after {
        padding: var(--space-12) 0;
    }

    .ba_heading {
        font-size: var(--text-2xl);
    }

    .before_after_header {
        margin-bottom: var(--space-8);
    }

    .ba_transform_content {
        padding: var(--space-8) var(--space-6);
    }

    .ba_transform_title {
        font-size: var(--text-lg);
    }
}

@media (max-width: 480px) {

    .before_after {
        padding: var(--space-10) 0;
    }

    .ba_heading {
        font-size: var(--text-xl);
    }

    .ba_slider {
        border-radius: var(--radius-md);
    }

    .ba_transform_content {
        padding: var(--space-6) var(--space-5);
    }
}

/* ── Label look: Rounded tag (Batch 8H, BATCH_8_PLAN.md §28) ──────
   Added only when the editor picks Label look → Rounded tag; Plain text
   (the default) adds nothing, so existing sections look the same. Uses the
   label's own color (currentColor), so it reads on light and dark
   backgrounds. The first border line is the fallback for browsers without
   color-mix(). No blur, glow or animation.
   BOILERPLATE NOTE: the same rule lives in style.css §10c. Kept here so
   this block works when copied to a new project on its own; on a live
   project with §10c in place this copy can be removed. */
.ba_eyebrow.ba_label_pill {
    display: inline-block;
    padding: var(--space-2) var(--space-4);
    border: 1px solid currentColor;
    border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
    border-radius: var(--radius-full);
    background-color: color-mix(in srgb, currentColor 8%, transparent);
    line-height: var(--leading-tight);
}
