/**
 * Websly Harvest Compatibility Layer
 * ==================================
 * Makes harvested core-block patterns (anything the converter wraps in
 * .ws-harvested) adopt Websly's Customizer TYPOGRAPHY (brand fonts, role sizes,
 * weights) and SURFACE treatment (card radius / shadow / hairline border), so a
 * stolen pattern looks like it was built in Websly.
 *
 * Scoped entirely to .ws-harvested → ZERO effect on Websly's own blocks/content.
 * Colours already flow via the Preset Bridge; this adds type + surfaces.
 * Per-family overrides live in each family's skin.css (.ws-fam-<name>).
 *
 * @since 2026-06-02 (Family Harvest Pipeline) — see HOW-TO-STEAL §7.4 / §7.5
 */

/* ============================ Typography ============================ */
/* Headings → Websly title font + role weight / tracking / line-height. */
.ws-harvested :is(h1, h2, h3, h4, h5, h6),
.ws-harvested .wp-block-heading {
    font-family: var(--ws-font-titles, inherit);
    font-style: var(--style-titles, normal);
    font-weight: var(--ws-font-weight-titles, var(--ws-section-title-weight, 700));
    letter-spacing: var(--ws-letter-spacing-titles, var(--ws-section-title-letter-spacing, -0.02em));
    line-height: var(--ws-line-height-titles, var(--ws-section-title-line-height, 1.15));
}
/* Body text → Websly body font. */
.ws-harvested :is(p, li, blockquote, dd, dt, figcaption, cite, address),
.ws-harvested .wp-block-paragraph {
    font-family: var(--ws-font-body, inherit);
    font-weight: var(--ws-font-weight-body, inherit);
    line-height: var(--ws-line-height-body, 1.6);
}
/* Buttons → Websly button font. */
.ws-harvested .wp-block-button__link {
    font-family: var(--ws-font-buttons, var(--ws-font-body, inherit));
    font-weight: var(--ws-font-weight-buttons, 600);
}

/* Default role SIZES by element — only when the block set NO explicit size
   (no inline font-size, no has-*-font-size preset class). */
.ws-harvested :is(h1, h2):not([style*="font-size"]):not([class*="font-size"])    { font-size: var(--ws-typo-cat-section-title-size); }
.ws-harvested h3:not([style*="font-size"]):not([class*="font-size"])             { font-size: var(--ws-typo-cat-card-title-size); }
.ws-harvested :is(h4, h5, h6):not([style*="font-size"]):not([class*="font-size"]) { font-size: var(--ws-typo-cat-card-subtitle-size); }
.ws-harvested p:not([style*="font-size"]):not([class*="font-size"])              { font-size: var(--ws-typo-cat-card-body-size); }

/* Explicit WP font-size presets → mapped to Websly role sizes (overrides the
   Preset Bridge's generic clamps WITHIN harvested content, so sizes match). */
.ws-harvested .has-x-small-font-size  { font-size: var(--ws-typo-cat-section-badge-size); }
.ws-harvested .has-small-font-size    { font-size: var(--ws-typo-cat-section-badge-size); }
.ws-harvested .has-medium-font-size   { font-size: var(--ws-typo-cat-card-body-size); }
.ws-harvested .has-large-font-size    { font-size: var(--ws-typo-cat-card-title-size); }
.ws-harvested .has-x-large-font-size  { font-size: var(--ws-typo-cat-section-subtitle-size); }
.ws-harvested .has-xx-large-font-size { font-size: var(--ws-typo-cat-section-title-size); }

/* ===================== Local contrast ownership =====================
   Some patterns set surface-relative text colours (base / contrast /
   main-accent…) that only read on a SPECIFIC background. When the
   background context differs, you got "white text in light mode, dark
   text in dark mode" — invisible. Fix = Websly's tone model: each
   coloured container publishes a readable text colour via a CSS var,
   and text consumes it. CSS-var inheritance means the NEAREST coloured
   ancestor wins, so nesting (a light card inside an accent band) just
   works — no specificity wars. */
.ws-harvested { --ws-h-text: var(--page-text-base, var(--theme-text)); }

/* --- Containers publish a local readable text colour via --ws-h-text --- */
/* Accent / primary fills → on-accent text */
.ws-harvested :is(
    .has-accent-background-color, .has-accent-1-background-color,
    .has-accent-2-background-color, .has-accent-3-background-color,
    .has-accent-4-background-color, .has-accent-5-background-color,
    .has-accent-6-background-color, .has-primary-background-color,
    .has-main-accent-background-color) {
    --ws-h-text: var(--theme-text-on-accent, #fff);
}
/* Dark "contrast" fill (near-black in light / near-white in dark) → inverse text (flips) */
.ws-harvested :is(.has-contrast-background-color, .has-contrast-2-background-color) {
    --ws-h-text: var(--page-bg-base, #fff);
}
/* Light surface fills → normal readable page text */
.ws-harvested :is(
    .has-base-background-color, .has-base-2-background-color,
    .has-base-3-background-color, .has-neutral-background-color,
    .has-tertiary-background-color) {
    --ws-h-text: var(--page-text-base, var(--theme-text));
}

/* --- COVER blocks: the overlay colour lives on a SIBLING __background span,
   not an ancestor, and the baked `is-light` class is stale after token remap.
   Derive the cover's text colour from the overlay via :has(). --- */
.ws-harvested .wp-block-cover:has(> .wp-block-cover__background:is(
    .has-accent-background-color, .has-primary-background-color,
    .has-main-accent-background-color, .has-accent-5-background-color,
    .has-accent-6-background-color)) {
    --ws-h-text: var(--theme-text-on-accent, #fff);
}
.ws-harvested .wp-block-cover:has(> .wp-block-cover__background:is(
    .has-contrast-background-color, .has-contrast-2-background-color)) {
    --ws-h-text: var(--page-bg-base, #fff);
}
.ws-harvested .wp-block-cover:has(> .wp-block-cover__background:is(
    .has-base-background-color, .has-base-2-background-color,
    .has-base-3-background-color, .has-neutral-background-color)) {
    --ws-h-text: var(--page-text-strong, var(--theme-text));
}

/* --- Apply the resolved colour --- */
/* Un-classed text in any coloured section follows the local readable colour. */
.ws-harvested :is(h1,h2,h3,h4,h5,h6,p,li,blockquote,cite,figcaption,dd,dt):not([class*="-color"]) {
    color: var(--ws-h-text);
}
/* Stale SURFACE-RELATIVE text classes (base*/contrast*/neutral) only read on a
   specific background — force them to the local readable colour so they never
   go invisible. Brand accent-coloured text is intentionally left alone. */
.ws-harvested :is(
    .has-base-color, .has-base-2-color, .has-base-3-color,
    .has-contrast-color, .has-contrast-2-color, .has-neutral-color) {
    color: var(--ws-h-text) !important;
}
/* Keep a muted feel for the muted role while staying readable. */
.ws-harvested .has-contrast-3-color {
    color: color-mix(in srgb, var(--ws-h-text) 72%, transparent) !important;
}

/* ============================ Surfaces ============================ */
/* Card-like surfaces: a CONTAINED container carrying a background becomes a
   Websly card (radius + shadow + hairline border). Full-bleed bands
   (alignfull / alignwide) stay flat. Override per family via .ws-fam-<name>. */
.ws-harvested :is(.wp-block-group, .wp-block-column, .wp-block-cover):not(.alignfull):not(.alignwide).has-background {
    border-radius: var(--ws-card-radius, var(--radius-xl));
    box-shadow: var(--ws-card-shadow, var(--shadow-md));
    border: var(--ws-card-border, 1px solid var(--theme-border-subtle, transparent));
}

/* Contained images / covers pick up a matching radius (full-bleed stays square). */
.ws-harvested :is(.wp-block-image img, .wp-block-cover):not(.alignfull):not(.alignwide) {
    border-radius: var(--ws-card-radius, var(--radius-lg));
}

/* Buttons → adopt Websly's PRIMARY / SECONDARY / TERTIARY button presets so
   harvested CTAs automatically match the client's brand (accent colour, hover,
   dark-mode flip) instead of the source theme's flat button. Mirrors the
   .btn-primary / .btn-secondary declarations in inc/themes.php. Social-link
   icons (.wp-block-social-link-anchor) are a different element — untouched. */

/* Shared geometry: radius from the family skin + smooth transition. */
.ws-harvested .wp-block-button__link {
    border-radius: var(--ws-button-radius, var(--radius-full));
    transition: background-color .3s ease, border-color .3s ease, color .3s ease, transform .3s ease;
}

/* PRIMARY — solid accent (default button without an explicit custom colour). */
.ws-harvested .wp-block-button:not(.is-style-outline):not(.is-style-secondary):not(.is-style-secondary-button):not(.is-style-link) .wp-block-button__link:not(.has-background) {
    background-color: var(--theme-accent);
    color: var(--theme-text-on-accent, #fff);
    border: 1px solid var(--theme-accent);
}
.ws-harvested .wp-block-button:not(.is-style-outline):not(.is-style-secondary):not(.is-style-secondary-button):not(.is-style-link) .wp-block-button__link:not(.has-background):hover {
    background-color: var(--theme-primary-dark, var(--theme-accent-strong, var(--theme-accent)));
    border-color: var(--theme-primary-dark, var(--theme-accent-strong, var(--theme-accent)));
    color: var(--theme-text-on-accent, #fff);
}

/* SECONDARY / OUTLINE — soft accent tint (Websly .btn-secondary). */
.ws-harvested .wp-block-button.is-style-outline .wp-block-button__link,
.ws-harvested .wp-block-button.is-style-secondary .wp-block-button__link,
.ws-harvested .wp-block-button.is-style-secondary-button .wp-block-button__link {
    background-color: color-mix(in srgb, var(--theme-accent) 8%, transparent);
    color: var(--accent-strong, var(--theme-primary-dark, var(--theme-accent)));
    border: 1px solid transparent;
}
.ws-harvested .wp-block-button.is-style-outline .wp-block-button__link:hover,
.ws-harvested .wp-block-button.is-style-secondary .wp-block-button__link:hover,
.ws-harvested .wp-block-button.is-style-secondary-button .wp-block-button__link:hover {
    background-color: color-mix(in srgb, var(--theme-accent) 22%, transparent);
    color: var(--accent-strong, var(--theme-primary-dark, var(--theme-accent)));
}

/* TERTIARY / LINK — text-only accent link (Websly .btn-link-underline). */
.ws-harvested .wp-block-button.is-style-link .wp-block-button__link {
    background-color: transparent;
    color: var(--theme-accent);
    border: 0;
    padding-left: 0;
    padding-right: 0;
}

/* ====================================================================
   WordPress block-theme LAYOUT ENGINE (polyfill)
   --------------------------------------------------------------------
   Websly is a CLASSIC theme with no theme.json, so WordPress never
   emits the global layout scaffolding these patterns were authored
   against: content/wide widths + the block-gap vertical rhythm + the
   .is-layout-{flow,constrained,flex} margin rules. Without it,
   constrained containers get max-width:none (content sprawls full
   width → "weird layout") and stacked blocks have no vertical spacing
   (→ cramped). We polyfill it here, SCOPED to .ws-harvested so native
   Websly blocks are untouched.
   ==================================================================== */

/* Global layout sizes (WP-namespaced vars; nothing else reads them).
   content-size = reading measure; wide-size = Websly's page container. */
.ws-harvested {
    --wp--style--global--content-size: 680px;
    --wp--style--global--wide-size: var(--theme-max-width, var(--ws-width-wide, 1200px));
    --wp--style--block-gap: clamp(1.25rem, 1rem + 1.1vw, 2rem);
}

/* Flow layout → vertical rhythm between stacked children. */
.ws-harvested .is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }
.ws-harvested .is-layout-flow > * + * { margin-block-start: var(--wp--style--block-gap, 1.5rem); }

/* Constrained layout → centre children to content-size; wide → wide-size;
   full keeps spanning. Mirrors core's .is-layout-constrained rules. */
.ws-harvested .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide)) {
    max-width: var(--wp--style--global--content-size);
    margin-left: auto;
    margin-right: auto;
}
.ws-harvested .is-layout-constrained > .alignwide {
    max-width: var(--wp--style--global--wide-size);
    margin-left: auto;
    margin-right: auto;
}
.ws-harvested .is-layout-constrained > .alignfull { max-width: none; }
.ws-harvested .is-layout-constrained > * { margin-block-start: 0; margin-block-end: 0; }
.ws-harvested .is-layout-constrained > * + * { margin-block-start: var(--wp--style--block-gap, 1.5rem); }

/* Flex layout → fall back to block-gap when the block set no explicit gap. */
.ws-harvested .is-layout-flex { gap: var(--wp--style--block-gap, 1rem); }

/* ====================================================================
   FULL-BLEED SECTION MODEL
   --------------------------------------------------------------------
   These patterns are authored as edge-to-edge SECTIONS (like Websly's
   own section blocks), not as boxes meant to sit inside a content
   column. But the page template wraps post content in a max-width
   container with side padding, which trapped them. So each harvested
   top-level section breaks OUT to the full viewport width, then re-adds
   its own inner gutter — and the constrained-content rules above keep
   text centred to a readable measure inside the band.

   Breakout uses calc(50% - 50vw): this resolves to exactly 100vw from
   the element's own (viewport-centred) midpoint, so it never overshoots
   even when a full-bleed band is nested inside another. Safe because
   <body> has overflow-x: clip (no horizontal scrollbar). box-sizing
   keeps the gutter inside the 100vw.
   ==================================================================== */
.ws-harvested {
    --ws-bleed-gutter: clamp(1.25rem, 4vw, 3.5rem);
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    max-width: 100vw;
    padding-inline: var(--ws-bleed-gutter);
    box-sizing: border-box;
}
/* A full-bleed child band spans the viewport edges (re-correcting at any depth). */
.ws-harvested .alignfull {
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    max-width: 100vw;
}
/* …but a band that HOLDS content re-pads, so its text keeps the gutter. */
.ws-harvested .alignfull:is(.wp-block-cover, .wp-block-group, .wp-block-columns) {
    padding-inline: var(--ws-bleed-gutter);
}

/* ====================================================================
   PLACEHOLDER-IMAGE TAMING
   --------------------------------------------------------------------
   The harvester swaps every source image for a placehold.co placeholder.
   Until a real image is dropped in, those grey boxes can dominate (a
   1200×800 placeholder rendered full-bleed becomes a ~900px void). These
   rules ONLY match the placeholder src, so they SELF-DISABLE the moment
   a real image replaces it — zero effect on finished pages.
   ==================================================================== */
.ws-harvested img[src*="placehold.co"] { opacity: 0.5; }
/* Image BLOCKS: cap height + cover-crop so a placeholder reads as a tidy
   banner instead of a giant box (cover backgrounds are already cropped). */
.ws-harvested .wp-block-image img[src*="placehold.co"] {
    width: 100%;
    height: auto;
    max-height: 48vh;
    object-fit: cover;
}

/* ====================================================================
   .screen-reader-text — accessibility clip (frontend was MISSING it)
   --------------------------------------------------------------------
   The editor ships this rule, the classic-theme frontend did not, so
   social-link / contact labels ("Twitter", "Facebook"…) rendered as
   visible text next to the icon. Canonical WP definition, global +
   safe (only hides text already meant for screen readers only).
   ==================================================================== */
.screen-reader-text {
    border: 0;
    clip: rect(1px, 1px, 1px, 1px);
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute !important;
    width: 1px;
    word-wrap: normal !important;
}
